Commit e83b39d6 authored by Jan Kara's avatar Jan Kara Committed by Andrew Morton

mm: make drop_caches keep reclaiming on all nodes

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.czSigned-off-by: default avatarJan Kara <jack@suse.cz>
Reported-by: default avatarYou Zhou <you.zhou@intel.com>
Reported-by: default avatarPengfei Xu <pengfei.xu@intel.com>
Tested-by: default avatarPengfei Xu <pengfei.xu@intel.com>
Reviewed-by: default avatarShakeel Butt <shakeelb@google.com>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent d09e8ca6
...@@ -1021,31 +1021,34 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, ...@@ -1021,31 +1021,34 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
return freed; return freed;
} }
static void drop_slab_node(int nid) static unsigned long drop_slab_node(int nid)
{ {
unsigned long freed; unsigned long freed = 0;
int shift = 0; struct mem_cgroup *memcg = NULL;
memcg = mem_cgroup_iter(NULL, NULL, NULL);
do { do {
struct mem_cgroup *memcg = NULL; freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
if (fatal_signal_pending(current))
return;
freed = 0; return freed;
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);
} }
void drop_slab(void) void drop_slab(void)
{ {
int nid; int nid;
int shift = 0;
unsigned long freed;
for_each_online_node(nid) do {
drop_slab_node(nid); 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) static int reclaimer_offset(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment