__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.

[rient...@google.com: David noticed the problem during review]
Signed-off-by: Mel Gorman <mgor...@suse.de>
---
 mm/page_alloc.c |   27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f19c724..f88519b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2088,8 +2088,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int 
order,
 
                page = get_page_from_freelist(gfp_mask, nodemask,
                                order, zonelist, high_zoneidx,
-                               alloc_flags, preferred_zone,
-                               migratetype);
+                               alloc_flags & ~ALLOC_NO_WATERMARKS,
+                               preferred_zone, migratetype);
                if (page) {
                        preferred_zone->compact_considered = 0;
                        preferred_zone->compact_defer_shift = 0;
@@ -2181,8 +2181,8 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int 
order,
 retry:
        page = get_page_from_freelist(gfp_mask, nodemask, order,
                                        zonelist, high_zoneidx,
-                                       alloc_flags, preferred_zone,
-                                       migratetype);
+                                       alloc_flags & ~ALLOC_NO_WATERMARKS,
+                                       preferred_zone, migratetype);
 
        /*
         * If an allocation failed after direct reclaim, it could be because
@@ -2353,8 +2353,17 @@ rebalance:
                page = __alloc_pages_high_priority(gfp_mask, order,
                                zonelist, high_zoneidx, nodemask,
                                preferred_zone, migratetype);
-               if (page)
+               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;
+               }
        }
 
        /* Atomic allocations - we can't balance anything */
@@ -2471,14 +2480,6 @@ nopage:
        warn_alloc_failed(gfp_mask, order, NULL);
        return page;
 got_pg:
-       /*
-        * page->pfmemalloc is set when the caller had PFMEMALLOC set, is
-        * been OOM killed or specified __GFP_MEMALLOC. 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);
-
        if (kmemcheck_enabled)
                kmemcheck_pagealloc_alloc(page, order, gfp_mask);
 
-- 
1.7.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to