]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/vmscan.c
Merge tag 'mac80211-for-davem-2017-02-28' of git://git.kernel.org/pub/scm/linux/kerne...
[karo-tx-linux.git] / mm / vmscan.c
index 532a2a750952daffed4e4242d36a449eb9ba8837..70aa739c6b68beeca628dde8d947023ce4b18ca3 100644 (file)
@@ -87,6 +87,7 @@ struct scan_control {
        /* The highest zone to isolate pages for reclaim from */
        enum zone_type reclaim_idx;
 
+       /* Writepage batching in laptop mode; RECLAIM_WRITE */
        unsigned int may_writepage:1;
 
        /* Can mapped pages be reclaimed? */
@@ -234,22 +235,39 @@ bool pgdat_reclaimable(struct pglist_data *pgdat)
                pgdat_reclaimable_pages(pgdat) * 6;
 }
 
-unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru)
+/**
+ * lruvec_lru_size -  Returns the number of pages on the given LRU list.
+ * @lruvec: lru vector
+ * @lru: lru to use
+ * @zone_idx: zones to consider (use MAX_NR_ZONES for the whole LRU list)
+ */
+unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx)
 {
+       unsigned long lru_size;
+       int zid;
+
        if (!mem_cgroup_disabled())
-               return mem_cgroup_get_lru_size(lruvec, lru);
+               lru_size = mem_cgroup_get_lru_size(lruvec, lru);
+       else
+               lru_size = node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
 
-       return node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
-}
+       for (zid = zone_idx + 1; zid < MAX_NR_ZONES; zid++) {
+               struct zone *zone = &lruvec_pgdat(lruvec)->node_zones[zid];
+               unsigned long size;
 
-unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, enum lru_list lru,
-                                  int zone_idx)
-{
-       if (!mem_cgroup_disabled())
-               return mem_cgroup_get_zone_lru_size(lruvec, lru, zone_idx);
+               if (!managed_zone(zone))
+                       continue;
+
+               if (!mem_cgroup_disabled())
+                       size = mem_cgroup_get_zone_lru_size(lruvec, lru, zid);
+               else
+                       size = zone_page_state(&lruvec_pgdat(lruvec)->node_zones[zid],
+                                      NR_ZONE_LRU_BASE + lru);
+               lru_size -= min(size, lru_size);
+       }
+
+       return lru_size;
 
-       return zone_page_state(&lruvec_pgdat(lruvec)->node_zones[zone_idx],
-                              NR_ZONE_LRU_BASE + lru);
 }
 
 /*
@@ -912,6 +930,17 @@ static void page_check_dirty_writeback(struct page *page,
                mapping->a_ops->is_dirty_writeback(page, dirty, writeback);
 }
 
+struct reclaim_stat {
+       unsigned nr_dirty;
+       unsigned nr_unqueued_dirty;
+       unsigned nr_congested;
+       unsigned nr_writeback;
+       unsigned nr_immediate;
+       unsigned nr_activate;
+       unsigned nr_ref_keep;
+       unsigned nr_unmap_fail;
+};
+
 /*
  * shrink_page_list() returns the number of reclaimed pages
  */
@@ -919,22 +948,20 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                                      struct pglist_data *pgdat,
                                      struct scan_control *sc,
                                      enum ttu_flags ttu_flags,
