power: rk818 charger: remove suspend and resume callback
[firefly-linux-kernel-4.4.55.git] / mm / page_alloc.c
index 89ef8347900c93505576b338ea3c2dd0ebf2b98b..8bbefa93eb773b8f552396d5052640a0b43561c7 100644 (file)
@@ -674,34 +674,28 @@ static inline void __free_one_page(struct page *page,
        unsigned long combined_idx;
        unsigned long uninitialized_var(buddy_idx);
        struct page *buddy;
-       unsigned int max_order = MAX_ORDER;
+       unsigned int max_order;
+
+       max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1);
 
        VM_BUG_ON(!zone_is_initialized(zone));
        VM_BUG_ON_PAGE(page->flags & PAGE_FLAGS_CHECK_AT_PREP, page);
 
        VM_BUG_ON(migratetype == -1);
-       if (is_migrate_isolate(migratetype)) {
-               /*
-                * We restrict max order of merging to prevent merge
-                * between freepages on isolate pageblock and normal
-                * pageblock. Without this, pageblock isolation
-                * could cause incorrect freepage accounting.
-                */
-               max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1);
-       } else {
+       if (likely(!is_migrate_isolate(migratetype)))
                __mod_zone_freepage_state(zone, 1 << order, migratetype);
-       }
 
-       page_idx = pfn & ((1 << max_order) - 1);
+       page_idx = pfn & ((1 << MAX_ORDER) - 1);
 
        VM_BUG_ON_PAGE(page_idx & ((1 << order) - 1), page);
        VM_BUG_ON_PAGE(bad_range(zone, page), page);
 
+continue_merging:
        while (order < max_order - 1) {
                buddy_idx = __find_buddy_index(page_idx, order);
                buddy = page + (buddy_idx - page_idx);
                if (!page_is_buddy(page, buddy, order))
-                       break;
+                       goto done_merging;
                /*
                 * Our buddy is free or it is CONFIG_DEBUG_PAGEALLOC guard page,
                 * merge with it and move up one order.
@@ -718,6 +712,32 @@ static inline void __free_one_page(struct page *page,
                page_idx = combined_idx;
                order++;
        }
+       if (max_order < MAX_ORDER) {
+               /* If we are here, it means order is >= pageblock_order.
+                * We want to prevent merge between freepages on isolate
+                * pageblock and normal pageblock. Without this, pageblock
+                * isolation could cause incorrect freepage or CMA accounting.
+                *
+                * We don't want to hit this code for the more frequent
+                * low-order merging.
+                */
+               if (unlikely(has_isolate_pageblock(zone))) {
+                       int buddy_mt;
+
+                       buddy_idx = __find_buddy_index(page_idx, order);
+                       buddy = page + (buddy_idx - page_idx);
+                       buddy_mt = get_pageblock_migratetype(buddy);
+
+                       if (migratetype != buddy_mt
+                                       && (is_migrate_isolate(migratetype) ||
+                                               is_migrate_isolate(buddy_mt)))
+                               goto done_merging;
+               }
+               max_order++;
+               goto continue_merging;
+       }
+
+done_merging:
        set_page_order(page, order);
 
        /*
@@ -943,7 +963,7 @@ static inline void init_reserved_page(unsigned long pfn)
  * marks the pages PageReserved. The remaining valid pages are later
  * sent to the buddy page allocator.
  */
-void __meminit reserve_bootmem_region(unsigned long start, unsigned long end)
+void __meminit reserve_bootmem_region(phys_addr_t start, phys_addr_t end)
 {
        unsigned long start_pfn = PFN_DOWN(start);
        unsigned long end_pfn = PFN_UP(end);
@@ -6191,7 +6211,7 @@ int __meminit init_per_zone_wmark_min(void)
        setup_per_zone_inactive_ratio();
        return 0;
 }
-module_init(init_per_zone_wmark_min)
+core_initcall(init_per_zone_wmark_min)
 
 /*
  * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so