mm, compaction: return failed migration target pages back to freelist
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / compaction.c
index 9185775..22338a1 100644 (file)
@@ -208,30 +208,15 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
        return true;
 }
 
-static inline bool compact_trylock_irqsave(spinlock_t *lock,
-                       unsigned long *flags, struct compact_control *cc)
-{
-       return compact_checklock_irqsave(lock, flags, false, cc);
-}
-
 /* Returns true if the page is within a block suitable for migration to */
 static bool suitable_migration_target(struct page *page)
 {
-       int migratetype = get_pageblock_migratetype(page);
-
-       /* Don't interfere with memory hot-remove or the min_free_kbytes blocks */
-       if (migratetype == MIGRATE_RESERVE)
-               return false;
-
-       if (is_migrate_isolate(migratetype))
-               return false;
-
-       /* If the page is a large free page, then allow migration */
+       /* If the page is a large free page, then disallow migration */
        if (PageBuddy(page) && page_order(page) >= pageblock_order)
-               return true;
+               return false;
 
        /* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
-       if (migrate_async_suitable(migratetype))
+       if (migrate_async_suitable(get_pageblock_migratetype(page)))
                return true;
 
        /* Otherwise skip the block */
@@ -253,6 +238,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
        struct page *cursor, *valid_page = NULL;
        unsigned long flags;
        bool locked = false;
+       bool checked_pageblock = false;
 
        cursor = pfn_to_page(blockpfn);
 
@@ -284,8 +270,16 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
                        break;
 
                /* Recheck this is a suitable migration target under lock */
-               if (!strict && !suitable_migration_target(page))
-                       break;
+               if (!strict && !checked_pageblock) {
+                       /*
+                        * We need to check suitability of pageblock only once
+                        * and this isolate_freepages_block() is called with
+                        * pageblock range, so just check once is sufficient.
+                        */
+                       checked_pageblock = true;
+                       if (!suitable_migration_target(page))
+                               break;
+               }
 
                /* Recheck this is a buddy page under lock */
                if (!PageBuddy(page))
@@ -460,12 +454,13 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
        unsigned long last_pageblock_nr = 0, pageblock_nr;
        unsigned long nr_scanned = 0, nr_isolated = 0;
        struct list_head *migratelist = &cc->migratepages;
-       isolate_mode_t mode = 0;
        struct lruvec *lruvec;
        unsigned long flags;
        bool locked = false;
        struct page *page = NULL, *valid_page = NULL;
        bool skipped_async_unsuitable = false;
+       const isolate_mode_t mode = (!cc->sync ? ISOLATE_ASYNC_MIGRATE : 0) |
+                                   (unevictable ? ISOLATE_UNEVICTABLE : 0);
 
        /*
         * Ensure that there are not too many pages isolated from the LRU
@@ -487,7 +482,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
        cond_resched();
        for (; low_pfn < end_pfn; low_pfn++) {
                /* give a chance to irqs before checking need_resched() */
-               if (locked && !((low_pfn+1) % SWAP_CLUSTER_MAX)) {
+               if (locked && !(low_pfn % SWAP_CLUSTER_MAX)) {
                        if (should_release_lock(&zone->lru_lock)) {
                                spin_unlock_irqrestore(&zone->lru_lock, flags);
                                locked = false;
@@ -526,8 +521,25 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
 
                /* If isolation recently failed, do not retry */
                pageblock_nr = low_pfn >> pageblock_order;
-               if (!isolation_suitable(cc, page))
-                       goto next_pageblock;
+               if (last_pageblock_nr != pageblock_nr) {
+                       int mt;
+
+                       last_pageblock_nr = pageblock_nr;
+                       if (!isolation_suitable(cc, page))
+                               goto next_pageblock;
+
+                       /*
+                        * For async migration, also only scan in MOVABLE
+                        * blocks. Async migration is optimistic to see if
+                        * the minimum amount of work satisfies the allocation
+                        */
+                       mt = get_pageblock_migratetype(page);
+                       if (!cc->sync && !migrate_async_suitable(mt)) {
+                               cc->finished_update_migrate = true;
+                               skipped_async_unsuitable = true;
+                               goto next_pageblock;
+                       }
+               }
 
                /*
                 * Skip if free. page_order cannot be used without zone->lock
@@ -537,18 +549,6 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                        continue;
 
                /*
-                * For async migration, also only scan in MOVABLE blocks. Async
-                * migration is optimistic to see if the minimum amount of work
-                * satisfies the allocation
-                */
-               if (!cc->sync && last_pageblock_nr != pageblock_nr &&
-                   !migrate_async_suitable(get_pageblock_migratetype(page))) {
-                       cc->finished_update_migrate = true;
-                       skipped_async_unsuitable = true;
-                       goto next_pageblock;
-               }
-
-               /*
                 * Check may be lockless but that's ok as we recheck later.
                 * It's possible to migrate LRU pages and balloon pages
                 * Skip any other type of page
@@ -557,11 +557,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                        if (unlikely(balloon_page_movable(page))) {
                                if (locked && balloon_page_isolate(page)) {
                                        /* Successfully isolated */
-                                       cc->finished_update_migrate = true;
-                                       list_add(&page->lru, migratelist);
-                                       cc->nr_migratepages++;
-                                       nr_isolated++;
-                                       goto check_compact_cluster;
+                                       goto isolate_success;
                                }
                        }
                        continue;
@@ -584,6 +580,15 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                        continue;
                }
 
+               /*
+                * Migration will fail if an anonymous page is pinned in memory,
+                * so avoid taking lru_lock and isolating it unnecessarily in an
+                * admittedly racy check.
+                */
+               if (!page_mapping(page) &&
+                   page_count(page) > page_mapcount(page))
+                       continue;
+
                /* Check if it is ok to still hold the lock */
                locked = compact_checklock_irqsave(&zone->lru_lock, &flags,
                                                                locked, cc);
@@ -598,12 +603,6 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                        continue;
                }
 
