]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - mm/page_alloc.c
scripts/spelling.txt: add "algined" pattern and fix typo instances
[linux.git] / mm / page_alloc.c
index 8af0d4fa683db56c0ba0695c1e8939b57fd15fe4..a7a6aac95a6d158690e1ca0981b1b652820248d4 100644 (file)
@@ -59,7 +59,6 @@
 #include <linux/prefetch.h>
 #include <linux/mm_inline.h>
 #include <linux/migrate.h>
-#include <linux/page_ext.h>
 #include <linux/hugetlb.h>
 #include <linux/sched/rt.h>
 #include <linux/page_owner.h>
@@ -92,6 +91,10 @@ EXPORT_PER_CPU_SYMBOL(_numa_mem_);
 int _node_numa_mem_[MAX_NUMNODES];
 #endif
 
+/* work_structs for global per-cpu drains */
+DEFINE_MUTEX(pcpu_drain_mutex);
+DEFINE_PER_CPU(struct work_struct, pcpu_drain);
+
 #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
 volatile unsigned long latent_entropy __latent_entropy;
 EXPORT_SYMBOL(latent_entropy);
@@ -1085,10 +1088,10 @@ static void free_pcppages_bulk(struct zone *zone, int count,
 {
        int migratetype = 0;
        int batch_free = 0;
-       unsigned long nr_scanned;
+       unsigned long nr_scanned, flags;
        bool isolated_pageblocks;
 
-       spin_lock(&zone->lock);
+       spin_lock_irqsave(&zone->lock, flags);
        isolated_pageblocks = has_isolate_pageblock(zone);
        nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED);
        if (nr_scanned)
@@ -1137,7 +1140,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
                        trace_mm_page_pcpu_drain(page, 0, mt);
                } while (--count && --batch_free && !list_empty(list));
        }
-       spin_unlock(&zone->lock);
+       spin_unlock_irqrestore(&zone->lock, flags);
 }
 
 static void free_one_page(struct zone *zone,
@@ -1145,8 +1148,9 @@ static void free_one_page(struct zone *zone,
                                unsigned int order,
                                int migratetype)
 {
-       unsigned long nr_scanned;
-       spin_lock(&zone->lock);
+       unsigned long nr_scanned, flags;
+       spin_lock_irqsave(&zone->lock, flags);
+       __count_vm_events(PGFREE, 1 << order);
        nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED);
        if (nr_scanned)
                __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned);
@@ -1156,7 +1160,7 @@ static void free_one_page(struct zone *zone,
                migratetype = get_pfnblock_migratetype(page, pfn);
        }
        __free_one_page(page, pfn, zone, order, migratetype);
