In preparation for implementing lockless slab shrink,
we need to dynamically allocate the ext4-es shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct ext4_sb_info.

Signed-off-by: Qi Zheng <zhengqi.a...@bytedance.com>
---
 fs/ext4/ext4.h           |  2 +-
 fs/ext4/extents_status.c | 21 ++++++++++++---------
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0a2d55faa095..1bd150d454f5 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1651,7 +1651,7 @@ struct ext4_sb_info {
        __u32 s_csum_seed;
 
        /* Reclaim extents from extent status tree */
-       struct shrinker s_es_shrinker;
+       struct shrinker *s_es_shrinker;
        struct list_head s_es_list;     /* List of inodes with reclaimable 
extents */
        long s_es_nr_inode;
        struct ext4_es_stats s_es_stats;
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index 9b5b8951afb4..fea82339f4b4 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -1596,7 +1596,7 @@ static unsigned long ext4_es_count(struct shrinker 
*shrink,
        unsigned long nr;
        struct ext4_sb_info *sbi;
 
-       sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker);
+       sbi = shrink->private_data;
        nr = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt);
        trace_ext4_es_shrink_count(sbi->s_sb, sc->nr_to_scan, nr);
        return nr;
@@ -1605,8 +1605,7 @@ static unsigned long ext4_es_count(struct shrinker 
*shrink,
 static unsigned long ext4_es_scan(struct shrinker *shrink,
                                  struct shrink_control *sc)
 {
-       struct ext4_sb_info *sbi = container_of(shrink,
-                                       struct ext4_sb_info, s_es_shrinker);
+       struct ext4_sb_info *sbi = shrink->private_data;
        int nr_to_scan = sc->nr_to_scan;
        int ret, nr_shrunk;
 
@@ -1690,15 +1689,19 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi)
        if (err)
                goto err3;
 
-       sbi->s_es_shrinker.scan_objects = ext4_es_scan;
-       sbi->s_es_shrinker.count_objects = ext4_es_count;
-       sbi->s_es_shrinker.seeks = DEFAULT_SEEKS;
-       err = register_shrinker(&sbi->s_es_shrinker, "ext4-es:%s",
+       sbi->s_es_shrinker = shrinker_alloc_and_init(ext4_es_count, 
ext4_es_scan,
+                                                    0, DEFAULT_SEEKS, 0, sbi);
+       if (!sbi->s_es_shrinker)
+               goto err4;
+
+       err = register_shrinker(sbi->s_es_shrinker, "ext4-es:%s",
                                sbi->s_sb->s_id);
        if (err)
-               goto err4;
+               goto err5;
 
        return 0;
+err5:
+       shrinker_free(sbi->s_es_shrinker);
 err4:
        percpu_counter_destroy(&sbi->s_es_stats.es_stats_shk_cnt);
 err3:
@@ -1716,7 +1719,7 @@ void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi)
        percpu_counter_destroy(&sbi->s_es_stats.es_stats_cache_misses);
        percpu_counter_destroy(&sbi->s_es_stats.es_stats_all_cnt);
        percpu_counter_destroy(&sbi->s_es_stats.es_stats_shk_cnt);
-       unregister_shrinker(&sbi->s_es_shrinker);
+       unregister_and_free_shrinker(sbi->s_es_shrinker);
 }
 
 /*
-- 
2.30.2

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to