-               if (!cc->sync)
-                       mode |= ISOLATE_ASYNC_MIGRATE;
-
-               if (unevictable)
-                       mode |= ISOLATE_UNEVICTABLE;
-
                lruvec = mem_cgroup_page_lruvec(page, zone);
 
                /* Try isolate the page */
@@ -613,13 +612,14 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                VM_BUG_ON_PAGE(PageTransCompound(page), page);
 
                /* Successfully isolated */
-               cc->finished_update_migrate = true;
                del_page_from_lru_list(page, lruvec, page_lru(page));
+
+isolate_success:
+               cc->finished_update_migrate = true;
                list_add(&page->lru, migratelist);
                cc->nr_migratepages++;
                nr_isolated++;
 
-check_compact_cluster:
                /* Avoid isolating too much */
                if (cc->nr_migratepages == COMPACT_CLUSTER_MAX) {
                        ++low_pfn;
@@ -630,7 +630,6 @@ check_compact_cluster:
 
 next_pageblock:
                low_pfn = ALIGN(low_pfn + 1, pageblock_nr_pages) - 1;
-               last_pageblock_nr = pageblock_nr;
        }
 
        acct_isolated(zone, locked, cc);
@@ -666,34 +665,43 @@ static void isolate_freepages(struct zone *zone,
                                struct compact_control *cc)
 {
        struct page *page;
-       unsigned long high_pfn, low_pfn, pfn, z_end_pfn, end_pfn;
+       unsigned long block_start_pfn;  /* start of current pageblock */
+       unsigned long block_end_pfn;    /* end of current pageblock */
+       unsigned long low_pfn;       /* lowest pfn scanner is able to scan */
+       unsigned long next_free_pfn; /* start pfn for scaning at next round */
        int nr_freepages = cc->nr_freepages;
        struct list_head *freelist = &cc->freepages;
 
        /*
         * Initialise the free scanner. The starting point is where we last
-        * scanned from (or the end of the zone if starting). The low point
-        * is the end of the pageblock the migration scanner is using.
+        * successfully isolated from, zone-cached value, or the end of the
+        * zone when isolating for the first time. We need this aligned to
+        * the pageblock boundary, because we do
+        * block_start_pfn -= pageblock_nr_pages in the for loop.
+        * For ending point, take care when isolating in last pageblock of a
+        * a zone which ends in the middle of a pageblock.
+        * The low boundary is the end of the pageblock the migration scanner
+        * is using.
         */
-       pfn = cc->free_pfn;
+       block_start_pfn = cc->free_pfn & ~(pageblock_nr_pages-1);
+       block_end_pfn = min(block_start_pfn + pageblock_nr_pages,
+                                               zone_end_pfn(zone));
        low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages);
 
        /*
-        * Take care that if the migration scanner is at the end of the zone
-        * that the free scanner does not accidentally move to the next zone
-        * in the next isolation cycle.
+        * If no pages are isolated, the block_start_pfn < low_pfn check
+        * will kick in.
         */
-       high_pfn = min(low_pfn, pfn);
-
-       z_end_pfn = zone_end_pfn(zone);
+       next_free_pfn = 0;
 
        /*
         * Isolate free pages until enough are available to migrate the
         * pages on cc->migratepages. We stop searching if the migrate
         * and free page scanners meet or enough free pages are isolated.
         */
