]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - mm/vmscan.c
mm: only force scan in reclaim when none of the LRUs are big enough.
[mirror_ubuntu-zesty-kernel.git] / mm / vmscan.c
index 32c661d66a45498e270ba5e9019cda60a114cc27..7901cb749e17515787df579ad1336186a391852d 100644 (file)
@@ -1866,6 +1866,8 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
        bool force_scan = false;
        unsigned long ap, fp;
        enum lru_list lru;
+       bool some_scanned;
+       int pass;
 
        /*
         * If the zone or memcg is small, nr[l] can be 0.  This
@@ -1989,39 +1991,49 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
        fraction[1] = fp;
        denominator = ap + fp + 1;
 out:
-       for_each_evictable_lru(lru) {
-               int file = is_file_lru(lru);
-               unsigned long size;
-               unsigned long scan;
+       some_scanned = false;
+       /* Only use force_scan on second pass. */
+       for (pass = 0; !some_scanned && pass < 2; pass++) {
+               for_each_evictable_lru(lru) {
+                       int file = is_file_lru(lru);
+                       unsigned long size;
+                       unsigned long scan;
 
-               size = get_lru_size(lruvec, lru);
-               scan = size >> sc->priority;
+                       size = get_lru_size(lruvec, lru);
+                       scan = size >> sc->priority;
 
-               if (!scan && force_scan)
-                       scan = min(size, SWAP_CLUSTER_MAX);
+                       if (!scan && pass && force_scan)
+                               scan = min(size, SWAP_CLUSTER_MAX);
 
-               switch (scan_balance) {
-               case SCAN_EQUAL:
-                       /* Scan lists relative to size */
-                       break;
-               case SCAN_FRACT:
+                       switch (scan_balance) {
+                       case SCAN_EQUAL:
+                               /* Scan lists relative to size */
+                               break;
+                       case SCAN_FRACT:
+                               /*
+                                * Scan types proportional to swappiness and
+                                * their relative recent reclaim efficiency.
+                                */
+                               scan = div64_u64(scan * fraction[file],
+                                                       denominator);
+                               break;
+                       case SCAN_FILE:
+                       case SCAN_ANON:
+                               /* Scan one type exclusively */
+                               if ((scan_balance == SCAN_FILE) != file)
+                                       scan = 0;
+                               break;
+                       default:
+                               /* Look ma, no brain */
+                               BUG();
+                       }
+                       nr[lru] = scan;
                        /*
-                        * Scan types proportional to swappiness and
-                        * their relative recent reclaim efficiency.
+                        * Skip the second pass and don't force_scan,
+                        * if we found something to scan.
                         */
-                       scan = div64_u64(scan * fraction[file], denominator);
-                       break;
-               case SCAN_FILE:
-               case SCAN_ANON:
-                       /* Scan one type exclusively */
-                       if ((scan_balance == SCAN_FILE) != file)
-                               scan = 0;
-                       break;
-               default:
-                       /* Look ma, no brain */
-                       BUG();
+                       some_scanned |= !!scan;
                }
-               nr[lru] = scan;
        }
 }