[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <153365636747.19074.12610817307548583381.stgit@localhost.localdomain>
Date: Tue, 07 Aug 2018 18:39:27 +0300
From: Kirill Tkhai <ktkhai@...tuozzo.com>
To: akpm@...ux-foundation.org, gregkh@...uxfoundation.org,
rafael@...nel.org, viro@...iv.linux.org.uk,
darrick.wong@...cle.com, paulmck@...ux.vnet.ibm.com,
josh@...htriplett.org, rostedt@...dmis.org,
mathieu.desnoyers@...icios.com, jiangshanlai@...il.com,
hughd@...gle.com, shuah@...nel.org, robh@...nel.org,
ulf.hansson@...aro.org, aspriel@...il.com,
vivek.gautam@...eaurora.org, robin.murphy@....com, joe@...ches.com,
heikki.krogerus@...ux.intel.com, ktkhai@...tuozzo.com,
sfr@...b.auug.org.au, vdavydov.dev@...il.com, mhocko@...e.com,
chris@...is-wilson.co.uk, penguin-kernel@...ove.SAKURA.ne.jp,
aryabinin@...tuozzo.com, willy@...radead.org, ying.huang@...el.com,
shakeelb@...gle.com, jbacik@...com, mingo@...nel.org,
mhiramat@...nel.org, linux-kernel@...r.kernel.org,
linux-fsdevel@...r.kernel.org, linux-mm@...ck.org
Subject: [PATCH RFC 10/10] fs: Use unregister_shrinker_delayed_{initiate,
finalize} for super_block shrinker
Previous patches made all the data, which is touched from
super_cache_count(), destroyed from destroy_super_work():
s_dentry_lru, s_inode_lru and super_block::s_fs_info.
super_cache_scan() can't be called after SB_ACTIVE is cleared
in generic_shutdown_super().
So, it safe to move heavy unregister_shrinker_delayed_finalize()
part to delayed work, i.e. it's safe for parallel do_shrink_slab()
to be executed between unregister_shrinker_delayed_initiate() and
destroy_super_work()->unregister_shrinker_delayed_finalize().
This makes the heavy synchronize_srcu() to do not affect on user-visible
unregistration speed (since now it's executed from workqueue).
All further time-critical for unregistration places may be written
in the same conception.
Signed-off-by: Kirill Tkhai <ktkhai@...tuozzo.com>
---
fs/super.c | 4 +++-
include/linux/fs.h | 5 +++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/super.c b/fs/super.c
index c60f092538c7..33e829741ec0 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -165,6 +165,8 @@ static void destroy_super_work(struct work_struct *work)
destroy_work);
int i;
+ unregister_shrinker_delayed_finalize(&s->s_shrink);
+
WARN_ON(list_lru_count(&s->s_dentry_lru));
WARN_ON(list_lru_count(&s->s_inode_lru));
list_lru_destroy(&s->s_dentry_lru);
@@ -334,7 +336,7 @@ void deactivate_locked_super(struct super_block *s)
struct file_system_type *fs = s->s_type;
if (atomic_dec_and_test(&s->s_active)) {
cleancache_invalidate_fs(s);
- unregister_shrinker(&s->s_shrink);
+ unregister_shrinker_delayed_initiate(&s->s_shrink);
fs->kill_sb(s);
put_filesystem(fs);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 33dfaed0a01a..8a1cd3097eef 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1902,6 +1902,11 @@ struct super_operations {
struct dquot **(*get_dquots)(struct inode *);
#endif
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
+ /*
+ * Shrinker may call these two function on destructing super_block
+ * till unregister_shrinker_delayed_finalize() has completed
+ * in destroy_super_work(), and they must care about that.
+ */
long (*nr_cached_objects)(struct super_block *,
struct shrink_control *);
long (*free_cached_objects)(struct super_block *,
Powered by blists - more mailing lists