-                                     unsigned long *ret_nr_dirty,
-                                     unsigned long *ret_nr_unqueued_dirty,
-                                     unsigned long *ret_nr_congested,
-                                     unsigned long *ret_nr_writeback,
-                                     unsigned long *ret_nr_immediate,
+                                     struct reclaim_stat *stat,
                                      bool force_reclaim)
 {
        LIST_HEAD(ret_pages);
        LIST_HEAD(free_pages);
        int pgactivate = 0;
-       unsigned long nr_unqueued_dirty = 0;
-       unsigned long nr_dirty = 0;
-       unsigned long nr_congested = 0;
-       unsigned long nr_reclaimed = 0;
-       unsigned long nr_writeback = 0;
-       unsigned long nr_immediate = 0;
+       unsigned nr_unqueued_dirty = 0;
+       unsigned nr_dirty = 0;
+       unsigned nr_congested = 0;
+       unsigned nr_reclaimed = 0;
+       unsigned nr_writeback = 0;
+       unsigned nr_immediate = 0;
+       unsigned nr_ref_keep = 0;
+       unsigned nr_unmap_fail = 0;
 
        cond_resched();
 
@@ -1029,6 +1056,15 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                 *    throttling so we could easily OOM just because too many
                 *    pages are in writeback and there is nothing else to
                 *    reclaim. Wait for the writeback to complete.
+                *
+                * In cases 1) and 2) we activate the pages to get them out of
+                * the way while we continue scanning for clean pages on the
+                * inactive list and refilling from the active list. The
+                * observation here is that waiting for disk writes is more
+                * expensive than potentially causing reloads down the line.
+                * Since they're marked for immediate reclaim, they won't put
+                * memory pressure on the cache working set any longer than it
+                * takes to write them to disk.
                 */
                if (PageWriteback(page)) {
                        /* Case 1 above */
@@ -1036,7 +1072,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                            PageReclaim(page) &&
                            test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {
                                nr_immediate++;
-                               goto keep_locked;
+                               goto activate_locked;
 
                        /* Case 2 above */
                        } else if (sane_reclaim(sc) ||
@@ -1054,7 +1090,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                                 */
                                SetPageReclaim(page);
                                nr_writeback++;
-                               goto keep_locked;
+                               goto activate_locked;
 
                        /* Case 3 above */
                        } else {
@@ -1073,6 +1109,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                case PAGEREF_ACTIVATE:
                        goto activate_locked;
                case PAGEREF_KEEP:
+                       nr_ref_keep++;
                        goto keep_locked;
                case PAGEREF_RECLAIM:
                case PAGEREF_RECLAIM_CLEAN:
@@ -1110,6 +1147,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                                (ttu_flags | TTU_BATCH_FLUSH | TTU_LZFREE) :
                                (ttu_flags | TTU_BATCH_FLUSH))) {
                        case SWAP_FAIL:
+                               nr_unmap_fail++;
                                goto activate_locked;
                        case SWAP_AGAIN:
                                goto keep_locked;
@@ -1124,13 +1162,18 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 
                if (PageDirty(page)) {
                        /*
-                        * Only kswapd can writeback filesystem pages to
-                        * avoid risk of stack overflow but only writeback
-                        * if many dirty pages have been encountered.
+                        * Only kswapd can writeback filesystem pages
+                        * to avoid risk of stack overflow. But avoid
+                        * injecting inefficient single-page IO into
+                        * flusher writeback as much as possible: only
+                        * write pages when we've encountered many
+                        * dirty pages, and when we've already scanned
+                        * the rest of the LRU for clean pages and see
+                        * the same dirty pages again (PageReclaim).
                         */
                        if (page_is_file_cache(page) &&
-                                       (!current_is_kswapd() ||
-                                        !test_bit(PGDAT_DIRTY, &pgdat->flags))) {
+                           (!current_is_kswapd() || !PageReclaim(page) ||
+                            !test_bit(PGDAT_DIRTY, &pgdat->flags))) {
                                /*
                                 * Immediately reclaim when written back.
                                 * Similar in principal to deactivate_page()
@@ -1140,7 +1183,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                                inc_node_page_state(page, NR_VMSCAN_IMMEDIATE);
                                SetPageReclaim(page);
 
-                               goto keep_locked;
+                               goto activate_locked;
                        }
 
                        if (references == PAGEREF_RECLAIM_CLEAN)
@@ -1276,11 +1319,16 @@ keep:
        list_splice(&ret_pages, page_list);
        count_vm_events(PGACTIVATE, pgactivate);
 
-       *ret_nr_dirty += nr_dirty;
-       *ret_nr_congested += nr_congested;
-       *ret_nr_unqueued_dirty += nr_unqueued_dirty;
-       *ret_nr_writeback += nr_writeback;
-       *ret_nr_immediate += nr_immediate;
+       if (stat) {
+               stat->nr_dirty = nr_dirty;
+               stat->nr_congested = nr_congested;
+               stat->nr_unqueued_dirty = nr_unqueued_dirty;
+               stat->nr_writeback = nr_writeback;
+               stat->nr_immediate = nr_immediate;
+               stat->nr_activate = pgactivate;
+               stat->nr_ref_keep = nr_ref_keep;
+               stat->nr_unmap_fail = nr_unmap_fail;
+       }
        return nr_reclaimed;
 }
 
@@ -1292,7 +1340,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
                .priority = DEF_PRIORITY,
                .may_unmap = 1,
        };
-       unsigned long ret, dummy1, dummy2, dummy3, dummy4, dummy5;
+       unsigned long ret;
        struct page *page, *next;
        LIST_HEAD(clean_pages);
 
@@ -1305,8 +1353,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
        }
 
        ret = shrink_page_list(&clean_pages, zone->zone_pgdat, &sc,
-                       TTU_UNMAP|TTU_IGNORE_ACCESS,
-                       &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, true);
+                       TTU_UNMAP|TTU_IGNORE_ACCESS, NULL, true);
        list_splice(&clean_pages, page_list);
        mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE, -ret);
        return ret;
@@ -1341,13 +1388,10 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode)
         * wants to isolate pages it will be able to operate on without
         * blocking - clean pages for the most part.
         *
-        * ISOLATE_CLEAN means that only clean pages should be isolated. This
-        * is used by reclaim when it is cannot write to backing storage
-        *
         * ISOLATE_ASYNC_MIGRATE is used to indicate that it only wants to pages
         * that it is possible to migrate without blocking
         */
-       if (mode & (ISOLATE_CLEAN|ISOLATE_ASYNC_MIGRATE)) {
+       if (mode & ISOLATE_ASYNC_MIGRATE) {
                /* All the caller can do on PageWriteback is block */
                if (PageWriteback(page))
                        return ret;
@@ -1355,10 +1399,6 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode)
                if (PageDirty(page)) {
                        struct address_space *mapping;
 
-                       /* ISOLATE_CLEAN means only clean pages */
-                       if (mode & ISOLATE_CLEAN)
-                               return ret;
-
                        /*
                         * Only pages without mappings or that have a
                         * ->migratepage callback are possible to migrate
@@ -1437,6 +1477,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
        unsigned long nr_taken = 0;
        unsigned long nr_zone_taken[MAX_NR_ZONES] = { 0 };
        unsigned long nr_skipped[MAX_NR_ZONES] = { 0, };
+       unsigned long skipped = 0, total_skipped = 0;
        unsigned long scan, nr_pages;
        LIST_HEAD(pages_skipped);
 
@@ -1488,14 +1529,13 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
         */
        if (!list_empty(&pages_skipped)) {
                int zid;
-               unsigned long total_skipped = 0;
 
                for (zid = 0; zid < MAX_NR_ZONES; zid++) {
                        if (!nr_skipped[zid])
                                continue;
 
                        __count_zid_vm_events(PGSCAN_SKIP, zid, nr_skipped[zid]);
-                       total_skipped += nr_skipped[zid];
+                       skipped += nr_skipped[zid];
                }
 
                /*
@@ -1503,13 +1543,13 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
                 * close to unreclaimable. If the LRU list is empty, account
                 * skipped pages as a full scan.
                 */
-               scan += list_empty(src) ? total_skipped : total_skipped >> 2;
+               total_skipped = list_empty(src) ? skipped : skipped >> 2;
 
                list_splice(&pages_skipped, src);
        }
-       *nr_scanned = scan;
-       trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan, scan,
-                                   nr_taken, mode, is_file_lru(lru));
+       *nr_scanned = scan + total_skipped;
+       trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan,
+                                   scan, skipped, nr_taken, mode, lru);
        update_lru_sizes(lruvec, lru, nr_zone_taken);
        return nr_taken;
 }
@@ -1669,30 +1709,6 @@ static int current_may_throttle(void)
                bdi_write_congested(current->backing_dev_info);
 }
 
-static bool inactive_reclaimable_pages(struct lruvec *lruvec,
-                               struct scan_control *sc, enum lru_list lru)
-{
-       int zid;
-       struct zone *zone;
-       int file = is_file_lru(lru);
-       struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-
-       if (!global_reclaim(sc))
-               return true;
-
-       for (zid = sc->reclaim_idx; zid >= 0; zid--) {
-               zone = &pgdat->node_zones[zid];
-               if (!managed_zone(zone))
-                       continue;
-
-               if (zone_page_state_snapshot(zone, NR_ZONE_LRU_BASE +
-                               LRU_FILE * file) >= SWAP_CLUSTER_MAX)
-                       return true;
-       }
-
-       return false;
-}
-
 /*
  * shrink_inactive_list() is a helper for shrink_node().  It returns the number
  * of reclaimed pages
@@ -1705,19 +1721,12 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
        unsigned long nr_scanned;
        unsigned long nr_reclaimed = 0;
        unsigned long nr_taken;
-       unsigned long nr_dirty = 0;
-       unsigned long nr_congested = 0;
-       unsigned long nr_unqueued_dirty = 0;
-       unsigned long nr_writeback = 0;
-       unsigned long nr_immediate = 0;
+       struct reclaim_stat stat = {};
        isolate_mode_t isolate_mode = 0;
        int file = is_file_lru(lru);
        struct pglist_data *pgdat = lruvec_pgdat(lruvec);
        struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat;
 
-       if (!inactive_reclaimable_pages(lruvec, sc, lru))
-               return 0;
-
        while (unlikely(too_many_isolated(pgdat, file, sc))) {
                congestion_wait(BLK_RW_ASYNC, HZ/10);
 
@@ -1730,8 +1739,6 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 
        if (!sc->may_unmap)
                isolate_mode |= ISOLATE_UNMAPPED;
-       if (!sc->may_writepage)
-               isolate_mode |= ISOLATE_CLEAN;
 
        spin_lock_irq(&pgdat->lru_lock);
 
@@ -1754,9 +1761,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
                return 0;
 
        nr_reclaimed = shrink_page_list(&page_list, pgdat, sc, TTU_UNMAP,
-                               &nr_dirty, &nr_unqueued_dirty, &nr_congested,
-                               &nr_writeback, &nr_immediate,
-                               false);
+                               &stat, false);
 
        spin_lock_irq(&pgdat->lru_lock);
 
@@ -1790,7 +1795,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
         * of pages under pages flagged for immediate reclaim and stall if any
         * are encountered in the nr_immediate check below.
         */
-       if (nr_writeback && nr_writeback == nr_taken)
+       if (stat.nr_writeback && stat.nr_writeback == nr_taken)
                set_bit(PGDAT_WRITEBACK, &pgdat->flags);
 
        /*
@@ -1802,17 +1807,25 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
                 * Tag a zone as congested if all the dirty pages scanned were
                 * backed by a congested BDI and wait_iff_congested will stall.
                 */
-               if (nr_dirty && nr_dirty == nr_congested)
+               if (stat.nr_dirty && stat.nr_dirty == stat.nr_congested)
                        set_bit(PGDAT_CONGESTED, &pgdat->flags);
 
                /*
                 * If dirty pages are scanned that are not queued for IO, it
-                * implies that flushers are not keeping up. In this case, flag
-                * the pgdat PGDAT_DIRTY and kswapd will start writing pages from
-                * reclaim context.
+                * implies that flushers are not doing their job. This can
+                * happen when memory pressure pushes dirty pages to the end of
+                * the LRU before the dirty limits are breached and the dirty
+                * data has expired. It can also happen when the proportion of
+                * dirty pages grows not through writes but through memory
+                * pressure reclaiming all the clean cache. And in some cases,
+                * the flushers simply cannot keep up with the allocation
+                * rate. Nudge the flusher threads in case they are asleep, but
+                * also allow kswapd to start writing pages during reclaim.
                 */
-               if (nr_unqueued_dirty == nr_taken)
+               if (stat.nr_unqueued_dirty == nr_taken) {
+                       wakeup_flusher_threads(0, WB_REASON_VMSCAN);
                        set_bit(PGDAT_DIRTY, &pgdat->flags);
+               }
 
                /*
                 * If kswapd scans pages marked marked for immediate
@@ -1820,7 +1833,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
                 * that pages are cycling through the LRU faster than
                 * they are written so also forcibly stall.
                 */
-               if (nr_immediate && current_may_throttle())
+               if (stat.nr_immediate && current_may_throttle())
                        congestion_wait(BLK_RW_ASYNC, HZ/10);
        }
 
