tunnels: fix netns vs proto registration ordering
[safe/jmp/linux-2.6] / mm / page_alloc.c
index 81926c7..d2a8889 100644 (file)
@@ -48,6 +48,8 @@
 #include <linux/page_cgroup.h>
 #include <linux/debugobjects.h>
 #include <linux/kmemleak.h>
+#include <linux/memory.h>
+#include <trace/events/kmem.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -71,7 +73,6 @@ EXPORT_SYMBOL(node_states);
 
 unsigned long totalram_pages __read_mostly;
 unsigned long totalreserve_pages __read_mostly;
-unsigned long highest_memmap_pfn __read_mostly;
 int percpu_pagelist_fraction;
 gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
 
@@ -123,8 +124,8 @@ static char * const zone_names[MAX_NR_ZONES] = {
 
 int min_free_kbytes = 1024;
 
-unsigned long __meminitdata nr_kernel_pages;
-unsigned long __meminitdata nr_all_pages;
+static unsigned long __meminitdata nr_kernel_pages;
+static unsigned long __meminitdata nr_all_pages;
 static unsigned long __meminitdata dma_reserve;
 
 #ifdef CONFIG_ARCH_POPULATES_NODE_MAP
@@ -234,6 +235,12 @@ static void bad_page(struct page *page)
        static unsigned long nr_shown;
        static unsigned long nr_unshown;
 
+       /* Don't complain about poisoned pages */
+       if (PageHWPoison(page)) {
+               __ClearPageBuddy(page);
+               return;
+       }
+
        /*
         * Allow a burst of 60 reports, then keep quiet for that minute;
         * or allow a steady drip of one report per second.
@@ -480,7 +487,6 @@ static inline void __free_one_page(struct page *page,
        zone->free_area[order].nr_free++;
 }
 
-#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT
 /*
  * free_page_mlock() -- clean up attempts to free and mlocked() page.
  * Page should not be on lru, so no need to fix that up.
@@ -491,9 +497,6 @@ static inline void free_page_mlock(struct page *page)
        __dec_zone_page_state(page, NR_MLOCK);
        __count_vm_event(UNEVICTABLE_MLOCKFREED);
 }
-#else
-static void free_page_mlock(struct page *page) { }
-#endif
 
 static inline int free_pages_check(struct page *page)
 {
@@ -510,7 +513,7 @@ static inline int free_pages_check(struct page *page)
 }
 
 /*
- * Frees a list of pages. 
+ * Frees a number of pages from the PCP lists
  * Assumes all pages on list are in same zone, and of same order.
  * count is the number of pages to free.
  *
@@ -520,22 +523,42 @@ static inline int free_pages_check(struct page *page)
  * And clear the zone's pages_scanned counter, to hold off the "all pages are
  * pinned" detection logic.
  */
-static void free_pages_bulk(struct zone *zone, int count,
-                                       struct list_head *list, int order)
+static void free_pcppages_bulk(struct zone *zone, int count,
+                                       struct per_cpu_pages *pcp)
 {
+       int migratetype = 0;
+       int batch_free = 0;
+
        spin_lock(&zone->lock);
        zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
        zone->pages_scanned = 0;
 
-       __mod_zone_page_state(zone, NR_FREE_PAGES, count << order);
-       while (count--) {
+       __mod_zone_page_state(zone, NR_FREE_PAGES, count);
+       while (count) {
                struct page *page;
+               struct list_head *list;
 
-               VM_BUG_ON(list_empty(list));
-               page = list_entry(list->prev, struct page, lru);
-               /* have to delete it as __free_one_page list manipulates */
-               list_del(&page->lru);
-               __free_one_page(page, zone, order, page_private(page));
+               /*
+                * Remove pages from lists in a round-robin fashion. A
+                * batch_free count is maintained that is incremented when an
+                * empty list is encountered.  This is so more pages are freed
+                * off fuller lists instead of spinning excessively around empty
+                * lists
+                */
+               do {
+                       batch_free++;
+                       if (++migratetype == MIGRATE_PCPTYPES)
+                               migratetype = 0;
+                       list = &pcp->lists[migratetype];
+               } while (list_empty(list));
+
+               do {
+                       page = list_entry(list->prev, struct page, lru);
+                       /* must delete as __free_one_page list manipulates */
+                       list_del(&page->lru);
+                       __free_one_page(page, zone, 0, migratetype);
+                       trace_mm_page_pcpu_drain(page, 0, migratetype);
+               } while (--count && --batch_free && !list_empty(list));
        }
        spin_unlock(&zone->lock);
 }
@@ -557,7 +580,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
        unsigned long flags;
        int i;
        int bad = 0;
-       int wasMlocked = TestClearPageMlocked(page);
+       int wasMlocked = __TestClearPageMlocked(page);
 
        kmemcheck_free_shadow(page, order);
 
@@ -646,7 +669,7 @@ static inline void expand(struct zone *zone, struct page *page,
 /*
  * This page is about to be returned from the page allocator
  */
-static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
+static inline int check_new_page(struct page *page)
 {
        if (unlikely(page_mapcount(page) |
                (page->mapping != NULL)  |
@@ -655,6 +678,18 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
                bad_page(page);
                return 1;
        }
+       return 0;
+}
+
+static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
+{
+       int i;
+
+       for (i = 0; i < (1 << order); i++) {
+               struct page *p = page + i;
+               if (unlikely(check_new_page(p)))
+                       return 1;
+       }
 
        set_page_private(page, 0);
        set_page_refcounted(page);
@@ -783,6 +818,17 @@ static int move_freepages_block(struct zone *zone, struct page *page,
        return move_freepages(zone, start_page, end_page, migratetype);
 }
 
+static void change_pageblock_range(struct page *pageblock_page,
+                                       int start_order, int migratetype)
+{
+       int nr_pageblocks = 1 << (start_order - pageblock_order);
+
+       while (nr_pageblocks--) {
+               set_pageblock_migratetype(pageblock_page, migratetype);
+               pageblock_page += pageblock_nr_pages;
+       }
+}
+
 /* Remove an element from the buddy allocator from the fallback list */
 static inline struct page *
 __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
@@ -836,11 +882,16 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
                        list_del(&page->lru);
                        rmv_page_order(page);
 
-                       if (current_order == pageblock_order)
-                               set_pageblock_migratetype(page,
+                       /* Take ownership for orders >= pageblock_order */
+                       if (current_order >= pageblock_order)
+                               change_pageblock_range(page, current_order,
                                                        start_migratetype);
 
                        expand(zone, page, order, current_order, area, migratetype);
+
+                       trace_mm_page_alloc_extfrag(page, order, current_order,
+                               start_migratetype, migratetype);
+
                        return page;
                }
        }
@@ -874,6 +925,7 @@ retry_reserve:
                }
        }
 
+       trace_mm_page_alloc_zone_locked(page, order, migratetype);
        return page;
 }
 
@@ -934,7 +986,7 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp)
                to_drain = pcp->batch;
        else
                to_drain = pcp->count;
