[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230622085335.77010-24-zhengqi.arch@bytedance.com>
Date: Thu, 22 Jun 2023 16:53:29 +0800
From: Qi Zheng <zhengqi.arch@...edance.com>
To: akpm@...ux-foundation.org, david@...morbit.com, tkhai@...ru,
vbabka@...e.cz, roman.gushchin@...ux.dev, djwong@...nel.org,
brauner@...nel.org, paulmck@...nel.org, tytso@....edu
Cc: linux-kernel@...r.kernel.org, linux-mm@...ck.org,
intel-gfx@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
linux-arm-msm@...r.kernel.org, dm-devel@...hat.com,
linux-raid@...r.kernel.org, linux-bcache@...r.kernel.org,
virtualization@...ts.linux-foundation.org,
linux-fsdevel@...r.kernel.org, linux-ext4@...r.kernel.org,
linux-nfs@...r.kernel.org, linux-xfs@...r.kernel.org,
linux-btrfs@...r.kernel.org, Qi Zheng <zhengqi.arch@...edance.com>
Subject: [PATCH 23/29] mm: shrinker: add refcount and completion_wait fields
This commit introduces refcount and completion_wait
fields to struct shrinker to manage the life cycle
of shrinker instance.
Just a preparation work for implementing the lockless
slab shrink, no functional changes.
Signed-off-by: Qi Zheng <zhengqi.arch@...edance.com>
---
include/linux/shrinker.h | 11 +++++++++++
mm/vmscan.c | 5 +++++
2 files changed, 16 insertions(+)
diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 4094e4c44e80..7bfeb2f25246 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -4,6 +4,8 @@
#include <linux/atomic.h>
#include <linux/types.h>
+#include <linux/refcount.h>
+#include <linux/completion.h>
/*
* This struct is used to pass information from page reclaim to the shrinkers.
@@ -70,6 +72,9 @@ struct shrinker {
int seeks; /* seeks to recreate an obj */
unsigned flags;
+ refcount_t refcount;
+ struct completion completion_wait;
+
void *private_data;
/* These are for internal use */
@@ -118,6 +123,12 @@ struct shrinker *shrinker_alloc_and_init(count_objects_cb count,
void shrinker_free(struct shrinker *shrinker);
void unregister_and_free_shrinker(struct shrinker *shrinker);
+static inline void shrinker_put(struct shrinker *shrinker)
+{
+ if (refcount_dec_and_test(&shrinker->refcount))
+ complete(&shrinker->completion_wait);
+}
+
#ifdef CONFIG_SHRINKER_DEBUG
extern int shrinker_debugfs_add(struct shrinker *shrinker);
extern struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3a8d50ad6ff6..6f9c4750effa 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -740,6 +740,8 @@ void free_prealloced_shrinker(struct shrinker *shrinker)
void register_shrinker_prepared(struct shrinker *shrinker)
{
down_write(&shrinker_rwsem);
+ refcount_set(&shrinker->refcount, 1);
+ init_completion(&shrinker->completion_wait);
list_add_tail(&shrinker->list, &shrinker_list);
shrinker->flags |= SHRINKER_REGISTERED;
shrinker_debugfs_add(shrinker);
@@ -794,6 +796,9 @@ void unregister_shrinker(struct shrinker *shrinker)
if (!(shrinker->flags & SHRINKER_REGISTERED))
return;
+ shrinker_put(shrinker);
+ wait_for_completion(&shrinker->completion_wait);
+
down_write(&shrinker_rwsem);
list_del(&shrinker->list);
shrinker->flags &= ~SHRINKER_REGISTERED;
--
2.30.2
Powered by blists - more mailing lists