diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 4025d9979..82a296ec2 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -281,6 +281,8 @@ void __meminit set_pageblock_mobility(struct page *page, int mobility) } #endif +bool oom_killer_disabled __read_mostly; + #ifdef CONFIG_DEBUG_VM static int page_outside_zone_boundaries(struct zone *zone, struct page *page) { @@ -2529,17 +2531,28 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, *did_some_progress = 0; + if (oom_killer_disabled) + return NULL; + /* - * Acquire the oom lock. If that fails, somebody else is - * making progress for us. + * Acquire the per-zone oom lock for each zone. If that + * fails, somebody else is making progress for us. */ - if (!mutex_trylock(&oom_lock)) { + if (!oom_zonelist_trylock(zonelist, gfp_mask)) { *did_some_progress = 1; schedule_timeout_uninterruptible(1); return NULL; } /* + * PM-freezer should be notified that there might be an OOM killer on + * its way to kill and wake somebody up. This is too early and we might + * end up not killing anything but false positives are acceptable. + * See freeze_processes. + */ + note_oom_kill(); + + /* * Go through the zonelist yet one more time, keep very high watermark * here, this is only to catch a parallel oom killing, we must fail if * we're still under heavy pressure. @@ -2575,10 +2588,10 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, goto out; } /* Exhausted what can be done so it's blamo time */ - if (out_of_memory(zonelist, gfp_mask, order, nodemask, false)) - *did_some_progress = 1; + out_of_memory(zonelist, gfp_mask, order, nodemask, false); + *did_some_progress = 1; out: - mutex_unlock(&oom_lock); + oom_zonelist_unlock(zonelist, gfp_mask); return page; } |