-       for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
-                                       pfn -= pageblock_nr_pages) {
+       for (; block_start_pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
+                               block_end_pfn = block_start_pfn,
+                               block_start_pfn -= pageblock_nr_pages) {
                unsigned long isolated;
 
                /*
@@ -703,7 +711,7 @@ static void isolate_freepages(struct zone *zone,
                 */
                cond_resched();
 
-               if (!pfn_valid(pfn))
+               if (!pfn_valid(block_start_pfn))
                        continue;
 
                /*
@@ -713,7 +721,7 @@ static void isolate_freepages(struct zone *zone,
                 * i.e. it's possible that all pages within a zones range of
                 * pages do not belong to a single zone.
                 */
-               page = pfn_to_page(pfn);
+               page = pfn_to_page(block_start_pfn);
                if (page_zone(page) != zone)
                        continue;
 
@@ -726,18 +734,8 @@ static void isolate_freepages(struct zone *zone,
                        continue;
 
                /* Found a block suitable for isolating free pages from */
-               isolated = 0;
-
-               /*
-                * As pfn may not start aligned, pfn+pageblock_nr_page
-                * may cross a MAX_ORDER_NR_PAGES boundary and miss
-                * a pfn_valid check. Ensure isolate_freepages_block()
-                * only scans within a pageblock
-                */
-               end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
-               end_pfn = min(end_pfn, z_end_pfn);
-               isolated = isolate_freepages_block(cc, pfn, end_pfn,
-                                                  freelist, false);
+               isolated = isolate_freepages_block(cc, block_start_pfn,
+                                       block_end_pfn, freelist, false);
                nr_freepages += isolated;
 
                /*
@@ -745,9 +743,9 @@ static void isolate_freepages(struct zone *zone,
                 * looking for free pages, the search will restart here as
                 * page migration may have returned some pages to the allocator
                 */
-               if (isolated) {
+               if (isolated && next_free_pfn == 0) {
                        cc->finished_update_free = true;
-                       high_pfn = max(high_pfn, pfn);
+                       next_free_pfn = block_start_pfn;
                }
        }
 
@@ -758,10 +756,10 @@ static void isolate_freepages(struct zone *zone,
         * If we crossed the migrate scanner, we want to keep it that way
         * so that compact_finished() may detect this
         */
-       if (pfn < low_pfn)
-               cc->free_pfn = max(pfn, zone->zone_start_pfn);
-       else
-               cc->free_pfn = high_pfn;
+       if (block_start_pfn < low_pfn)
+               next_free_pfn = cc->migrate_pfn;
+
+       cc->free_pfn = next_free_pfn;
        cc->nr_freepages = nr_freepages;
 }
 
@@ -792,23 +790,32 @@ static struct page *compaction_alloc(struct page *migratepage,
 }
 
 /*
- * We cannot control nr_migratepages and nr_freepages fully when migration is
- * running as migrate_pages() has no knowledge of compact_control. When
- * migration is complete, we count the number of pages on the lists by hand.
+ * This is a migrate-callback that "frees" freepages back to the isolated
+ * freelist.  All pages on the freelist are from the same zone, so there is no
+ * special handling needed for NUMA.
+ */
+static void compaction_free(struct page *page, unsigned long data)
+{
+       struct compact_control *cc = (struct compact_control *)data;
+
+       list_add(&page->lru, &cc->freepages);
+       cc->nr_freepages++;
+}
+
+/*
+ * We cannot control nr_migratepages fully when migration is running as
+ * migrate_pages() has no knowledge of of compact_control.  When migration is
+ * complete, we count the number of pages on the list by hand.
  */
 static void update_nr_listpages(struct compact_control *cc)
 {
        int nr_migratepages = 0;
-       int nr_freepages = 0;
        struct page *page;
 
        list_for_each_entry(page, &cc->migratepages, lru)
                nr_migratepages++;
-       list_for_each_entry(page, &cc->freepages, lru)
-               nr_freepages++;
 
        cc->nr_migratepages = nr_migratepages;
-       cc->nr_freepages = nr_freepages;
 }
 
 /* possible outcome of isolate_migratepages */
@@ -1019,7 +1026,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
 
                nr_migrate = cc->nr_migratepages;
                err = migrate_pages(&cc->migratepages, compaction_alloc,
-                               (unsigned long)cc,
+                               compaction_free, (unsigned long)cc,
                                cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC,
                                MR_COMPACTION);
                update_nr_listpages(cc);
@@ -1158,9 +1165,6 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
                        if (zone_watermark_ok(zone, cc->order,
                                                low_wmark_pages(zone), 0, 0))
                                compaction_defer_reset(zone, cc->order, false);
-                       /* Currently async compaction is never deferred. */
-                       else if (cc->sync)
-                               defer_compaction(zone, cc->order);
                }
 
                VM_BUG_ON(!list_empty(&cc->freepages));
@@ -1186,6 +1190,7 @@ static void compact_node(int nid)
        struct compact_control cc = {
                .order = -1,
                .sync = true,
+               .ignore_skip_hint = true,
        };
 
        __compact_pgdat(NODE_DATA(nid), &cc);