*
  * Isolate all pages that can be migrated from the range specified by
  * [low_pfn, end_pfn). The range is expected to be within same pageblock.
- * Returns zero if there is a fatal signal pending, otherwise PFN of the
- * first page that was not scanned (which may be both less, equal to or more
- * than end_pfn).
+ * Returns errno, like -EAGAIN or -EINTR in case e.g signal pending or congestion,
+ * or 0.
+ * cc->migrate_pfn will contain the next pfn to scan.
  *
  * The pages are isolated on cc->migratepages list (not required to be empty),
- * and cc->nr_migratepages is updated accordingly. The cc->migrate_pfn field
- * is neither read nor updated.
+ * and cc->nr_migratepages is updated accordingly.
  */
-static unsigned long
+static int
 isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
                        unsigned long end_pfn, isolate_mode_t isolate_mode)
 {
        bool skip_on_failure = false;
        unsigned long next_skip_pfn = 0;
        bool skip_updated = false;
+       int ret = 0;
+
+       cc->migrate_pfn = low_pfn;
 
        /*
         * Ensure that there are not too many pages isolated from the LRU
        while (unlikely(too_many_isolated(pgdat))) {
                /* stop isolation if there are still pages not migrated */
                if (cc->nr_migratepages)
-                       return 0;
+                       return -EAGAIN;
 
                /* async migration should just abort */
                if (cc->mode == MIGRATE_ASYNC)
-                       return 0;
+                       return -EAGAIN;
 
                congestion_wait(BLK_RW_ASYNC, HZ/10);
 
                if (fatal_signal_pending(current))
-                       return 0;
+                       return -EINTR;
        }
 
        cond_resched();
 
                        if (fatal_signal_pending(current)) {
                                cc->contended = true;
+                               ret = -EINTR;
 
-                               low_pfn = 0;
                                goto fatal_pending;
                        }
 
        if (nr_isolated)
                count_compact_events(COMPACTISOLATED, nr_isolated);
 
-       return low_pfn;
+       cc->migrate_pfn = low_pfn;
+
+       return ret;
 }
 
 /**
  * @start_pfn: The first PFN to start isolating.
  * @end_pfn:   The one-past-last PFN.
  *
- * Returns zero if isolation fails fatally due to e.g. pending signal.
- * Otherwise, function returns one-past-the-last PFN of isolated page
- * (which may be greater than end_pfn if end fell in a middle of a THP page).
+ * Returns -EAGAIN when contented, -EINTR in case of a signal pending or 0.
  */
-unsigned long
+int
 isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
                                                        unsigned long end_pfn)
 {
        unsigned long pfn, block_start_pfn, block_end_pfn;
+       int ret = 0;
 
        /* Scan block by block. First and last block may be incomplete */
        pfn = start_pfn;
                                        block_end_pfn, cc->zone))
                        continue;
 
-               pfn = isolate_migratepages_block(cc, pfn, block_end_pfn,
-                                                       ISOLATE_UNEVICTABLE);
+               ret = isolate_migratepages_block(cc, pfn, block_end_pfn,
+                                                ISOLATE_UNEVICTABLE);
 
-               if (!pfn)
+               if (ret)
                        break;
 
                if (cc->nr_migratepages >= COMPACT_CLUSTER_MAX)
                        break;
        }
 
-       return pfn;
+       return ret;
 }
 
 #endif /* CONFIG_COMPACTION || CONFIG_CMA */
         */
        for (; block_end_pfn <= cc->free_pfn;
                        fast_find_block = false,
-                       low_pfn = block_end_pfn,
+                       cc->migrate_pfn = low_pfn = block_end_pfn,
                        block_start_pfn = block_end_pfn,
                        block_end_pfn += pageblock_nr_pages) {
 
                }
 
                /* Perform the isolation */
-               low_pfn = isolate_migratepages_block(cc, low_pfn,
-                                               block_end_pfn, isolate_mode);
-
-               if (!low_pfn)
+               if (isolate_migratepages_block(cc, low_pfn, block_end_pfn,
+                                               isolate_mode))
                        return ISOLATE_ABORT;
 
                /*
                break;
        }
 
-       /* Record where migration scanner will be restarted. */
-       cc->migrate_pfn = low_pfn;
-
        return cc->nr_migratepages ? ISOLATE_SUCCESS : ISOLATE_NONE;
 }
 
 
        unsigned int nr_freepages;      /* Number of isolated free pages */
        unsigned int nr_migratepages;   /* Number of pages to migrate */
        unsigned long free_pfn;         /* isolate_freepages search base */
-       unsigned long migrate_pfn;      /* isolate_migratepages search base */
+       /*
+        * Acts as an in/out parameter to page isolation for migration.
+        * isolate_migratepages uses it as a search base.
+        * isolate_migratepages_block will update the value to the next pfn
+        * after the last isolated one.
+        */
+       unsigned long migrate_pfn;
        unsigned long fast_start_pfn;   /* a pfn to start linear scan from */
        struct zone *zone;
        unsigned long total_migrate_scanned;
 unsigned long
 isolate_freepages_range(struct compact_control *cc,
                        unsigned long start_pfn, unsigned long end_pfn);
-unsigned long
+int
 isolate_migratepages_range(struct compact_control *cc,
                           unsigned long low_pfn, unsigned long end_pfn);
 int find_suitable_fallback(struct free_area *area, unsigned int order,