-       free_pages_bulk(zone, to_drain, &pcp->list, 0);
+       free_pcppages_bulk(zone, to_drain, pcp);
        pcp->count -= to_drain;
        local_irq_restore(flags);
 }
@@ -960,7 +1012,7 @@ static void drain_pages(unsigned int cpu)
 
                pcp = &pset->pcp;
                local_irq_save(flags);
-               free_pages_bulk(zone, pcp->count, &pcp->list, 0);
+               free_pcppages_bulk(zone, pcp->count, pcp);
                pcp->count = 0;
                local_irq_restore(flags);
        }
@@ -1026,7 +1078,8 @@ static void free_hot_cold_page(struct page *page, int cold)
        struct zone *zone = page_zone(page);
        struct per_cpu_pages *pcp;
        unsigned long flags;
-       int wasMlocked = TestClearPageMlocked(page);
+       int migratetype;
+       int wasMlocked = __TestClearPageMlocked(page);
 
        kmemcheck_free_shadow(page, 0);
 
@@ -1043,35 +1096,49 @@ static void free_hot_cold_page(struct page *page, int cold)
        kernel_map_pages(page, 1, 0);
 
        pcp = &zone_pcp(zone, get_cpu())->pcp;
-       set_page_private(page, get_pageblock_migratetype(page));
+       migratetype = get_pageblock_migratetype(page);
+       set_page_private(page, migratetype);
        local_irq_save(flags);
        if (unlikely(wasMlocked))
                free_page_mlock(page);
        __count_vm_event(PGFREE);
 
