diff options
author | Mel Gorman <mgorman@suse.de> | 2012-07-31 19:44:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:42:45 -0400 |
commit | cfd19c5a9ecf8e5e38de2603077c4330af21316e (patch) | |
tree | 5ecf3f51012676c60d12e78ad5a762597ec26385 /mm | |
parent | 907aed48f65efeecf91575397e3d79335d93a466 (diff) |
mm: only set page->pfmemalloc when ALLOC_NO_WATERMARKS was used
__alloc_pages_slowpath() is called when the number of free pages is below
the low watermark. If the caller is entitled to use ALLOC_NO_WATERMARKS
then the page will be marked page->pfmemalloc. This protects more pages
than are strictly necessary as we only need to protect pages allocated
below the min watermark (the pfmemalloc reserves).
This patch only sets page->pfmemalloc when ALLOC_NO_WATERMARKS was
required to allocate the page.
[rientjes@google.com: David noticed the problem during review]
Signed-off-by: Mel Gorman <mgorman@suse.de>
Cc: David Miller <davem@davemloft.net>
Cc: Neil Brown <neilb@suse.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Cc: Eric B Munson <emunson@mgebm.net>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Christoph Lameter <cl@linux.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index cd5390f2f18d..f9d925451bfd 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2116,8 +2116,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
2116 | 2116 | ||
2117 | page = get_page_from_freelist(gfp_mask, nodemask, | 2117 | page = get_page_from_freelist(gfp_mask, nodemask, |
2118 | order, zonelist, high_zoneidx, | 2118 | order, zonelist, high_zoneidx, |
2119 | alloc_flags, preferred_zone, | 2119 | alloc_flags & ~ALLOC_NO_WATERMARKS, |
2120 | migratetype); | 2120 | preferred_zone, migratetype); |
2121 | if (page) { | 2121 | if (page) { |
2122 | preferred_zone->compact_considered = 0; | 2122 | preferred_zone->compact_considered = 0; |
2123 | preferred_zone->compact_defer_shift = 0; | 2123 | preferred_zone->compact_defer_shift = 0; |
@@ -2209,8 +2209,8 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, | |||
2209 | retry: | 2209 | retry: |
2210 | page = get_page_from_freelist(gfp_mask, nodemask, order, | 2210 | page = get_page_from_freelist(gfp_mask, nodemask, order, |
2211 | zonelist, high_zoneidx, | 2211 | zonelist, high_zoneidx, |
2212 | alloc_flags, preferred_zone, | 2212 | alloc_flags & ~ALLOC_NO_WATERMARKS, |
2213 | migratetype); | 2213 | preferred_zone, migratetype); |
2214 | 2214 | ||
2215 | /* | 2215 | /* |
2216 | * If an allocation failed after direct reclaim, it could be because | 2216 | * If an allocation failed after direct reclaim, it could be because |
@@ -2381,8 +2381,17 @@ rebalance: | |||
2381 | page = __alloc_pages_high_priority(gfp_mask, order, | 2381 | page = __alloc_pages_high_priority(gfp_mask, order, |
2382 | zonelist, high_zoneidx, nodemask, | 2382 | zonelist, high_zoneidx, nodemask, |
2383 | preferred_zone, migratetype); | 2383 | preferred_zone, migratetype); |
2384 | if (page) | 2384 | if (page) { |
2385 | /* | ||
2386 | * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was | ||
2387 | * necessary to allocate the page. The expectation is | ||
2388 | * that the caller is taking steps that will free more | ||
2389 | * memory. The caller should avoid the page being used | ||
2390 | * for !PFMEMALLOC purposes. | ||
2391 | */ | ||
2392 | page->pfmemalloc = true; | ||
2385 | goto got_pg; | 2393 | goto got_pg; |
2394 | } | ||
2386 | } | 2395 | } |
2387 | 2396 | ||
2388 | /* Atomic allocations - we can't balance anything */ | 2397 | /* Atomic allocations - we can't balance anything */ |
@@ -2499,14 +2508,6 @@ nopage: | |||
2499 | warn_alloc_failed(gfp_mask, order, NULL); | 2508 | warn_alloc_failed(gfp_mask, order, NULL); |
2500 | return page; | 2509 | return page; |
2501 | got_pg: | 2510 | got_pg: |
2502 | /* | ||
2503 | * page->pfmemalloc is set when the caller had PFMEMALLOC set, is | ||
2504 | * been OOM killed or specified __GFP_MEMALLOC. The expectation is | ||
2505 | * that the caller is taking steps that will free more memory. The | ||
2506 | * caller should avoid the page being used for !PFMEMALLOC purposes. | ||
2507 | */ | ||
2508 | page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS); | ||
2509 | |||
2510 | if (kmemcheck_enabled) | 2511 | if (kmemcheck_enabled) |
2511 | kmemcheck_pagealloc_alloc(page, order, gfp_mask); | 2512 | kmemcheck_pagealloc_alloc(page, order, gfp_mask); |
2512 | 2513 | ||