vfree: add debug might_sleep()
[sfrench/cifs-2.6.git] / mm / vmscan.c
index c5ef7240cbcbba05b4ef759b3c05d1ffdb163369..28c9ae5633b9899be8b4f2dd05bb9070238007e4 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/prefetch.h>
 #include <linux/printk.h>
 #include <linux/dax.h>
+#include <linux/psi.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -473,9 +474,18 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
        nr = atomic_long_xchg(&shrinker->nr_deferred[nid], 0);
 
        total_scan = nr;
-       delta = freeable >> priority;
-       delta *= 4;
-       do_div(delta, shrinker->seeks);
+       if (shrinker->seeks) {
+               delta = freeable >> priority;
+               delta *= 4;
+               do_div(delta, shrinker->seeks);
+       } else {
+               /*
+                * These objects don't require any IO to create. Trim
+                * them aggressively under memory pressure to keep
+                * them from causing refetches in the IO caches.
+                */
+               delta = freeable / 2;
+       }
 
        /*
         * Make sure we apply some minimal pressure on default priority
@@ -2145,6 +2155,7 @@ static void shrink_active_list(unsigned long nr_to_scan,
                }
 
                ClearPageActive(page);  /* we are de-activating */
+               SetPageWorkingset(page);
                list_add(&page->lru, &l_inactive);
        }
 
@@ -2456,9 +2467,11 @@ out:
                        /*
                         * Scan types proportional to swappiness and
                         * their relative recent reclaim efficiency.
+                        * Make sure we don't miss the last page
+                        * because of a round-off error.
                         */
-                       scan = div64_u64(scan * fraction[file],
-                                        denominator);
+                       scan = DIV64_U64_ROUND_UP(scan * fraction[file],
+                                                 denominator);
                        break;
                case SCAN_FILE:
                case SCAN_ANON:
@@ -3302,6 +3315,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
 {
        struct zonelist *zonelist;
        unsigned long nr_reclaimed;
+       unsigned long pflags;
        int nid;
        unsigned int noreclaim_flag;
        struct scan_control sc = {
@@ -3330,9 +3344,13 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
                                            sc.gfp_mask,
                                            sc.reclaim_idx);
 
+       psi_memstall_enter(&pflags);
        noreclaim_flag = memalloc_noreclaim_save();
+
        nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
+
        memalloc_noreclaim_restore(noreclaim_flag);
+       psi_memstall_leave(&pflags);
 
        trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
 
@@ -3497,6 +3515,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
        int i;
        unsigned long nr_soft_reclaimed;
        unsigned long nr_soft_scanned;
+       unsigned long pflags;
        struct zone *zone;
        struct scan_control sc = {
                .gfp_mask = GFP_KERNEL,
@@ -3507,6 +3526,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
                .may_swap = 1,
        };
 
+       psi_memstall_enter(&pflags);
        __fs_reclaim_acquire();
 
        count_vm_event(PAGEOUTRUN);
@@ -3608,6 +3628,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
 out:
        snapshot_refaults(NULL, pgdat);
        __fs_reclaim_release();
+       psi_memstall_leave(&pflags);
        /*
         * Return the order kswapd stopped reclaiming at as
         * prepare_kswapd_sleep() takes it into account. If another caller