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 /mm/page_alloc.c | |
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>
Diffstat (limited to 'mm/page_alloc.c')
-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 | ||