tile: add <asm/word-at-a-time.h> and enable support functions
[cascardo/linux.git] / mm / compaction.c
index a18201a..018f08d 100644 (file)
@@ -391,28 +391,6 @@ static inline bool compact_should_abort(struct compact_control *cc)
        return false;
 }
 
-/* Returns true if the page is within a block suitable for migration to */
-static bool suitable_migration_target(struct page *page)
-{
-       /* If the page is a large free page, then disallow migration */
-       if (PageBuddy(page)) {
-               /*
-                * We are checking page_order without zone->lock taken. But
-                * the only small danger is that we skip a potentially suitable
-                * pageblock, so it's not worth to check order for valid range.
-                */
-               if (page_order_unsafe(page) >= pageblock_order)
-                       return false;
-       }
-
-       /* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
-       if (migrate_async_suitable(get_pageblock_migratetype(page)))
-               return true;
-
-       /* Otherwise skip the block */
-       return false;
-}
-
 /*
  * Isolate free pages onto a private freelist. If @strict is true, will abort
  * returning 0 on any invalid PFNs or non-free pages inside of the pageblock
@@ -896,6 +874,29 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
 
 #endif /* CONFIG_COMPACTION || CONFIG_CMA */
 #ifdef CONFIG_COMPACTION
+
+/* Returns true if the page is within a block suitable for migration to */
+static bool suitable_migration_target(struct page *page)
+{
+       /* If the page is a large free page, then disallow migration */
+       if (PageBuddy(page)) {
+               /*
+                * We are checking page_order without zone->lock taken. But
+                * the only small danger is that we skip a potentially suitable
+                * pageblock, so it's not worth to check order for valid range.
+                */
+               if (page_order_unsafe(page) >= pageblock_order)
+                       return false;
+       }
+
+       /* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
+       if (migrate_async_suitable(get_pageblock_migratetype(page)))
+               return true;
+
+       /* Otherwise skip the block */
+       return false;
+}
+
 /*
  * Based on information in the current compact_control, find blocks
  * suitable for isolating free pages from and then isolate them.
@@ -1046,6 +1047,12 @@ typedef enum {
        ISOLATE_SUCCESS,        /* Pages isolated, migrate */
 } isolate_migrate_t;
 
+/*
+ * Allow userspace to control policy on scanning the unevictable LRU for
+ * compactable pages.
+ */
+int sysctl_compact_unevictable_allowed __read_mostly = 1;
+
 /*
  * Isolate all pages that can be migrated from the first suitable block,
  * starting at the block pointed to by the migrate scanner pfn within
@@ -1057,6 +1064,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
        unsigned long low_pfn, end_pfn;
        struct page *page;
        const isolate_mode_t isolate_mode =
+               (sysctl_compact_unevictable_allowed ? ISOLATE_UNEVICTABLE : 0) |
                (cc->mode == MIGRATE_ASYNC ? ISOLATE_ASYNC_MIGRATE : 0);
 
        /*
@@ -1598,6 +1606,14 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
                INIT_LIST_HEAD(&cc->freepages);
                INIT_LIST_HEAD(&cc->migratepages);
 
+               /*
+                * When called via /proc/sys/vm/compact_memory
+                * this makes sure we compact the whole zone regardless of
+                * cached scanner positions.
+                */
+               if (cc->order == -1)
+                       __reset_isolation_suitable(zone);
+
                if (cc->order == -1 || !compaction_deferred(zone, cc->order))
                        compact_zone(zone, cc);