From: Ye Bin This patch is prepare for support drop_caches for specify file system. Signed-off-by: Ye Bin --- include/linux/mm.h | 1 + mm/internal.h | 3 +++ mm/shrinker.c | 4 ++-- mm/vmscan.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 5be3d8a8f806..5bab9472a758 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4470,6 +4470,7 @@ static inline int in_gate_area(struct mm_struct *mm, unsigned long addr) bool process_shares_mm(const struct task_struct *p, const struct mm_struct *mm); void drop_slab(void); +void drop_sb_dentry_inode(struct super_block *sb); #ifndef CONFIG_MMU #define randomize_va_space 0 diff --git a/mm/internal.h b/mm/internal.h index cb0af847d7d9..4690a58c4820 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1662,6 +1662,9 @@ void __meminit __init_page_from_nid(unsigned long pfn, int nid); unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg, int priority); +unsigned long do_shrink_slab(struct shrink_control *shrinkctl, + struct shrinker *shrinker, int priority); + int shmem_add_to_page_cache(struct folio *folio, struct address_space *mapping, pgoff_t index, void *expected, gfp_t gfp); diff --git a/mm/shrinker.c b/mm/shrinker.c index 4a93fd433689..075e4393da9c 100644 --- a/mm/shrinker.c +++ b/mm/shrinker.c @@ -368,8 +368,8 @@ static long add_nr_deferred(long nr, struct shrinker *shrinker, #define SHRINK_BATCH 128 -static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, - struct shrinker *shrinker, int priority) +unsigned long do_shrink_slab(struct shrink_control *shrinkctl, + struct shrinker *shrinker, int priority) { unsigned long freed = 0; unsigned long long delta; diff --git a/mm/vmscan.c b/mm/vmscan.c index 01d3364fe506..310bed25df78 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -455,6 +455,56 @@ void drop_slab(void) } while ((freed >> shift++) > 1); } +static unsigned long drop_shrinker_node(int nid, struct shrinker *shrinker) +{ + unsigned long freed = 0; + struct mem_cgroup *memcg = NULL; + + memcg = mem_cgroup_iter(NULL, NULL, NULL); + do { + unsigned long ret; + + struct shrink_control sc = { + .gfp_mask = GFP_KERNEL, + .nid = nid, + .memcg = memcg, + }; + + if (!mem_cgroup_disabled() && + !mem_cgroup_is_root(memcg) && + !mem_cgroup_online(memcg)) + continue; + + ret = do_shrink_slab(&sc, shrinker, 0); + if (ret == SHRINK_EMPTY) + ret = 0; + freed += ret; + cond_resched(); + } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL); + + return freed; +} + +void drop_sb_dentry_inode(struct super_block *sb) +{ + int nid; + int shift = 0; + unsigned long freed; + + if (!sb || !sb->s_shrink) + return; + + do { + freed = 0; + + for_each_online_node(nid) { + if (fatal_signal_pending(current)) + return; + freed += drop_shrinker_node(nid, sb->s_shrink); + } + } while ((freed >> shift++) > 1); +} + #define CHECK_RECLAIMER_OFFSET(type) \ do { \ BUILD_BUG_ON(PGSTEAL_##type - PGSTEAL_KSWAPD != \ -- 2.34.1