Merge tag 'mm-stable-2024-03-13-20-04' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / mm / page_alloc.c
index cc7f9b3..14d39f3 100644 (file)
@@ -4047,6 +4047,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
                                                struct alloc_context *ac)
 {
        bool can_direct_reclaim = gfp_mask & __GFP_DIRECT_RECLAIM;
+       bool can_compact = gfp_compaction_allowed(gfp_mask);
        const bool costly_order = order > PAGE_ALLOC_COSTLY_ORDER;
        struct page *page = NULL;
        unsigned int alloc_flags;
@@ -4117,7 +4118,7 @@ restart:
         * Don't try this for allocations that are allowed to ignore
         * watermarks, as the ALLOC_NO_WATERMARKS attempt didn't yet happen.
         */
-       if (can_direct_reclaim &&
+       if (can_direct_reclaim && can_compact &&
                        (costly_order ||
                           (order > 0 && ac->migratetype != MIGRATE_MOVABLE))
                        && !gfp_pfmemalloc_allowed(gfp_mask)) {
@@ -4215,9 +4216,10 @@ retry:
 
        /*
         * Do not retry costly high order allocations unless they are
-        * __GFP_RETRY_MAYFAIL
+        * __GFP_RETRY_MAYFAIL and we can compact
         */
-       if (costly_order && !(gfp_mask & __GFP_RETRY_MAYFAIL))
+       if (costly_order && (!can_compact ||
+                            !(gfp_mask & __GFP_RETRY_MAYFAIL)))
                goto nopage;
 
        if (should_reclaim_retry(gfp_mask, order, ac, alloc_flags,
@@ -4230,7 +4232,7 @@ retry:
         * implementation of the compaction depends on the sufficient amount
         * of free memory (see __compaction_suitable)
         */
-       if (did_some_progress > 0 &&
+       if (did_some_progress > 0 && can_compact &&
                        should_compact_retry(ac, order, alloc_flags,
                                compact_result, &compact_priority,
                                &compaction_retries))
@@ -4691,8 +4693,8 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc,
        gfp_t gfp = gfp_mask;
 
 #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE)
-       gfp_mask |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY |
-                   __GFP_NOMEMALLOC;
+       gfp_mask = (gfp_mask & ~__GFP_DIRECT_RECLAIM) |  __GFP_COMP |
+                  __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC;
        page = alloc_pages_node(NUMA_NO_NODE, gfp_mask,
                                PAGE_FRAG_CACHE_MAX_ORDER);
        nc->size = page ? PAGE_FRAG_CACHE_MAX_SIZE : PAGE_SIZE;
@@ -4705,6 +4707,16 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc,
        return page;
 }
 
+void page_frag_cache_drain(struct page_frag_cache *nc)
+{
+       if (!nc->va)
+               return;
+
+       __page_frag_cache_drain(virt_to_head_page(nc->va), nc->pagecnt_bias);
+       nc->va = NULL;
+}
+EXPORT_SYMBOL(page_frag_cache_drain);
+
 void __page_frag_cache_drain(struct page *page, unsigned int count)
 {
        VM_BUG_ON_PAGE(page_ref_count(page) == 0, page);
@@ -4714,9 +4726,9 @@ void __page_frag_cache_drain(struct page *page, unsigned int count)
 }
 EXPORT_SYMBOL(__page_frag_cache_drain);
 
-void *page_frag_alloc_align(struct page_frag_cache *nc,
-                     unsigned int fragsz, gfp_t gfp_mask,
-                     unsigned int align_mask)
+void *__page_frag_alloc_align(struct page_frag_cache *nc,
+                             unsigned int fragsz, gfp_t gfp_mask,
+                             unsigned int align_mask)
 {
        unsigned int size = PAGE_SIZE;
        struct page *page;
@@ -4785,7 +4797,7 @@ refill:
 
        return nc->va + offset;
 }
-EXPORT_SYMBOL(page_frag_alloc_align);
+EXPORT_SYMBOL(__page_frag_alloc_align);
 
 /*
  * Frees a page fragment allocated out of either a compound or order 0 page.