mm: use proper type for cma_[alloc|release]
[linux-2.6-block.git] / mm / page_alloc.c
index c73557bb8c58a8c732cb91c2af35dcab0d156eb8..d12299c08b95c4f90947c93e7994824098792292 100644 (file)
@@ -72,8 +72,6 @@
 #include <linux/padata.h>
 #include <linux/khugepaged.h>
 #include <linux/buffer_head.h>
-#include <linux/vmalloc.h>
-
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -788,32 +786,36 @@ static inline void clear_page_guard(struct zone *zone, struct page *page,
  */
 void init_mem_debugging_and_hardening(void)
 {
+       bool page_poisoning_requested = false;
+
+#ifdef CONFIG_PAGE_POISONING
+       /*
+        * Page poisoning is debug page alloc for some arches. If
+        * either of those options are enabled, enable poisoning.
+        */
+       if (page_poisoning_enabled() ||
+            (!IS_ENABLED(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) &&
+             debug_pagealloc_enabled())) {
+               static_branch_enable(&_page_poisoning_enabled);
+               page_poisoning_requested = true;
+       }
+#endif
+
        if (_init_on_alloc_enabled_early) {
-               if (page_poisoning_enabled())
+               if (page_poisoning_requested)
                        pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, "
                                "will take precedence over init_on_alloc\n");
                else
                        static_branch_enable(&init_on_alloc);
        }
        if (_init_on_free_enabled_early) {
-               if (page_poisoning_enabled())
+               if (page_poisoning_requested)
                        pr_info("mem auto-init: CONFIG_PAGE_POISONING is on, "
                                "will take precedence over init_on_free\n");
                else
                        static_branch_enable(&init_on_free);
        }
 
-#ifdef CONFIG_PAGE_POISONING
-       /*
-        * Page poisoning is debug page alloc for some arches. If
-        * either of those options are enabled, enable poisoning.
-        */
-       if (page_poisoning_enabled() ||
-            (!IS_ENABLED(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) &&
-             debug_pagealloc_enabled()))
-               static_branch_enable(&_page_poisoning_enabled);
-#endif
-
 #ifdef CONFIG_DEBUG_PAGEALLOC
        if (!debug_pagealloc_enabled())
                return;
@@ -2431,19 +2433,21 @@ static inline struct page *__rmqueue_cma_fallback(struct zone *zone,
  * boundary. If alignment is required, use move_freepages_block()
  */
 static int move_freepages(struct zone *zone,
-                         struct page *start_page, struct page *end_page,
+                         unsigned long start_pfn, unsigned long end_pfn,
                          int migratetype, int *num_movable)
 {
        struct page *page;
+       unsigned long pfn;
        unsigned int order;
        int pages_moved = 0;
 
-       for (page = start_page; page <= end_page;) {
-               if (!pfn_valid_within(page_to_pfn(page))) {
-                       page++;
+       for (pfn = start_pfn; pfn <= end_pfn;) {
+               if (!pfn_valid_within(pfn)) {
+                       pfn++;
                        continue;
                }
 
+               page = pfn_to_page(pfn);
                if (!PageBuddy(page)) {
                        /*
                         * We assume that pages that could be isolated for
@@ -2453,8 +2457,7 @@ static int move_freepages(struct zone *zone,
                        if (num_movable &&
                                        (PageLRU(page) || __PageMovable(page)))
                                (*num_movable)++;
-
-                       page++;
+                       pfn++;
                        continue;
                }
 
@@ -2464,7 +2467,7 @@ static int move_freepages(struct zone *zone,
 
                order = buddy_order(page);
                move_to_free_list(page, zone, order, migratetype);
-               page += 1 << order;
+               pfn += 1 << order;
                pages_moved += 1 << order;
        }
 
@@ -2474,25 +2477,22 @@ static int move_freepages(struct zone *zone,
 int move_freepages_block(struct zone *zone, struct page *page,
                                int migratetype, int *num_movable)
 {
-       unsigned long start_pfn, end_pfn;
-       struct page *start_page, *end_page;
+       unsigned long start_pfn, end_pfn, pfn;
 
        if (num_movable)
                *num_movable = 0;
 
-       start_pfn = page_to_pfn(page);
-       start_pfn = start_pfn & ~(pageblock_nr_pages-1);
-       start_page = pfn_to_page(start_pfn);
-       end_page = start_page + pageblock_nr_pages - 1;
+       pfn = page_to_pfn(page);
+       start_pfn = pfn & ~(pageblock_nr_pages - 1);
        end_pfn = start_pfn + pageblock_nr_pages - 1;
 
        /* Do not cross zone boundaries */
        if (!zone_spans_pfn(zone, start_pfn))
-               start_page = page;
+               start_pfn = pfn;
        if (!zone_spans_pfn(zone, end_pfn))
                return 0;
 
-       return move_freepages(zone, start_page, end_page, migratetype,
+       return move_freepages(zone, start_pfn, end_pfn, migratetype,
                                                                num_movable);
 }
 
@@ -2953,7 +2953,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
                        unsigned long count, struct list_head *list,
                        int migratetype, unsigned int alloc_flags)
 {
-       int i, alloced = 0;
+       int i, allocated = 0;
 
        spin_lock(&zone->lock);
        for (i = 0; i < count; ++i) {
@@ -2976,7 +2976,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
                 * pages are ordered properly.
                 */
                list_add_tail(&page->lru, list);
-               alloced++;
+               allocated++;
                if (is_migrate_cma(get_pcppage_migratetype(page)))
                        __mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
                                              -(1 << order));
@@ -2985,12 +2985,12 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
        /*
         * i pages were removed from the buddy list even if some leak due
         * to check_pcp_refill failing so adjust NR_FREE_PAGES based
-        * on i. Do not confuse with 'alloced' which is the number of
+        * on i. Do not confuse with 'allocated' which is the number of
         * pages added to the pcp list.
         */
        __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
        spin_unlock(&zone->lock);
-       return alloced;
+       return allocated;
 }
 
 #ifdef CONFIG_NUMA
@@ -3460,7 +3460,8 @@ static inline void zone_statistics(struct zone *preferred_zone, struct zone *z)
 }
 
 /* Remove page from the per-cpu list, caller must protect the list */
-static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype,
+static inline
+struct page *__rmqueue_pcplist(struct zone *zone, int migratetype,
                        unsigned int alloc_flags,
                        struct per_cpu_pages *pcp,
                        struct list_head *list)
@@ -3967,7 +3968,7 @@ retry:
                        if (alloc_flags & ALLOC_NO_WATERMARKS)
                                goto try_this_zone;
 
-                       if (node_reclaim_mode == 0 ||
+                       if (!node_reclaim_enabled() ||
                            !zone_allows_reclaim(ac->preferred_zoneref->zone, zone))
                                continue;
 
@@ -4203,6 +4204,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
        memalloc_noreclaim_restore(noreclaim_flag);
        psi_memstall_leave(&pflags);
 
+       if (*compact_result == COMPACT_SKIPPED)
+               return NULL;
        /*
         * At least in one zone compaction wasn't deferred or skipped, so let's
         * count a compaction stall
@@ -4966,7 +4969,7 @@ got_pg:
 
 static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
                int preferred_nid, nodemask_t *nodemask,
-               struct alloc_context *ac, gfp_t *alloc_mask,
+               struct alloc_context *ac, gfp_t *alloc_gfp,
                unsigned int *alloc_flags)
 {
        ac->highest_zoneidx = gfp_zone(gfp_mask);
@@ -4975,7 +4978,7 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
        ac->migratetype = gfp_migratetype(gfp_mask);
 
        if (cpusets_enabled()) {
-               *alloc_mask |= __GFP_HARDWALL;
+               *alloc_gfp |= __GFP_HARDWALL;
                /*
                 * When we are in the interrupt context, it is irrelevant
                 * to the current task context. It means that any node ok.
@@ -5010,16 +5013,161 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
        return true;
 }
 
+/*
+ * __alloc_pages_bulk - Allocate a number of order-0 pages to a list or array
+ * @gfp: GFP flags for the allocation
+ * @preferred_nid: The preferred NUMA node ID to allocate from
+ * @nodemask: Set of nodes to allocate from, may be NULL
+ * @nr_pages: The number of pages desired on the list or array
+ * @page_list: Optional list to store the allocated pages
+ * @page_array: Optional array to store the pages
+ *
+ * This is a batched version of the page allocator that attempts to
+ * allocate nr_pages quickly. Pages are added to page_list if page_list
+ * is not NULL, otherwise it is assumed that the page_array is valid.
+ *
+ * For lists, nr_pages is the number of pages that should be allocated.
+ *
+ * For arrays, only NULL elements are populated with pages and nr_pages
+ * is the maximum number of pages that will be stored in the array.
+ *
+ * Returns the number of pages on the list or array.
+ */
+unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
+                       nodemask_t *nodemask, int nr_pages,
+                       struct list_head *page_list,
+                       struct page **page_array)
+{
+       struct page *page;
+       unsigned long flags;
+       struct zone *zone;
+       struct zoneref *z;
+       struct per_cpu_pages *pcp;
+       struct list_head *pcp_list;
+       struct alloc_context ac;
+       gfp_t alloc_gfp;
+       unsigned int alloc_flags = ALLOC_WMARK_LOW;
+       int nr_populated = 0;
+
+       if (unlikely(nr_pages <= 0))
+               return 0;
+
+       /*
+        * Skip populated array elements to determine if any pages need
+        * to be allocated before disabling IRQs.
+        */
+       while (page_array && page_array[nr_populated] && nr_populated < nr_pages)
+               nr_populated++;
+
+       /* Use the single page allocator for one page. */
+       if (nr_pages - nr_populated == 1)
+               goto failed;
+
+       /* May set ALLOC_NOFRAGMENT, fragmentation will return 1 page. */
+       gfp &= gfp_allowed_mask;
+       alloc_gfp = gfp;
+       if (!prepare_alloc_pages(gfp, 0, preferred_nid, nodemask, &ac, &alloc_gfp, &alloc_flags))
+               return 0;
+       gfp = alloc_gfp;
+
+       /* Find an allowed local zone that meets the low watermark. */
+       for_each_zone_zonelist_nodemask(zone, z, ac.zonelist, ac.highest_zoneidx, ac.nodemask) {
+               unsigned long mark;
+
+               if (cpusets_enabled() && (alloc_flags & ALLOC_CPUSET) &&
+                   !__cpuset_zone_allowed(zone, gfp)) {
+                       continue;
+               }
+
+               if (nr_online_nodes > 1 && zone != ac.preferred_zoneref->zone &&
+                   zone_to_nid(zone) != zone_to_nid(ac.preferred_zoneref->zone)) {
+                       goto failed;
+               }
+
+               mark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK) + nr_pages;
+               if (zone_watermark_fast(zone, 0,  mark,
+                               zonelist_zone_idx(ac.preferred_zoneref),
+                               alloc_flags, gfp)) {
+                       break;
+               }
+       }
+
+       /*
+        * If there are no allowed local zones that meets the watermarks then
+        * try to allocate a single page and reclaim if necessary.
+        */
+       if (unlikely(!zone))
+               goto failed;
+
+       /* Attempt the batch allocation */
+       local_irq_save(flags);
+       pcp = &this_cpu_ptr(zone->pageset)->pcp;
+       pcp_list = &pcp->lists[ac.migratetype];
+
+       while (nr_populated < nr_pages) {
+
+               /* Skip existing pages */
+               if (page_array && page_array[nr_populated]) {
+                       nr_populated++;
+                       continue;
+               }
+
+               page = __rmqueue_pcplist(zone, ac.migratetype, alloc_flags,
+                                                               pcp, pcp_list);
+               if (unlikely(!page)) {
+                       /* Try and get at least one page */
+                       if (!nr_populated)
+                               goto failed_irq;
+                       break;
+               }
+
+               /*
+                * Ideally this would be batched but the best way to do
+                * that cheaply is to first convert zone_statistics to
+                * be inaccurate per-cpu counter like vm_events to avoid
+                * a RMW cycle then do the accounting with IRQs enabled.
+                */
+               __count_zid_vm_events(PGALLOC, zone_idx(zone), 1);
+               zone_statistics(ac.preferred_zoneref->zone, zone);
+
+               prep_new_page(page, 0, gfp, 0);
+               if (page_list)
+                       list_add(&page->lru, page_list);
+               else
+                       page_array[nr_populated] = page;
+               nr_populated++;
+       }
+
+       local_irq_restore(flags);
+
+       return nr_populated;
+
+failed_irq:
+       local_irq_restore(flags);
+
+failed:
+       page = __alloc_pages(gfp, 0, preferred_nid, nodemask);
+       if (page) {
+               if (page_list)
+                       list_add(&page->lru, page_list);
+               else
+                       page_array[nr_populated] = page;
+               nr_populated++;
+       }
+
+       return nr_populated;
+}
+EXPORT_SYMBOL_GPL(__alloc_pages_bulk);
+
 /*
  * This is the 'heart' of the zoned buddy allocator.
  */
-struct page *
-__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
+struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid,
                                                        nodemask_t *nodemask)
 {
        struct page *page;
        unsigned int alloc_flags = ALLOC_WMARK_LOW;
-       gfp_t alloc_mask; /* The gfp_t that was actually used for allocation */
+       gfp_t alloc_gfp; /* The gfp_t that was actually used for allocation */
        struct alloc_context ac = { };
 
        /*
@@ -5027,23 +5175,24 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
         * so bail out early if the request is out of bound.
         */
        if (unlikely(order >= MAX_ORDER)) {
-               WARN_ON_ONCE(!(gfp_mask & __GFP_NOWARN));
+               WARN_ON_ONCE(!(gfp & __GFP_NOWARN));
                return NULL;
        }
 
-       gfp_mask &= gfp_allowed_mask;
-       alloc_mask = gfp_mask;
-       if (!prepare_alloc_pages(gfp_mask, order, preferred_nid, nodemask, &ac, &alloc_mask, &alloc_flags))
+       gfp &= gfp_allowed_mask;
+       alloc_gfp = gfp;
+       if (!prepare_alloc_pages(gfp, order, preferred_nid, nodemask, &ac,
+                       &alloc_gfp, &alloc_flags))
                return NULL;
 
        /*
         * Forbid the first pass from falling back to types that fragment
         * memory until all local zones are considered.
         */
-       alloc_flags |= alloc_flags_nofragment(ac.preferred_zoneref->zone, gfp_mask);
+       alloc_flags |= alloc_flags_nofragment(ac.preferred_zoneref->zone, gfp);
 
        /* First allocation attempt */
-       page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac);
+       page = get_page_from_freelist(alloc_gfp, order, alloc_flags, &ac);
        if (likely(page))
                goto out;
 
@@ -5053,7 +5202,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
         * from a particular context which has been marked by
         * memalloc_no{fs,io}_{save,restore}.
         */
-       alloc_mask = current_gfp_context(gfp_mask);
+       alloc_gfp = current_gfp_context(gfp);
        ac.spread_dirty_pages = false;
 
        /*
@@ -5062,20 +5211,20 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
         */
        ac.nodemask = nodemask;
 
-       page = __alloc_pages_slowpath(alloc_mask, order, &ac);
+       page = __alloc_pages_slowpath(alloc_gfp, order, &ac);
 
 out:
-       if (memcg_kmem_enabled() && (gfp_mask & __GFP_ACCOUNT) && page &&
-           unlikely(__memcg_kmem_charge_page(page, gfp_mask, order) != 0)) {
+       if (memcg_kmem_enabled() && (gfp & __GFP_ACCOUNT) && page &&
+           unlikely(__memcg_kmem_charge_page(page, gfp, order) != 0)) {
                __free_pages(page, order);
                page = NULL;
        }
 
-       trace_mm_page_alloc(page, order, alloc_mask, ac.migratetype);
+       trace_mm_page_alloc(page, order, alloc_gfp, ac.migratetype);
 
        return page;
 }
-EXPORT_SYMBOL(__alloc_pages_nodemask);
+EXPORT_SYMBOL(__alloc_pages);
 
 /*
  * Common helper functions. Never use with __GFP_HIGHMEM because the returned
@@ -8497,6 +8646,27 @@ static unsigned long pfn_max_align_up(unsigned long pfn)
                                pageblock_nr_pages));
 }
 
+#if defined(CONFIG_DYNAMIC_DEBUG) || \
+       (defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))
+/* Usage: See admin-guide/dynamic-debug-howto.rst */
+static void alloc_contig_dump_pages(struct list_head *page_list)
+{
+       DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, "migrate failure");
+
+       if (DYNAMIC_DEBUG_BRANCH(descriptor)) {
+               struct page *page;
+
+               dump_stack();
+               list_for_each_entry(page, page_list, lru)
+                       dump_page(page, "migration failure");
+       }
+}
+#else
+static inline void alloc_contig_dump_pages(struct list_head *page_list)
+{
+}
+#endif
+
 /* [start, end) must belong to a single zone. */
 static int __alloc_contig_migrate_range(struct compact_control *cc,
                                        unsigned long start, unsigned long end)
@@ -8511,7 +8681,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
                .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
        };
 
-       migrate_prep();
+       lru_cache_disable();
 
        while (pfn < end || !list_empty(&cc->migratepages)) {
                if (fatal_signal_pending(current)) {
@@ -8521,14 +8691,13 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
 
                if (list_empty(&cc->migratepages)) {
                        cc->nr_migratepages = 0;
-                       pfn = isolate_migratepages_range(cc, pfn, end);
-                       if (!pfn) {
-                               ret = -EINTR;
+                       ret = isolate_migratepages_range(cc, pfn, end);
+                       if (ret && ret != -EAGAIN)
                                break;
-                       }
+                       pfn = cc->migrate_pfn;
                        tries = 0;
                } else if (++tries == 5) {
-                       ret = ret < 0 ? ret : -EBUSY;
+                       ret = -EBUSY;
                        break;
                }
 
@@ -8538,8 +8707,18 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
 
                ret = migrate_pages(&cc->migratepages, alloc_migration_target,
                                NULL, (unsigned long)&mtc, cc->mode, MR_CONTIG_RANGE);
+
+               /*
+                * On -ENOMEM, migrate_pages() bails out right away. It is pointless
+                * to retry again over this error, so do the same here.
+                */
+               if (ret == -ENOMEM)
+                       break;
        }
+
+       lru_cache_enable();
        if (ret < 0) {
+               alloc_contig_dump_pages(&cc->migratepages);
                putback_movable_pages(&cc->migratepages);
                return ret;
        }
@@ -8723,12 +8902,6 @@ static bool pfn_range_valid_contig(struct zone *z, unsigned long start_pfn,
 
                if (PageReserved(page))
                        return false;
-
-               if (page_count(page) > 0)
-                       return false;
-
-               if (PageHuge(page))
-                       return false;
        }
        return true;
 }
@@ -8800,9 +8973,9 @@ struct page *alloc_contig_pages(unsigned long nr_pages, gfp_t gfp_mask,
 }
 #endif /* CONFIG_CONTIG_ALLOC */
 
-void free_contig_range(unsigned long pfn, unsigned int nr_pages)
+void free_contig_range(unsigned long pfn, unsigned long nr_pages)
 {
-       unsigned int count = 0;
+       unsigned long count = 0;
 
        for (; nr_pages--; pfn++) {
                struct page *page = pfn_to_page(pfn);
@@ -8810,7 +8983,7 @@ void free_contig_range(unsigned long pfn, unsigned int nr_pages)
                count += page_count(page) != 1;
                __free_page(page);
        }
-       WARN(count != 0, "%d pages are still in use!\n", count);
+       WARN(count != 0, "%lu pages are still in use!\n", count);
 }
 EXPORT_SYMBOL(free_contig_range);