@@ -1835,6 +1848,10 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 
        trace_mm_vmscan_lru_shrink_inactive(pgdat->node_id,
                        nr_scanned, nr_reclaimed,
+                       stat.nr_dirty,  stat.nr_writeback,
+                       stat.nr_congested, stat.nr_immediate,
+                       stat.nr_activate, stat.nr_ref_keep,
+                       stat.nr_unmap_fail,
                        sc->priority, file);
        return nr_reclaimed;
 }
@@ -1855,17 +1872,19 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
  *
  * The downside is that we have to touch page->_refcount against each page.
  * But we had to alter page->flags anyway.
+ *
+ * Returns the number of pages moved to the given lru.
  */
 
-static void move_active_pages_to_lru(struct lruvec *lruvec,
+static unsigned move_active_pages_to_lru(struct lruvec *lruvec,
                                     struct list_head *list,
                                     struct list_head *pages_to_free,
                                     enum lru_list lru)
 {
        struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-       unsigned long pgmoved = 0;
        struct page *page;
        int nr_pages;
+       int nr_moved = 0;
 
        while (!list_empty(list)) {
                page = lru_to_page(list);
@@ -1877,7 +1896,6 @@ static void move_active_pages_to_lru(struct lruvec *lruvec,
                nr_pages = hpage_nr_pages(page);
                update_lru_size(lruvec, lru, page_zonenum(page), nr_pages);
                list_move(&page->lru, &lruvec->lists[lru]);
-               pgmoved += nr_pages;
 
                if (put_page_testzero(page)) {
                        __ClearPageLRU(page);
@@ -1891,11 +1909,15 @@ static void move_active_pages_to_lru(struct lruvec *lruvec,
                                spin_lock_irq(&pgdat->lru_lock);
                        } else
                                list_add(&page->lru, pages_to_free);
+               } else {
+                       nr_moved += nr_pages;
                }
        }
 
        if (!is_active_lru(lru))
-               __count_vm_events(PGDEACTIVATE, pgmoved);
+               __count_vm_events(PGDEACTIVATE, nr_moved);
+
+       return nr_moved;
 }
 
 static void shrink_active_list(unsigned long nr_to_scan,
@@ -1911,7 +1933,8 @@ static void shrink_active_list(unsigned long nr_to_scan,
        LIST_HEAD(l_inactive);
        struct page *page;
        struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat;
-       unsigned long nr_rotated = 0;
+       unsigned nr_deactivate, nr_activate;
+       unsigned nr_rotated = 0;
        isolate_mode_t isolate_mode = 0;
        int file = is_file_lru(lru);
        struct pglist_data *pgdat = lruvec_pgdat(lruvec);
@@ -1920,8 +1943,6 @@ static void shrink_active_list(unsigned long nr_to_scan,
 
        if (!sc->may_unmap)
                isolate_mode |= ISOLATE_UNMAPPED;
-       if (!sc->may_writepage)
-               isolate_mode |= ISOLATE_CLEAN;
 
        spin_lock_irq(&pgdat->lru_lock);
 
@@ -1989,13 +2010,15 @@ static void shrink_active_list(unsigned long nr_to_scan,
         */
        reclaim_stat->recent_rotated[file] += nr_rotated;
 
-       move_active_pages_to_lru(lruvec, &l_active, &l_hold, lru);
-       move_active_pages_to_lru(lruvec, &l_inactive, &l_hold, lru - LRU_ACTIVE);
+       nr_activate = move_active_pages_to_lru(lruvec, &l_active, &l_hold, lru);
+       nr_deactivate = move_active_pages_to_lru(lruvec, &l_inactive, &l_hold, lru - LRU_ACTIVE);
        __mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, -nr_taken);
        spin_unlock_irq(&pgdat->lru_lock);
 
        mem_cgroup_uncharge_list(&l_hold);
        free_hot_cold_page_list(&l_hold, true);
+       trace_mm_vmscan_lru_shrink_active(pgdat->node_id, nr_taken, nr_activate,
+                       nr_deactivate, nr_rotated, sc->priority, file);
 }
 
 /*
@@ -2025,14 +2048,13 @@ static void shrink_active_list(unsigned long nr_to_scan,
  *   10TB     320        32GB
  */
 static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
-                                               struct scan_control *sc)
+                                               struct scan_control *sc, bool trace)
 {
        unsigned long inactive_ratio;
-       unsigned long inactive;
-       unsigned long active;
+       unsigned long inactive, active;
+       enum lru_list inactive_lru = file * LRU_FILE;
+       enum lru_list active_lru = file * LRU_FILE + LRU_ACTIVE;
        unsigned long gb;
-       struct pglist_data *pgdat = lruvec_pgdat(lruvec);
-       int zid;
 
        /*
         * If we don't have swap space, anonymous page deactivation
@@ -2041,27 +2063,8 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
        if (!file && !total_swap_pages)
                return false;
 
-       inactive = lruvec_lru_size(lruvec, file * LRU_FILE);
-       active = lruvec_lru_size(lruvec, file * LRU_FILE + LRU_ACTIVE);
-
-       /*
-        * For zone-constrained allocations, it is necessary to check if
-        * deactivations are required for lowmem to be reclaimed. This
-        * calculates the inactive/active pages available in eligible zones.
-        */
-       for (zid = sc->reclaim_idx + 1; zid < MAX_NR_ZONES; zid++) {
-               struct zone *zone = &pgdat->node_zones[zid];
-               unsigned long inactive_zone, active_zone;
-
-               if (!managed_zone(zone))
-                       continue;
-
-               inactive_zone = lruvec_zone_lru_size(lruvec, file * LRU_FILE, zid);
-               active_zone = lruvec_zone_lru_size(lruvec, (file * LRU_FILE) + LRU_ACTIVE, zid);
-
-               inactive -= min(inactive, inactive_zone);
-               active -= min(active, active_zone);
-       }
+       inactive = lruvec_lru_size(lruvec, inactive_lru, sc->reclaim_idx);
+       active = lruvec_lru_size(lruvec, active_lru, sc->reclaim_idx);
 
        gb = (inactive + active) >> (30 - PAGE_SHIFT);
        if (gb)
@@ -2069,6 +2072,13 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
        else
                inactive_ratio = 1;
 
+       if (trace)
+               trace_mm_vmscan_inactive_list_is_low(lruvec_pgdat(lruvec)->node_id,
+                               sc->reclaim_idx,
+                               lruvec_lru_size(lruvec, inactive_lru, MAX_NR_ZONES), inactive,
+                               lruvec_lru_size(lruvec, active_lru, MAX_NR_ZONES), active,
+                               inactive_ratio, file);
+
        return inactive * inactive_ratio < active;
 }
 
@@ -2076,7 +2086,7 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
                                 struct lruvec *lruvec, struct scan_control *sc)
 {
        if (is_active_lru(lru)) {
-               if (inactive_list_is_low(lruvec, is_file_lru(lru), sc))
+               if (inactive_list_is_low(lruvec, is_file_lru(lru), sc, true))
                        shrink_active_list(nr_to_scan, lruvec, sc, lru);
                return 0;
        }
@@ -2207,8 +2217,8 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
         * lruvec even if it has plenty of old anonymous pages unless the
         * system is under heavy pressure.
         */
-       if (!inactive_list_is_low(lruvec, true, sc) &&
-           lruvec_lru_size(lruvec, LRU_INACTIVE_FILE) >> sc->priority) {
+       if (!inactive_list_is_low(lruvec, true, sc, false) &&
+           lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, sc->reclaim_idx) >> sc->priority) {
                scan_balance = SCAN_FILE;
                goto out;
        }
@@ -2234,10 +2244,10 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
         * anon in [0], file in [1]
         */
 
-       anon  = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON) +
-               lruvec_lru_size(lruvec, LRU_INACTIVE_ANON);
-       file  = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE) +
-               lruvec_lru_size(lruvec, LRU_INACTIVE_FILE);
+       anon  = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) +
+               lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES);
+       file  = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
+               lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES);
 
        spin_lock_irq(&pgdat->lru_lock);
        if (unlikely(reclaim_stat->recent_scanned[0] > anon / 4)) {
@@ -2275,7 +2285,7 @@ out:
                        unsigned long size;
                        unsigned long scan;
 
-                       size = lruvec_lru_size(lruvec, lru);
+                       size = lruvec_lru_size(lruvec, lru, sc->reclaim_idx);
                        scan = size >> sc->priority;
 
                        if (!scan && pass && force_scan)
@@ -2432,7 +2442,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
         * Even if we did not try to evict anon pages at all, we want to
         * rebalance the anon lru active/inactive ratio.
         */
-       if (inactive_list_is_low(lruvec, false, sc))
+       if (inactive_list_is_low(lruvec, false, sc, true))
                shrink_active_list(SWAP_CLUSTER_MAX, lruvec,
                                   sc, LRU_ACTIVE_ANON);
 }