-       spin_unlock(&zone->lock);
+       spin_unlock_irqrestore(&zone->lock, flags);
 }
 
 static void __meminit __init_single_page(struct page *page, unsigned long pfn,
@@ -1234,7 +1238,6 @@ void __meminit reserve_bootmem_region(phys_addr_t start, phys_addr_t end)
 
 static void __free_pages_ok(struct page *page, unsigned int order)
 {
-       unsigned long flags;
        int migratetype;
        unsigned long pfn = page_to_pfn(page);
 
@@ -1242,10 +1245,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
                return;
 
        migratetype = get_pfnblock_migratetype(page, pfn);
-       local_irq_save(flags);
-       __count_vm_events(PGFREE, 1 << order);
        free_one_page(page_zone(page), page, pfn, order, migratetype);
-       local_irq_restore(flags);
 }
 
 static void __init __free_pages_boot_core(struct page *page, unsigned int order)
@@ -2217,8 +2217,9 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
                        int migratetype, bool cold)
 {
        int i, alloced = 0;
+       unsigned long flags;
 
-       spin_lock(&zone->lock);
+       spin_lock_irqsave(&zone->lock, flags);
        for (i = 0; i < count; ++i) {
                struct page *page = __rmqueue(zone, order, migratetype);
                if (unlikely(page == NULL))
@@ -2254,7 +2255,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
         * pages added to the pcp list.
         */
        __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
-       spin_unlock(&zone->lock);
+       spin_unlock_irqrestore(&zone->lock, flags);
        return alloced;
 }
 
@@ -2362,7 +2363,6 @@ static void drain_local_pages_wq(struct work_struct *work)
  */
 void drain_all_pages(struct zone *zone)
 {
-       struct work_struct __percpu *works;
        int cpu;
 
        /*
@@ -2375,7 +2375,16 @@ void drain_all_pages(struct zone *zone)
        if (current->flags & PF_WQ_WORKER)
                return;
 
-       works = alloc_percpu_gfp(struct work_struct, GFP_ATOMIC);
+       /*
+        * Do not drain if one is already in progress unless it's specific to
+        * a zone. Such callers are primarily CMA and memory hotplug and need
+        * the drain to be complete when the call returns.
+        */
+       if (unlikely(!mutex_trylock(&pcpu_drain_mutex))) {
+               if (!zone)
+                       return;
+               mutex_lock(&pcpu_drain_mutex);
+       }
 
        /*
         * We don't care about racing with CPU hotplug event
@@ -2408,23 +2417,15 @@ void drain_all_pages(struct zone *zone)
                        cpumask_clear_cpu(cpu, &cpus_with_pcps);
        }
 
-       if (works) {
-               for_each_cpu(cpu, &cpus_with_pcps) {
-                       struct work_struct *work = per_cpu_ptr(works, cpu);
-                       INIT_WORK(work, drain_local_pages_wq);
-                       schedule_work_on(cpu, work);
-               }
-               for_each_cpu(cpu, &cpus_with_pcps)
-                       flush_work(per_cpu_ptr(works, cpu));
-       } else {
-               for_each_cpu(cpu, &cpus_with_pcps) {
-                       struct work_struct work;
-
-                       INIT_WORK(&work, drain_local_pages_wq);
-                       schedule_work_on(cpu, &work);
-                       flush_work(&work);
-               }
+       for_each_cpu(cpu, &cpus_with_pcps) {
+               struct work_struct *work = per_cpu_ptr(&pcpu_drain, cpu);
+               INIT_WORK(work, drain_local_pages_wq);
+               schedule_work_on(cpu, work);
        }
+       for_each_cpu(cpu, &cpus_with_pcps)
+               flush_work(per_cpu_ptr(&pcpu_drain, cpu));
+
+       mutex_unlock(&pcpu_drain_mutex);
 }
 
 #ifdef CONFIG_HIBERNATION
@@ -2475,17 +2476,20 @@ void free_hot_cold_page(struct page *page, bool cold)
 {
        struct zone *zone = page_zone(page);
        struct per_cpu_pages *pcp;
-       unsigned long flags;
        unsigned long pfn = page_to_pfn(page);
        int migratetype;
 
+       if (in_interrupt()) {
+               __free_pages_ok(page, 0);
+               return;
+       }
+
        if (!free_pcp_prepare(page))
                return;
 
        migratetype = get_pfnblock_migratetype(page, pfn);
        set_pcppage_migratetype(page, migratetype);
-       local_irq_save(flags);
-       __count_vm_event(PGFREE);
+       preempt_disable();
 
        /*
         * We only track unmovable, reclaimable and movable on pcp lists.
@@ -2502,6 +2506,7 @@ void free_hot_cold_page(struct page *page, bool cold)
                migratetype = MIGRATE_MOVABLE;
        }
 
+       __count_vm_event(PGFREE);
        pcp = &this_cpu_ptr(zone->pageset)->pcp;
        if (!cold)
                list_add(&page->lru, &pcp->lists[migratetype]);
@@ -2515,7 +2520,7 @@ void free_hot_cold_page(struct page *page, bool cold)
        }
 
 out:
-       local_irq_restore(flags);
+       preempt_enable();
 }
 
 /*
@@ -2640,6 +2645,8 @@ static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype,
 {
        struct page *page;
 
+       VM_BUG_ON(in_interrupt());
+
        do {
                if (list_empty(list)) {
                        pcp->count += rmqueue_bulk(zone, 0,
@@ -2670,9 +2677,8 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone,
        struct list_head *list;
        bool cold = ((gfp_flags & __GFP_COLD) != 0);
        struct page *page;
-       unsigned long flags;
 
-       local_irq_save(flags);
+       preempt_disable();
        pcp = &this_cpu_ptr(zone->pageset)->pcp;
        list = &pcp->lists[migratetype];
        page = __rmqueue_pcplist(zone,  migratetype, cold, pcp, list);
@@ -2680,7 +2686,7 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone,
                __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order);
                zone_statistics(preferred_zone, zone);
        }
-       local_irq_restore(flags);
+       preempt_enable();
        return page;
 }
 
@@ -2696,7 +2702,7 @@ struct page *rmqueue(struct zone *preferred_zone,
        unsigned long flags;
        struct page *page;
 
-       if (likely(order == 0)) {
+       if (likely(order == 0) && !in_interrupt()) {
                page = rmqueue_pcplist(preferred_zone, zone, order,
                                gfp_flags, migratetype);
                goto out;
@@ -2938,7 +2944,7 @@ bool zone_watermark_ok_safe(struct zone *z, unsigned int order,
 #ifdef CONFIG_NUMA
 static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
 {
-       return node_distance(zone_to_nid(local_zone), zone_to_nid(zone)) <
+       return node_distance(zone_to_nid(local_zone), zone_to_nid(zone)) <=
                                RECLAIM_DISTANCE;
 }
 #else  /* CONFIG_NUMA */
@@ -3900,9 +3906,10 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
 
        if (cpusets_enabled()) {
                *alloc_mask |= __GFP_HARDWALL;
-               *alloc_flags |= ALLOC_CPUSET;
                if (!ac->nodemask)
                        ac->nodemask = &cpuset_current_mems_allowed;
+               else
+                       *alloc_flags |= ALLOC_CPUSET;
        }
 
        lockdep_trace_alloc(gfp_mask);
@@ -3912,14 +3919,6 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
        if (should_fail_alloc_page(gfp_mask, order))
                return false;
 
-       /*
-        * Check the zones suitable for the gfp_mask contain at least one
-        * valid zone. It's possible to have an empty zonelist as a result
-        * of __GFP_THISNODE and a memoryless node
-        */
-       if (unlikely(!ac->zonelist->_zonerefs->zone))
-               return false;
-
        if (IS_ENABLED(CONFIG_CMA) && ac->migratetype == MIGRATE_MOVABLE)
                *alloc_flags |= ALLOC_CMA;
 
@@ -3959,22 +3958,12 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
                return NULL;
 
        finalise_ac(gfp_mask, order, &ac);
-       if (!ac.preferred_zoneref->zone) {
-               page = NULL;
-               /*
-                * This might be due to race with cpuset_current_mems_allowed
-                * update, so make sure we retry with original nodemask in the
-                * slow path.
-                */
-               goto no_zone;
-       }
 
        /* First allocation attempt */
        page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac);
        if (likely(page))
                goto out;
 
-no_zone:
        /*
         * Runtime PM, block IO and its error handling path can deadlock
         * because I/O on the device might not complete.
@@ -5936,7 +5925,7 @@ static unsigned long __paginginit calc_memmap_size(unsigned long spanned_pages,
         * the zone and SPARSEMEM is in use. If there are holes within the
         * zone, each populated memory region may cost us one or two extra
         * memmap pages due to alignment because memmap pages for each
-        * populated regions may not naturally algined on page boundary.
+        * populated regions may not be naturally aligned on page boundary.
         * So the (present_pages >> 4) heuristic is a tradeoff for that.
         */
        if (spanned_pages > present_pages + (present_pages >> 4) &&
@@ -6500,8 +6489,6 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
 
                start_pfn = end_pfn;
        }
-       arch_zone_lowest_possible_pfn[ZONE_MOVABLE] = 0;
-       arch_zone_highest_possible_pfn[ZONE_MOVABLE] = 0;
 
        /* Find the PFNs that ZONE_MOVABLE begins at in each node */
        memset(zone_movable_pfn, 0, sizeof(zone_movable_pfn));
@@ -7237,8 +7224,9 @@ void *__init alloc_large_system_hash(const char *tablename,
  * If @count is not zero, it is okay to include less @count unmovable pages
  *
  * PageLRU check without isolation or lru_lock could race so that
- * MIGRATE_MOVABLE block might include unmovable pages. It means you can't
- * expect this function should be exact.
+ * MIGRATE_MOVABLE block might include unmovable pages. And __PageMovable
+ * check without lock_page also may miss some movable non-lru pages at
+ * race condition. So you can't expect this function should be exact.
  */
 bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
                         bool skip_hwpoisoned_pages)
@@ -7294,6 +7282,9 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
                if (skip_hwpoisoned_pages && PageHWPoison(page))
                        continue;
 
+               if (__PageMovable(page))
+                       continue;
+
                if (!PageLRU(page))
                        found++;
                /*
@@ -7405,6 +7396,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
  *                     #MIGRATE_MOVABLE or #MIGRATE_CMA).  All pageblocks
  *                     in range must have the same migratetype and it must
  *                     be either of the two.
+ * @gfp_mask:  GFP mask to use during compaction
  *
  * The PFN range does not have to be pageblock or MAX_ORDER_NR_PAGES
  * aligned, however it's the caller's responsibility to guarantee that
@@ -7418,7 +7410,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
  * need to be freed with free_contig_range().
  */
 int alloc_contig_range(unsigned long start, unsigned long end,
-                      unsigned migratetype)
+                      unsigned migratetype, gfp_t gfp_mask)
 {
        unsigned long outer_start, outer_end;
        unsigned int order;
@@ -7430,7 +7422,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
                .zone = page_zone(pfn_to_page(start)),
                .mode = MIGRATE_SYNC,
                .ignore_skip_hint = true,
-               .gfp_mask = GFP_KERNEL,
+               .gfp_mask = memalloc_noio_flags(gfp_mask),
        };
        INIT_LIST_HEAD(&cc.migratepages);