+       /*
+        * We only track unmovable, reclaimable and movable on pcp lists.
+        * Free ISOLATE pages back to the allocator because they are being
+        * offlined but treat RESERVE as movable pages so we can get those
+        * areas back if necessary. Otherwise, we may have to free
+        * excessively into the page allocator
+        */
+       if (migratetype >= MIGRATE_PCPTYPES) {
+               if (unlikely(migratetype == MIGRATE_ISOLATE)) {
+                       free_one_page(zone, page, 0, migratetype);
+                       goto out;
+               }
+               migratetype = MIGRATE_MOVABLE;
+       }
+
        if (cold)
-               list_add_tail(&page->lru, &pcp->list);
+               list_add_tail(&page->lru, &pcp->lists[migratetype]);
        else
-               list_add(&page->lru, &pcp->list);
+               list_add(&page->lru, &pcp->lists[migratetype]);
        pcp->count++;
        if (pcp->count >= pcp->high) {
-               free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
+               free_pcppages_bulk(zone, pcp->batch, pcp);
                pcp->count -= pcp->batch;
        }
+
+out:
        local_irq_restore(flags);
        put_cpu();
 }
 
 void free_hot_page(struct page *page)
 {
+       trace_mm_page_free_direct(page, 0);
        free_hot_cold_page(page, 0);
 }
        
-void free_cold_page(struct page *page)
-{
-       free_hot_cold_page(page, 1);
-}
-
 /*
  * split_page takes a non-compound higher-order page, and splits it into
  * n (1<<order) sub-pages: page[0..n]
@@ -1119,46 +1186,24 @@ again:
        cpu  = get_cpu();
        if (likely(order == 0)) {
                struct per_cpu_pages *pcp;
+               struct list_head *list;
 
                pcp = &zone_pcp(zone, cpu)->pcp;
+               list = &pcp->lists[migratetype];
                local_irq_save(flags);
-               if (!pcp->count) {
-                       pcp->count = rmqueue_bulk(zone, 0,
-                                       pcp->batch, &pcp->list,
-                                       migratetype, cold);
-                       if (unlikely(!pcp->count))
-                               goto failed;
-               }
-
-               /* Find a page of the appropriate migrate type */
-               if (cold) {
-                       list_for_each_entry_reverse(page, &pcp->list, lru)
-                               if (page_private(page) == migratetype)
-                                       break;
-               } else {
-                       list_for_each_entry(page, &pcp->list, lru)
-                               if (page_private(page) == migratetype)
-                                       break;
-               }
-
-               /* Allocate more to the pcp list if necessary */
-               if (unlikely(&page->lru == &pcp->list)) {
-                       int get_one_page = 0;
-
+               if (list_empty(list)) {
                        pcp->count += rmqueue_bulk(zone, 0,
-                                       pcp->batch, &pcp->list,
+                                       pcp->batch, list,
                                        migratetype, cold);
-                       list_for_each_entry(page, &pcp->list, lru) {
-                               if (get_pageblock_migratetype(page) !=
-                                           MIGRATE_ISOLATE) {
-                                       get_one_page = 1;
-                                       break;
-                               }
-                       }
-                       if (!get_one_page)
+                       if (unlikely(list_empty(list)))
                                goto failed;
                }
 
+               if (cold)
+                       page = list_entry(list->prev, struct page, lru);
+               else
+                       page = list_entry(list->next, struct page, lru);
+
                list_del(&page->lru);
                pcp->count--;
        } else {
@@ -1177,10 +1222,10 @@ again:
                }
                spin_lock_irqsave(&zone->lock, flags);
                page = __rmqueue(zone, order, migratetype);
