diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index a12930a5969683..8a782143d16ca9 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1079,8 +1080,24 @@ static int balloon_oom_notify(struct notifier_block *nb, unsigned long dummy, before = balloon_stats.current_pages; /* runs XENMEM_populate_physmap, updates current_pages */ - if (nr > 0) + if (nr > 0) { + unsigned int noreclaim_flag; + + /* + * out_of_memory() calls us with oom_lock held. On PV, + * populating a page whose p2m leaf is still the shared missing + * page allocates the leaf with GFP_KERNEL; with reclaim already + * beaten, that allocation would try the OOM killer, find + * oom_lock taken, count that as progress and retry forever, + * and the OOM killer would never run. Run the deflate as a + * memory-freeing context: no reclaim, no OOM, and the reserves + * may be dipped into, which a leaf that lets 512 pages come + * back repays at once. + */ + noreclaim_flag = memalloc_noreclaim_save(); balloon_deflate(nr); + memalloc_noreclaim_restore(noreclaim_flag); + } /* * balloon_deflate() bumped current_pages by however many Xen diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 579e9104efa375..b0024c58f92ca0 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -384,6 +384,16 @@ static int gntdev_relocate_map(struct gntdev_grant_map *map) } err = gnttab_unmap_refs(map->unmap_ops, map->kunmap_ops, map->pages, map->count); + /* + * A successful hypercall only says the batch was processed; each op + * reports its own fate, and a refused one leaves its grant mapped. + */ + for (i = 0; !err && i < map->count; i++) { + if (map->unmap_ops[i].status != GNTST_okay || + (map->kunmap_ops && + map->kunmap_ops[i].status != GNTST_okay)) + err = -EIO; + } if (err) { /* * The old placeholders may still carry live foreign