]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
mm: make drop_caches keep reclaiming on all nodes
authorJan Kara <jack@suse.cz>
Tue, 15 Nov 2022 12:32:55 +0000 (13:32 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 30 Nov 2022 23:58:55 +0000 (15:58 -0800)
Currently, drop_caches are reclaiming node-by-node, looping on each node
until reclaim could not make progress.  This can however leave quite some
slab entries (such as filesystem inodes) unreclaimed if objects say on
node 1 keep objects on node 0 pinned.  So move the "loop until no
progress" loop to the node-by-node iteration to retry reclaim also on
other nodes if reclaim on some nodes made progress.  This fixes problem
when drop_caches was not reclaiming lots of otherwise perfectly fine to
reclaim inodes.

Link: https://lkml.kernel.org/r/20221115123255.12559-1-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Reported-by: You Zhou <you.zhou@intel.com>
Reported-by: Pengfei Xu <pengfei.xu@intel.com>
Tested-by: Pengfei Xu <pengfei.xu@intel.com>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/vmscan.c

index d7c71be6417d3366e6ef4fce1cc2226e8beecb07..82f32c929b114e204857223f8771edb10072672b 100644 (file)
@@ -1021,31 +1021,34 @@ out:
        return freed;
 }
 
-static void drop_slab_node(int nid)
+static unsigned long drop_slab_node(int nid)
 {
-       unsigned long freed;
-       int shift = 0;
+       unsigned long freed = 0;
+       struct mem_cgroup *memcg = NULL;
 
+       memcg = mem_cgroup_iter(NULL, NULL, NULL);
        do {
-               struct mem_cgroup *memcg = NULL;
-
-               if (fatal_signal_pending(current))
-                       return;
+               freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
+       } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
 
-               freed = 0;
-               memcg = mem_cgroup_iter(NULL, NULL, NULL);
-               do {
-                       freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
-               } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
-       } while ((freed >> shift++) > 1);
+       return freed;
 }
 
 void drop_slab(void)
 {
        int nid;
+       int shift = 0;
+       unsigned long freed;
 
-       for_each_online_node(nid)
-               drop_slab_node(nid);
+       do {
+               freed = 0;
+               for_each_online_node(nid) {
+                       if (fatal_signal_pending(current))
+                               return;
+
+                       freed += drop_slab_node(nid);
+               }
+       } while ((freed >> shift++) > 1);
 }
 
 static int reclaimer_offset(void)