-               __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
                spin_unlock(&zone->lock);
                if (!page)
                        goto failed;
+               __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
        }
 
        __count_zone_vm_events(PGALLOC, zone, 1 << order);
@@ -1610,12 +1655,22 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
        if (page)
                goto out;
 
-       /* The OOM killer will not help higher order allocs */
-       if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_NOFAIL))
-               goto out;
-
+       if (!(gfp_mask & __GFP_NOFAIL)) {
+               /* The OOM killer will not help higher order allocs */
+               if (order > PAGE_ALLOC_COSTLY_ORDER)
+                       goto out;
+               /*
+                * GFP_THISNODE contains __GFP_NORETRY and we never hit this.
+                * Sanity check for bare calls of __GFP_THISNODE, not real OOM.
+                * The caller should handle page allocation failure by itself if
+                * it specifies __GFP_THISNODE.
+                * Note: Hugepage uses it but will hit PAGE_ALLOC_COSTLY_ORDER.
+                */
+               if (gfp_mask & __GFP_THISNODE)
+                       goto out;
+       }
        /* Exhausted what can be done so it's blamo time */
-       out_of_memory(zonelist, gfp_mask, order);
+       out_of_memory(zonelist, gfp_mask, order, nodemask);
 
 out:
        clear_zonelist_oom(zonelist, gfp_mask);
@@ -1721,7 +1776,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
                 * See also cpuset_zone_allowed() comment in kernel/cpuset.c.
                 */
                alloc_flags &= ~ALLOC_CPUSET;
-       } else if (unlikely(rt_task(p)))
+       } else if (unlikely(rt_task(p)) && !in_interrupt())
                alloc_flags |= ALLOC_HARDER;
 
        if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) {
@@ -1769,9 +1824,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
        if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE)
                goto nopage;
 
+restart:
        wake_all_kswapd(order, zonelist, high_zoneidx);
 
