mm, oom_reaper: do not attempt to reap a task more than twice
[deliverable/linux.git] / mm / compaction.c
index d85520647d1da4c063b4a4f8496eff499b16699f..64df5fe052db656dcfd38999abdf561942dfd4c5 100644 (file)
 #include <linux/backing-dev.h>
 #include <linux/sysctl.h>
 #include <linux/sysfs.h>
-#include <linux/balloon_compaction.h>
 #include <linux/page-isolation.h>
 #include <linux/kasan.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/page_owner.h>
 #include "internal.h"
 
 #ifdef CONFIG_COMPACTION
@@ -65,13 +65,27 @@ static unsigned long release_freepages(struct list_head *freelist)
 
 static void map_pages(struct list_head *list)
 {
-       struct page *page;
+       unsigned int i, order, nr_pages;
+       struct page *page, *next;
+       LIST_HEAD(tmp_list);
+
+       list_for_each_entry_safe(page, next, list, lru) {
+               list_del(&page->lru);
 
-       list_for_each_entry(page, list, lru) {
-               arch_alloc_page(page, 0);
-               kernel_map_pages(page, 1, 1);
-               kasan_alloc_pages(page, 0);
+               order = page_private(page);
+               nr_pages = 1 << order;
+
+               post_alloc_hook(page, order, __GFP_MOVABLE);
+               if (order)
+                       split_page(page, order);
+
+               for (i = 0; i < nr_pages; i++) {
+                       list_add(&page->lru, &tmp_list);
+                       page++;
+               }
        }
+
+       list_splice(&tmp_list, list);
 }
 
 static inline bool migrate_async_suitable(int migratetype)
@@ -406,12 +420,13 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
        unsigned long flags = 0;
        bool locked = false;
        unsigned long blockpfn = *start_pfn;
+       unsigned int order;
 
        cursor = pfn_to_page(blockpfn);
 
        /* Isolate free pages. */
        for (; blockpfn < end_pfn; blockpfn++, cursor++) {
-               int isolated, i;
+               int isolated;
                struct page *page = cursor;
 
                /*
@@ -477,17 +492,17 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
                                goto isolate_fail;
                }
 
-               /* Found a free page, break it into order-0 pages */
-               isolated = split_free_page(page);
+               /* Found a free page, will break it into order-0 pages */
+               order = page_order(page);
+               isolated = __isolate_free_page(page, order);
                if (!isolated)
                        break;
+               set_page_private(page, order);
 
                total_isolated += isolated;
                cc->nr_freepages += isolated;
-               for (i = 0; i < isolated; i++) {
-                       list_add(&page->lru, freelist);
-                       page++;
-               }
+               list_add_tail(&page->lru, freelist);
+
                if (!strict && cc->nr_migratepages <= cc->nr_freepages) {
                        blockpfn += isolated;
                        break;
@@ -606,7 +621,7 @@ isolate_freepages_range(struct compact_control *cc,
                 */
        }
 
-       /* split_free_page does not map the pages */
+       /* __isolate_free_page() does not map the pages */
        map_pages(&freelist);
 
        if (pfn < end_pfn) {
@@ -1103,7 +1118,7 @@ static void isolate_freepages(struct compact_control *cc)
                }
        }
 
-       /* split_free_page does not map the pages */
+       /* __isolate_free_page() does not map the pages */
        map_pages(freelist);
 
        /*
This page took 0.026813 seconds and 5 git commands to generate.