@@ -2761,8 +2771,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
                                          struct scan_control *sc)
 {
        int initial_priority = sc->priority;
-       unsigned long total_scanned = 0;
-       unsigned long writeback_threshold;
 retry:
        delayacct_freepages_start();
 
@@ -2775,7 +2783,6 @@ retry:
                sc->nr_scanned = 0;
                shrink_zones(zonelist, sc);
 
-               total_scanned += sc->nr_scanned;
                if (sc->nr_reclaimed >= sc->nr_to_reclaim)
                        break;
 
@@ -2788,20 +2795,6 @@ retry:
                 */
                if (sc->priority < DEF_PRIORITY - 2)
                        sc->may_writepage = 1;
-
-               /*
-                * Try to write back as many pages as we just scanned.  This
-                * tends to cause slow streaming writers to write data to the
-                * disk smoothly, at the dirtying rate, which is nice.   But
-                * that's undesirable in laptop mode, where we *want* lumpy
-                * writeout.  So in laptop mode, write out the whole world.
-                */
-               writeback_threshold = sc->nr_to_reclaim + sc->nr_to_reclaim / 2;
-               if (total_scanned > writeback_threshold) {
-                       wakeup_flusher_threads(laptop_mode ? 0 : total_scanned,
-                                               WB_REASON_TRY_TO_FREE_PAGES);
-                       sc->may_writepage = 1;
-               }
        } while (--sc->priority >= 0);
 
        delayacct_freepages_end();
@@ -3082,7 +3075,7 @@ static void age_active_anon(struct pglist_data *pgdat,
        do {
                struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, memcg);
 
-               if (inactive_list_is_low(lruvec, false, sc))
+               if (inactive_list_is_low(lruvec, false, sc, true))
                        shrink_active_list(SWAP_CLUSTER_MAX, lruvec,
                                           sc, LRU_ACTIVE_ANON);
 
@@ -3103,6 +3096,7 @@ static bool zone_balanced(struct zone *zone, int order, int classzone_idx)
         */
        clear_bit(PGDAT_CONGESTED, &zone->zone_pgdat->flags);
        clear_bit(PGDAT_DIRTY, &zone->zone_pgdat->flags);
+       clear_bit(PGDAT_WRITEBACK, &zone->zone_pgdat->flags);
 
        return true;
 }