diff options
| author | Alex Shi <alex.shi@intel.com> | 2012-08-21 19:16:08 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-21 19:45:03 -0400 |
| commit | b121186ab1b12e2a96a945d88eae0735b4542158 (patch) | |
| tree | 9d142b77b090af2c508302457435f33143630a0b | |
| parent | 5ed12f12825c6c0451d703bfe918a7fc190e2738 (diff) | |
mm: correct page->pfmemalloc to fix deactivate_slab regression
Commit cfd19c5a9ecf ("mm: only set page->pfmemalloc when
ALLOC_NO_WATERMARKS was used") tried to narrow down page->pfmemalloc
setting, but it missed some places the pfmemalloc should be set.
So, in __slab_alloc, the unalignment pfmemalloc and ALLOC_NO_WATERMARKS
cause incorrect deactivate_slab() on our core2 server:
64.73% fio [kernel.kallsyms] [k] _raw_spin_lock
|
--- _raw_spin_lock
|
|---0.34%-- deactivate_slab
| __slab_alloc
| kmem_cache_alloc
| |
That causes our fio sync write performance to have a 40% regression.
Move the checking in get_page_from_freelist() which resolves this issue.
Signed-off-by: Alex Shi <alex.shi@intel.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Cc: David Miller <davem@davemloft.net
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Tested-by: Eric Dumazet <eric.dumazet@gmail.com>
Tested-by: Sage Weil <sage@inktank.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | mm/page_alloc.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 009ac285fea7..07f19248acb5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1928,6 +1928,17 @@ this_zone_full: | |||
| 1928 | zlc_active = 0; | 1928 | zlc_active = 0; |
| 1929 | goto zonelist_scan; | 1929 | goto zonelist_scan; |
| 1930 | } | 1930 | } |
| 1931 | |||
| 1932 | if (page) | ||
| 1933 | /* | ||
| 1934 | * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was | ||
| 1935 | * necessary to allocate the page. The expectation is | ||
| 1936 | * that the caller is taking steps that will free more | ||
| 1937 | * memory. The caller should avoid the page being used | ||
| 1938 | * for !PFMEMALLOC purposes. | ||
| 1939 | */ | ||
| 1940 | page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS); | ||
| 1941 | |||
| 1931 | return page; | 1942 | return page; |
| 1932 | } | 1943 | } |
| 1933 | 1944 | ||
| @@ -2389,14 +2400,6 @@ rebalance: | |||
| 2389 | zonelist, high_zoneidx, nodemask, | 2400 | zonelist, high_zoneidx, nodemask, |
| 2390 | preferred_zone, migratetype); | 2401 | preferred_zone, migratetype); |
| 2391 | if (page) { | 2402 | if (page) { |
| 2392 | /* | ||
| 2393 | * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was | ||
| 2394 | * necessary to allocate the page. The expectation is | ||
| 2395 | * that the caller is taking steps that will free more | ||
| 2396 | * memory. The caller should avoid the page being used | ||
| 2397 | * for !PFMEMALLOC purposes. | ||
| 2398 | */ | ||
| 2399 | page->pfmemalloc = true; | ||
| 2400 | goto got_pg; | 2403 | goto got_pg; |
| 2401 | } | 2404 | } |
| 2402 | } | 2405 | } |
| @@ -2569,8 +2572,6 @@ retry_cpuset: | |||
| 2569 | page = __alloc_pages_slowpath(gfp_mask, order, | 2572 | page = __alloc_pages_slowpath(gfp_mask, order, |
| 2570 | zonelist, high_zoneidx, nodemask, | 2573 | zonelist, high_zoneidx, nodemask, |
| 2571 | preferred_zone, migratetype); | 2574 | preferred_zone, migratetype); |
| 2572 | else | ||
| 2573 | page->pfmemalloc = false; | ||
| 2574 | 2575 | ||
| 2575 | trace_mm_page_alloc(page, order, gfp_mask, migratetype); | 2576 | trace_mm_page_alloc(page, order, gfp_mask, migratetype); |
| 2576 | 2577 | ||
