Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[sfrench/cifs-2.6.git] / mm / vmscan.c
index 47d5ced51f2d44cddc559814b42caa0ea9bf5863..444749669187e189b98fcbbe0050413a9c84b20c 100644 (file)
@@ -220,22 +220,6 @@ unsigned long zone_reclaimable_pages(struct zone *zone)
        return nr;
 }
 
-unsigned long pgdat_reclaimable_pages(struct pglist_data *pgdat)
-{
-       unsigned long nr;
-
-       nr = node_page_state_snapshot(pgdat, NR_ACTIVE_FILE) +
-            node_page_state_snapshot(pgdat, NR_INACTIVE_FILE) +
-            node_page_state_snapshot(pgdat, NR_ISOLATED_FILE);
-
-       if (get_nr_swap_pages() > 0)
-               nr += node_page_state_snapshot(pgdat, NR_ACTIVE_ANON) +
-                     node_page_state_snapshot(pgdat, NR_INACTIVE_ANON) +
-                     node_page_state_snapshot(pgdat, NR_ISOLATED_ANON);
-
-       return nr;
-}
-
 /**
  * lruvec_lru_size -  Returns the number of pages on the given LRU list.
  * @lruvec: lru vector
@@ -310,9 +294,7 @@ EXPORT_SYMBOL(unregister_shrinker);
 #define SHRINK_BATCH 128
 
 static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
-                                   struct shrinker *shrinker,
-                                   unsigned long nr_scanned,
-                                   unsigned long nr_eligible)
+                                   struct shrinker *shrinker, int priority)
 {
        unsigned long freed = 0;
        unsigned long long delta;
@@ -337,9 +319,9 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
        nr = atomic_long_xchg(&shrinker->nr_deferred[nid], 0);
 
        total_scan = nr;
-       delta = (4 * nr_scanned) / shrinker->seeks;
-       delta *= freeable;
-       do_div(delta, nr_eligible + 1);
+       delta = freeable >> priority;
+       delta *= 4;
+       do_div(delta, shrinker->seeks);
        total_scan += delta;
        if (total_scan < 0) {
                pr_err("shrink_slab: %pF negative objects to delete nr=%ld\n",
@@ -373,8 +355,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
                total_scan = freeable * 2;
 
        trace_mm_shrink_slab_start(shrinker, shrinkctl, nr,
-                                  nr_scanned, nr_eligible,
-                                  freeable, delta, total_scan);
+                                  freeable, delta, total_scan, priority);
 
        /*
         * Normally, we should not scan less than batch_size objects in one
@@ -434,8 +415,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
  * @gfp_mask: allocation context
  * @nid: node whose slab caches to target
  * @memcg: memory cgroup whose slab caches to target
- * @nr_scanned: pressure numerator
- * @nr_eligible: pressure denominator
+ * @priority: the reclaim priority
  *
  * Call the shrink functions to age shrinkable caches.
  *
@@ -447,20 +427,14 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
  * objects from the memory cgroup specified. Otherwise, only unaware
  * shrinkers are called.
  *
- * @nr_scanned and @nr_eligible form a ratio that indicate how much of
- * the available objects should be scanned.  Page reclaim for example
- * passes the number of pages scanned and the number of pages on the
- * LRU lists that it considered on @nid, plus a bias in @nr_scanned
- * when it encountered mapped pages.  The ratio is further biased by
- * the ->seeks setting of the shrink function, which indicates the
- * cost to recreate an object relative to that of an LRU page.
+ * @priority is sc->priority, we take the number of objects and >> by priority
+ * in order to get the scan target.
  *
  * Returns the number of reclaimed slab objects.
  */
 static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
                                 struct mem_cgroup *memcg,
-                                unsigned long nr_scanned,
-                                unsigned long nr_eligible)
+                                int priority)
 {
        struct shrinker *shrinker;
        unsigned long freed = 0;
@@ -468,9 +442,6 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
        if (memcg && (!memcg_kmem_enabled() || !mem_cgroup_online(memcg)))
                return 0;
 
-       if (nr_scanned == 0)
-               nr_scanned = SWAP_CLUSTER_MAX;
-
        if (!down_read_trylock(&shrinker_rwsem)) {
                /*
                 * If we would return 0, our callers would understand that we
@@ -501,7 +472,16 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
                if (!(shrinker->flags & SHRINKER_NUMA_AWARE))
                        sc.nid = 0;
 
-               freed += do_shrink_slab(&sc, shrinker, nr_scanned, nr_eligible);
+               freed += do_shrink_slab(&sc, shrinker, priority);
+               /*
+                * Bail out if someone want to register a new shrinker to
+                * prevent the regsitration from being stalled for long periods
+                * by parallel ongoing shrinking.
+                */
+               if (rwsem_is_contended(&shrinker_rwsem)) {
+                       freed = freed ? : 1;
+                       break;
+               }
        }
 
        up_read(&shrinker_rwsem);
@@ -519,8 +499,7 @@ void drop_slab_node(int nid)
 
                freed = 0;
                do {
-                       freed += shrink_slab(GFP_KERNEL, nid, memcg,
-                                            1000, 1000);
+                       freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
                } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
        } while (freed > 10);
 }
@@ -1436,14 +1415,24 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode)
 
                if (PageDirty(page)) {
                        struct address_space *mapping;
+                       bool migrate_dirty;
 
                        /*
                         * Only pages without mappings or that have a
                         * ->migratepage callback are possible to migrate
-                        * without blocking
+                        * without blocking. However, we can be racing with
+                        * truncation so it's necessary to lock the page
+                        * to stabilise the mapping as truncation holds
+                        * the page lock until after the page is removed
+                        * from the page cache.
                         */
+                       if (!trylock_page(page))
+                               return ret;
+
                        mapping = page_mapping(page);
-                       if (mapping && !mapping->a_ops->migratepage)
+                       migrate_dirty = mapping && mapping->a_ops->migratepage;
+                       unlock_page(page);
+                       if (!migrate_dirty)
                                return ret;
                }
        }
@@ -1606,6 +1595,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
  * found will be decremented.
  *
  * Restrictions:
+ *
  * (1) Must be called with an elevated refcount on the page. This is a
  *     fundamentnal difference from isolate_lru_pages (which is called
  *     without a stable reference).
@@ -2615,14 +2605,12 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc)
 
                        reclaimed = sc->nr_reclaimed;
                        scanned = sc->nr_scanned;
-
                        shrink_node_memcg(pgdat, memcg, sc, &lru_pages);
                        node_lru_pages += lru_pages;
 
                        if (memcg)
                                shrink_slab(sc->gfp_mask, pgdat->node_id,
-                                           memcg, sc->nr_scanned - scanned,
-                                           lru_pages);
+                                           memcg, sc->priority);
 
                        /* Record the group's reclaim efficiency */
                        vmpressure(sc->gfp_mask, memcg, false,
@@ -2646,14 +2634,9 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc)
                        }
                } while ((memcg = mem_cgroup_iter(root, memcg, &reclaim)));
 
-               /*
-                * Shrink the slab caches in the same proportion that
-                * the eligible LRU pages were scanned.
-                */
                if (global_reclaim(sc))
                        shrink_slab(sc->gfp_mask, pgdat->node_id, NULL,
-                                   sc->nr_scanned - nr_scanned,
-                                   node_lru_pages);
+                                   sc->priority);
 
                if (reclaim_state) {
                        sc->nr_reclaimed += reclaim_state->reclaimed_slab;