Skip to content

Commit

Permalink
mm: correct page->pfmemalloc to fix deactivate_slab regression
Browse files Browse the repository at this point in the history
Commit cfd19c5 ("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 <[email protected]>
Acked-by: Mel Gorman <[email protected]>
Cc: David Miller <[email protected]
Cc: Peter Zijlstra <[email protected]>
Tested-by: Eric Dumazet <[email protected]>
Tested-by: Sage Weil <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Alex Shi authored and torvalds committed Aug 21, 2012
1 parent 5ed12f1 commit b121186
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,17 @@ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,
zlc_active = 0;
goto zonelist_scan;
}

if (page)
/*
* page->pfmemalloc is set when ALLOC_NO_WATERMARKS was
* necessary to allocate the page. The expectation is
* that the caller is taking steps that will free more
* memory. The caller should avoid the page being used
* for !PFMEMALLOC purposes.
*/
page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS);

return page;
}

Expand Down Expand Up @@ -2389,14 +2400,6 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
zonelist, high_zoneidx, nodemask,
preferred_zone, migratetype);
if (page) {
/*
* page->pfmemalloc is set when ALLOC_NO_WATERMARKS was
* necessary to allocate the page. The expectation is
* that the caller is taking steps that will free more
* memory. The caller should avoid the page being used
* for !PFMEMALLOC purposes.
*/
page->pfmemalloc = true;
goto got_pg;
}
}
Expand Down Expand Up @@ -2569,8 +2572,6 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
page = __alloc_pages_slowpath(gfp_mask, order,
zonelist, high_zoneidx, nodemask,
preferred_zone, migratetype);
else
page->pfmemalloc = false;

trace_mm_page_alloc(page, order, gfp_mask, migratetype);

Expand Down

0 comments on commit b121186

Please sign in to comment.