-restart:
        /*
         * OK, we're below the kswapd watermark and have kicked background
         * reclaim. Now things get more complex, so set up alloc_flags according
@@ -1913,6 +1968,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
                                zonelist, high_zoneidx, nodemask,
                                preferred_zone, migratetype);
 
+       trace_mm_page_alloc(page, order, gfp_mask, migratetype);
        return page;
 }
 EXPORT_SYMBOL(__alloc_pages_nodemask);
@@ -1947,13 +2003,16 @@ void __pagevec_free(struct pagevec *pvec)
 {
        int i = pagevec_count(pvec);
 
-       while (--i >= 0)
+       while (--i >= 0) {
+               trace_mm_pagevec_free(pvec->pages[i], pvec->cold);
                free_hot_cold_page(pvec->pages[i], pvec->cold);
+       }
 }
 
 void __free_pages(struct page *page, unsigned int order)
 {
        if (put_page_testzero(page)) {
+               trace_mm_page_free_direct(page, order);
                if (order == 0)
                        free_hot_page(page);
                else
@@ -2131,7 +2190,7 @@ void show_free_areas(void)
        printk("active_anon:%lu inactive_anon:%lu isolated_anon:%lu\n"
                " active_file:%lu inactive_file:%lu isolated_file:%lu\n"
                " unevictable:%lu"
-               " dirty:%lu writeback:%lu unstable:%lu buffer:%lu\n"
+               " dirty:%lu writeback:%lu unstable:%lu\n"
                " free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
                " mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
                global_page_state(NR_ACTIVE_ANON),
@@ -2144,7 +2203,6 @@ void show_free_areas(void)
                global_page_state(NR_FILE_DIRTY),
                global_page_state(NR_WRITEBACK),
                global_page_state(NR_UNSTABLE_NFS),
-               nr_blockdev_pages(),
                global_page_state(NR_FREE_PAGES),
                global_page_state(NR_SLAB_RECLAIMABLE),
                global_page_state(NR_SLAB_UNRECLAIMABLE),
@@ -2339,18 +2397,19 @@ early_param("numa_zonelist_order", setup_numa_zonelist_order);
  * sysctl handler for numa_zonelist_order
  */
 int numa_zonelist_order_handler(ctl_table *table, int write,
-               struct file *file, void __user *buffer, size_t *length,
+               void __user *buffer, size_t *length,
                loff_t *ppos)
 {
        char saved_string[NUMA_ZONELIST_ORDER_LEN];
        int ret;
+       static DEFINE_MUTEX(zl_order_mutex);
 
+       mutex_lock(&zl_order_mutex);
        if (write)
-               strncpy(saved_string, (char*)table->data,
-                       NUMA_ZONELIST_ORDER_LEN);
-       ret = proc_dostring(table, write, file, buffer, length, ppos);
+               strcpy(saved_string, (char*)table->data);
+       ret = proc_dostring(table, write, buffer, length, ppos);
        if (ret)
-               return ret;
+               goto out;
        if (write) {
                int oldval = user_zonelist_order;
                if (__parse_numa_zonelist_order((char*)table->data)) {
@@ -2363,7 +2422,9 @@ int numa_zonelist_order_handler(ctl_table *table, int write,
                } else if (oldval != user_zonelist_order)
                        build_all_zonelists();
        }
-       return 0;
+out:
+       mutex_unlock(&zl_order_mutex);
+       return ret;
 }
 
 
@@ -2817,7 +2878,8 @@ static void setup_zone_migrate_reserve(struct zone *zone)
 {
        unsigned long start_pfn, pfn, end_pfn;
        struct page *page;
-       unsigned long reserve, block_migratetype;
+       unsigned long block_migratetype;
+       int reserve;
 
        /* Get the start pfn, end pfn and the number of blocks to reserve */
        start_pfn = zone->zone_start_pfn;
@@ -2825,6 +2887,15 @@ static void setup_zone_migrate_reserve(struct zone *zone)
        reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >>
                                                        pageblock_order;
 
+       /*
+        * Reserve blocks are generally in place to help high-order atomic
+        * allocations that are short-lived. A min_free_kbytes value that
+        * would result in more than 2 reserve blocks for atomic allocations
+        * is assumed to be in place to help anti-fragmentation for the
+        * future allocation of hugepages at runtime.
+        */
+       reserve = min(2, reserve);
+
        for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
                if (!pfn_valid(pfn))
                        continue;
@@ -2995,6 +3066,7 @@ static int zone_batchsize(struct zone *zone)
 static void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
 {
        struct per_cpu_pages *pcp;
+       int migratetype;
 
        memset(p, 0, sizeof(*p));
 
@@ -3002,7 +3074,8 @@ static void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
        pcp->count = 0;
        pcp->high = 6 * batch;
        pcp->batch = max(1UL, 1 * batch);
-       INIT_LIST_HEAD(&pcp->list);
+       for (migratetype = 0; migratetype < MIGRATE_PCPTYPES; migratetype++)
+               INIT_LIST_HEAD(&pcp->lists[migratetype]);
 }
 
 /*
@@ -3064,7 +3137,7 @@ static int __cpuinit process_zones(int cpu)
 
                if (percpu_pagelist_fraction)
                        setup_pagelist_highmark(zone_pcp(zone, cpu),
-                               (zone->present_pages / percpu_pagelist_fraction));
+                           (zone->present_pages / percpu_pagelist_fraction));
        }
 
        return 0;
@@ -3194,7 +3267,7 @@ static int __zone_pcp_update(void *data)
                pcp = &pset->pcp;
 
                local_irq_save(flags);
-               free_pages_bulk(zone, pcp->count, &pcp->list, 0);
+               free_pcppages_bulk(zone, pcp->count, pcp);
                setup_pageset(pset, batch);
                local_irq_restore(flags);
        }
@@ -3510,7 +3583,7 @@ static unsigned long __meminit zone_spanned_pages_in_node(int nid,
  * Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
  * then all holes in the requested range will be accounted for.
  */
-static unsigned long __meminit __absent_pages_in_range(int nid,
+unsigned long __meminit __absent_pages_in_range(int nid,
                                unsigned long range_start_pfn,
                                unsigned long range_end_pfn)
 {
@@ -3780,7 +3853,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
                zone_pcp_init(zone);
                for_each_lru(l) {
                        INIT_LIST_HEAD(&zone->lru[l].list);
-                       zone->lru[l].nr_saved_scan = 0;
+                       zone->reclaim_stat.nr_saved_scan[l] = 0;
                }
                zone->reclaim_stat.recent_rotated[0] = 0;
                zone->reclaim_stat.recent_rotated[1] = 0;
@@ -3925,7 +3998,7 @@ void __init add_active_range(unsigned int nid, unsigned long start_pfn,
                }
 
                /* Merge backward if suitable */
-               if (start_pfn < early_node_map[i].end_pfn &&
+               if (start_pfn < early_node_map[i].start_pfn &&
                                end_pfn >= early_node_map[i].start_pfn) {
                        early_node_map[i].start_pfn = start_pfn;
                        return;
@@ -4039,7 +4112,7 @@ static int __init cmp_node_active_region(const void *a, const void *b)
 }
 
 /* sort the node_map by start_pfn */
-static void __init sort_node_map(void)
+void __init sort_node_map(void)
 {
        sort(early_node_map, (size_t)nr_nodemap_entries,
                        sizeof(struct node_active_region),
@@ -4660,9 +4733,9 @@ module_init(init_per_zone_wmark_min)
  *     changes.
  */
 int min_free_kbytes_sysctl_handler(ctl_table *table, int write, 
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 {
-       proc_dointvec(table, write, file, buffer, length, ppos);
+       proc_dointvec(table, write, buffer, length, ppos);
        if (write)
                setup_per_zone_wmarks();
        return 0;
@@ -4670,12 +4743,12 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write,
 
 #ifdef CONFIG_NUMA
 int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write,
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 {
        struct zone *zone;
        int rc;
 
-       rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+       rc = proc_dointvec_minmax(table, write, buffer, length, ppos);
        if (rc)
                return rc;
 
@@ -4686,12 +4759,12 @@ int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write,
 }
 
 int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write,
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 {
        struct zone *zone;
        int rc;
 
-       rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+       rc = proc_dointvec_minmax(table, write, buffer, length, ppos);
        if (rc)
                return rc;
 
@@ -4712,9 +4785,9 @@ int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write,
  * if in function of the boot time zone sizes.
  */
 int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write,
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 {
-       proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+       proc_dointvec_minmax(table, write, buffer, length, ppos);
        setup_per_zone_lowmem_reserve();
        return 0;
 }
@@ -4726,13 +4799,13 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write,
  */
 
 int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
-       struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+       void __user *buffer, size_t *length, loff_t *ppos)
 {
        struct zone *zone;
        unsigned int cpu;
        int ret;
 
-       ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+       ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
        if (!write || (ret == -EINVAL))
                return ret;
        for_each_populated_zone(zone) {
@@ -4792,7 +4865,14 @@ void *__init alloc_large_system_hash(const char *tablename,
                        numentries <<= (PAGE_SHIFT - scale);
 
                /* Make sure we've got at least a 0-order allocation.. */
-               if (unlikely((numentries * bucketsize) < PAGE_SIZE))
+               if (unlikely(flags & HASH_SMALL)) {
+                       /* Makes no sense without HASH_EARLY */
+                       WARN_ON(!(flags & HASH_EARLY));
+                       if (!(numentries >> *_hash_shift)) {
+                               numentries = 1UL << *_hash_shift;
+                               BUG_ON(!numentries);
+                       }
+               } else if (unlikely((numentries * bucketsize) < PAGE_SIZE))
                        numentries = PAGE_SIZE / bucketsize;
        }
        numentries = roundup_pow_of_two(numentries);
@@ -4932,23 +5012,65 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
 int set_migratetype_isolate(struct page *page)
 {
        struct zone *zone;
-       unsigned long flags;
+       struct page *curr_page;
+       unsigned long flags, pfn, iter;
+       unsigned long immobile = 0;
+       struct memory_isolate_notify arg;
+       int notifier_ret;
        int ret = -EBUSY;
        int zone_idx;
 
        zone = page_zone(page);
        zone_idx = zone_idx(zone);
+
        spin_lock_irqsave(&zone->lock, flags);
+       if (get_pageblock_migratetype(page) == MIGRATE_MOVABLE ||
+           zone_idx == ZONE_MOVABLE) {
+               ret = 0;
+               goto out;
+       }
+
+       pfn = page_to_pfn(page);
+       arg.start_pfn = pfn;
+       arg.nr_pages = pageblock_nr_pages;
+       arg.pages_found = 0;
+
        /*
-        * In future, more migrate types will be able to be isolation target.
+        * It may be possible to isolate a pageblock even if the
+        * migratetype is not MIGRATE_MOVABLE. The memory isolation
+        * notifier chain is used by balloon drivers to return the
+        * number of pages in a range that are held by the balloon
+        * driver to shrink memory. If all the pages are accounted for
+        * by balloons, are free, or on the LRU, isolation can continue.
+        * Later, for example, when memory hotplug notifier runs, these
+        * pages reported as "can be isolated" should be isolated(freed)
+        * by the balloon driver through the memory notifier chain.
         */
-       if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE &&
-           zone_idx != ZONE_MOVABLE)
+       notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg);
+       notifier_ret = notifier_to_errno(notifier_ret);
+       if (notifier_ret || !arg.pages_found)
                goto out;
-       set_pageblock_migratetype(page, MIGRATE_ISOLATE);
-       move_freepages_block(zone, page, MIGRATE_ISOLATE);
-       ret = 0;
+
+       for (iter = pfn; iter < (pfn + pageblock_nr_pages); iter++) {
+               if (!pfn_valid_within(pfn))
+                       continue;
+
+               curr_page = pfn_to_page(iter);
+               if (!page_count(curr_page) || PageLRU(curr_page))
+                       continue;
+
+               immobile++;
+       }
+
+       if (arg.pages_found == immobile)
+               ret = 0;
+
 out:
+       if (!ret) {
+               set_pageblock_migratetype(page, MIGRATE_ISOLATE);
+               move_freepages_block(zone, page, MIGRATE_ISOLATE);
+       }
+
        spin_unlock_irqrestore(&zone->lock, flags);
        if (!ret)
                drain_all_pages();
@@ -5015,3 +5137,24 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
        spin_unlock_irqrestore(&zone->lock, flags);
 }
 #endif
+
+#ifdef CONFIG_MEMORY_FAILURE
+bool is_free_buddy_page(struct page *page)
+{
+       struct zone *zone = page_zone(page);
+       unsigned long pfn = page_to_pfn(page);
+       unsigned long flags;
+       int order;
+
+       spin_lock_irqsave(&zone->lock, flags);
+       for (order = 0; order < MAX_ORDER; order++) {
+               struct page *page_head = page - (pfn & ((1 << order) - 1));
+
+               if (PageBuddy(page_head) && page_order(page_head) >= order)
+                       break;
+       }
+       spin_unlock_irqrestore(&zone->lock, flags);
+
+       return order < MAX_ORDER;
+}
+#endif