Re: [PATCH v4 12/48] gfs2: dynamically allocate the gfs2-qd shrinker

2023-08-15 Thread Muchun Song



> On Aug 7, 2023, at 19:09, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the gfs2-qd shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v4 02/48] mm: vmscan: move shrinker-related code into a separate file

2023-08-15 Thread Muchun Song



> On Aug 7, 2023, at 19:08, Qi Zheng  wrote:
> 
> The mm/vmscan.c file is too large, so separate the shrinker-related
> code from it into a separate file. No functional changes.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 




Re: [PATCH v4 01/48] mm: move some shrinker-related function declarations to mm/internal.h

2023-08-15 Thread Muchun Song



> On Aug 7, 2023, at 19:08, Qi Zheng  wrote:
> 
> The following functions are only used inside the mm subsystem, so it's
> better to move their declarations to the mm/internal.h file.
> 
> 1. shrinker_debugfs_add()
> 2. shrinker_debugfs_detach()
> 3. shrinker_debugfs_remove()
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

One nit bellow.

[...]

> +
> +/*
> + * shrinker related functions
> + */

This is a multi-comment format. "/* shrinker related functions. */" is
the right one-line format of comment.

> +
> +#ifdef CONFIG_SHRINKER_DEBUG
> +extern int shrinker_debugfs_add(struct shrinker *shrinker);
> +extern struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker,
> +  int *debugfs_id);
> +extern void shrinker_debugfs_remove(struct dentry *debugfs_entry,
> +int debugfs_id);
> +#else /* CONFIG_SHRINKER_DEBUG */
> +static inline int shrinker_debugfs_add(struct shrinker *shrinker)
> +{
> + return 0;
> +}
> +static inline struct dentry *shrinker_debugfs_detach(struct shrinker 
> *shrinker,
> + int *debugfs_id)
> +{
> + *debugfs_id = -1;
> + return NULL;
> +}
> +static inline void shrinker_debugfs_remove(struct dentry *debugfs_entry,
> + int debugfs_id)
> +{
> +}
> +#endif /* CONFIG_SHRINKER_DEBUG */
> +
> #endif /* __MM_INTERNAL_H */
> -- 
> 2.30.2
> 




Re: [PATCH v4 06/48] binder: dynamically allocate the android-binder shrinker

2023-08-07 Thread Muchun Song



> On Aug 7, 2023, at 19:08, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the android-binder shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v4 19/48] rcu: dynamically allocate the rcu-kfree shrinker

2023-08-07 Thread Muchun Song



> On Aug 7, 2023, at 19:09, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the rcu-kfree shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 43/47] mm: shrinker: add a secondary array for shrinker_info::{map, nr_deferred}

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Currently, we maintain two linear arrays per node per memcg, which are
> shrinker_info::map and shrinker_info::nr_deferred. And we need to resize
> them when the shrinker_nr_max is exceeded, that is, allocate a new array,
> and then copy the old array to the new array, and finally free the old
> array by RCU.
> 
> For shrinker_info::map, we do set_bit() under the RCU lock, so we may set
> the value into the old map which is about to be freed. This may cause the
> value set to be lost. The current solution is not to copy the old map when
> resizing, but to set all the corresponding bits in the new map to 1. This
> solves the data loss problem, but bring the overhead of more pointless
> loops while doing memcg slab shrink.
> 
> For shrinker_info::nr_deferred, we will only modify it under the read lock
> of shrinker_rwsem, so it will not run concurrently with the resizing. But
> after we make memcg slab shrink lockless, there will be the same data loss
> problem as shrinker_info::map, and we can't work around it like the map.
> 
> For such resizable arrays, the most straightforward idea is to change it
> to xarray, like we did for list_lru [1]. We need to do xa_store() in the
> list_lru_add()-->set_shrinker_bit(), but this will cause memory
> allocation, and the list_lru_add() doesn't accept failure. A possible
> solution is to pre-allocate, but the location of pre-allocation is not
> well determined.
> 
> Therefore, this commit chooses to introduce a secondary array for
> shrinker_info::{map, nr_deferred}, so that we only need to copy this
> secondary array every time the size is resized. Then even if we get the
> old secondary array under the RCU lock, the found map and nr_deferred are
> also true, so no data is lost.
> 
> [1]. 
> https://lore.kernel.org/all/20220228122126.37293-13-songmuc...@bytedance.com/
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 42/47] drm/ttm: introduce pool_shrink_rwsem

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Currently, the synchronize_shrinkers() is only used by TTM pool. It only
> requires that no shrinkers run in parallel.
> 
> After we use RCU+refcount method to implement the lockless slab shrink,
> we can not use shrinker_rwsem or synchronize_rcu() to guarantee that all
> shrinker invocations have seen an update before freeing memory.
> 
> So we introduce a new pool_shrink_rwsem to implement a private
> synchronize_shrinkers(), so as to achieve the same purpose.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 41/47] mm: shrinker: remove old APIs

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Now no users are using the old APIs, just remove them.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 40/47] fs: super: dynamically allocate the s_shrink

2023-07-26 Thread Muchun Song




On 2023/7/24 17:43, Qi Zheng wrote:

In preparation for implementing lockless slab shrink, use new APIs to
dynamically allocate the s_shrink, 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 super_block.

Signed-off-by: Qi Zheng 


Reviewed-by: Muchun Song 



Re: [PATCH v2 39/47] zsmalloc: dynamically allocate the mm-zspool shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the mm-zspool 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 zs_pool.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 38/47] xfs: dynamically allocate the xfs-qm shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the xfs-qm 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 xfs_quotainfo.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 37/47] xfs: dynamically allocate the xfs-inodegc shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the xfs-inodegc 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 xfs_mount.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 36/47] xfs: dynamically allocate the xfs-buf shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the xfs-buf 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 xfs_buftarg.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 33/47] jbd2,ext4: dynamically allocate the jbd2-journal shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the jbd2-journal 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 journal_s.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 32/47] ext4: dynamically allocate the ext4-es shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs 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 

Reviewed-by: Muchun Song 





Re: [PATCH v2 31/47] mbcache: dynamically allocate the mbcache shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the mbcache 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 mb_cache.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 30/47] virtio_balloon: dynamically allocate the virtio-balloon shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the virtio-balloon 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 virtio_balloon.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 29/47] vmw_balloon: dynamically allocate the vmw-balloon shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the vmw-balloon 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 vmballoon.
> 
> And we can simply exit vmballoon_init() when registering the shrinker
> fails. So the shrinker_registered indication is redundant, just remove it.
> 
> Signed-off-by: Qi Zheng 

Nice cleanup.

Reviewed-by: Muchun Song 





Re: [PATCH v2 28/47] bcache: dynamically allocate the md-bcache shrinker

2023-07-26 Thread Muchun Song




On 2023/7/24 17:43, Qi Zheng wrote:

In preparation for implementing lockless slab shrink, use new APIs to
dynamically allocate the md-bcache 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 cache_set.

Signed-off-by: Qi Zheng 
---
  drivers/md/bcache/bcache.h |  2 +-
  drivers/md/bcache/btree.c  | 27 ---
  drivers/md/bcache/sysfs.c  |  3 ++-
  3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 5a79bb3c272f..c622bc50f81b 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -541,7 +541,7 @@ struct cache_set {
struct bio_set  bio_split;
  
  	/* For the btree cache */

-   struct shrinker shrink;
+   struct shrinker *shrink;
  
  	/* For the btree cache and anything allocation related */

struct mutexbucket_lock;
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index fd121a61f17c..c176c7fc77d9 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -667,7 +667,7 @@ static int mca_reap(struct btree *b, unsigned int 
min_order, bool flush)
  static unsigned long bch_mca_scan(struct shrinker *shrink,
  struct shrink_control *sc)
  {
-   struct cache_set *c = container_of(shrink, struct cache_set, shrink);
+   struct cache_set *c = shrink->private_data;
struct btree *b, *t;
unsigned long i, nr = sc->nr_to_scan;
unsigned long freed = 0;
@@ -734,7 +734,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
  static unsigned long bch_mca_count(struct shrinker *shrink,
   struct shrink_control *sc)
  {
-   struct cache_set *c = container_of(shrink, struct cache_set, shrink);
+   struct cache_set *c = shrink->private_data;
  
  	if (c->shrinker_disabled)

return 0;
@@ -752,8 +752,8 @@ void bch_btree_cache_free(struct cache_set *c)
  
  	closure_init_stack(&cl);
  
-	if (c->shrink.list.next)

-   unregister_shrinker(&c->shrink);
+   if (c->shrink)
+   shrinker_unregister(c->shrink);
  
  	mutex_lock(&c->bucket_lock);
  
@@ -828,14 +828,19 @@ int bch_btree_cache_alloc(struct cache_set *c)

c->verify_data = NULL;
  #endif
  
-	c->shrink.count_objects = bch_mca_count;

-   c->shrink.scan_objects = bch_mca_scan;
-   c->shrink.seeks = 4;
-   c->shrink.batch = c->btree_pages * 2;
+   c->shrink = shrinker_alloc(0, "md-bcache:%pU", c->set_uuid);
+   if (!c->shrink) {
+   pr_warn("bcache: %s: could not allocate shrinker\n", __func__);
+   return -ENOMEM;


Seems you have cheanged the semantic of this. In the past,
it is better to have a shrinker, but now it becomes a mandatory.
Right? I don't know if it is acceptable. From my point of view,
just do the cleanup, don't change any behaviour.


+   }
+
+   c->shrink->count_objects = bch_mca_count;
+   c->shrink->scan_objects = bch_mca_scan;
+   c->shrink->seeks = 4;
+   c->shrink->batch = c->btree_pages * 2;
+   c->shrink->private_data = c;
  
-	if (register_shrinker(&c->shrink, "md-bcache:%pU", c->set_uuid))

-   pr_warn("bcache: %s: could not register shrinker\n",
-   __func__);
+   shrinker_register(c->shrink);
  
  	return 0;

  }
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 0e2c1880f60b..45d8af755de6 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -866,7 +866,8 @@ STORE(__bch_cache_set)
  
  		sc.gfp_mask = GFP_KERNEL;

sc.nr_to_scan = strtoul_or_return(buf);
-   c->shrink.scan_objects(&c->shrink, &sc);
+   if (c->shrink)
+   c->shrink->scan_objects(c->shrink, &sc);
}
  
  	sysfs_strtoul_clamp(congested_read_threshold_us,





Re: [PATCH v2 27/47] md/raid5: dynamically allocate the md-raid5 shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the md-raid5 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 r5conf.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 26/47] dm zoned: dynamically allocate the dm-zoned-meta shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the dm-zoned-meta 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 dmz_metadata.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 25/47] dm: dynamically allocate the dm-bufio shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the dm-bufio 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 dm_bufio_client.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 23/47] drm/msm: dynamically allocate the drm-msm_gem shrinker

2023-07-26 Thread Muchun Song




On 2023/7/24 17:43, Qi Zheng wrote:

In preparation for implementing lockless slab shrink, use new APIs to
dynamically allocate the drm-msm_gem 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 msm_drm_private.

Signed-off-by: Qi Zheng 


Reviewed-by: Muchun Song 

A nit bellow.


---
  drivers/gpu/drm/msm/msm_drv.c  |  4 ++-
  drivers/gpu/drm/msm/msm_drv.h  |  4 +--
  drivers/gpu/drm/msm/msm_gem_shrinker.c | 36 --
  3 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 891eff8433a9..7f6933be703f 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -461,7 +461,9 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
if (ret)
goto err_msm_uninit;
  
-	msm_gem_shrinker_init(ddev);

+   ret = msm_gem_shrinker_init(ddev);
+   if (ret)
+   goto err_msm_uninit;
  
  	if (priv->kms_init) {

ret = priv->kms_init(ddev);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index e13a8cbd61c9..84523d4a1e58 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -217,7 +217,7 @@ struct msm_drm_private {
} vram;
  
  	struct notifier_block vmap_notifier;

-   struct shrinker shrinker;
+   struct shrinker *shrinker;
  
  	struct drm_atomic_state *pm_state;
  
@@ -279,7 +279,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,

  unsigned long msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long 
nr_to_scan);
  #endif
  
-void msm_gem_shrinker_init(struct drm_device *dev);

+int msm_gem_shrinker_init(struct drm_device *dev);
  void msm_gem_shrinker_cleanup(struct drm_device *dev);
  
  int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);

diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c 
b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index f38296ad8743..7daab1298c11 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -34,8 +34,7 @@ static bool can_block(struct shrink_control *sc)
  static unsigned long
  msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
  {
-   struct msm_drm_private *priv =
-   container_of(shrinker, struct msm_drm_private, shrinker);
+   struct msm_drm_private *priv = shrinker->private_data;
unsigned count = priv->lru.dontneed.count;
  
  	if (can_swap())

@@ -100,8 +99,7 @@ active_evict(struct drm_gem_object *obj)
  static unsigned long
  msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
  {
-   struct msm_drm_private *priv =
-   container_of(shrinker, struct msm_drm_private, shrinker);
+   struct msm_drm_private *priv = shrinker->private_data;
struct {
struct drm_gem_lru *lru;
bool (*shrink)(struct drm_gem_object *obj);
@@ -148,10 +146,11 @@ msm_gem_shrinker_shrink(struct drm_device *dev, unsigned 
long nr_to_scan)
struct shrink_control sc = {
.nr_to_scan = nr_to_scan,
};
-   int ret;
+   unsigned long ret = SHRINK_STOP;
  
  	fs_reclaim_acquire(GFP_KERNEL);

-   ret = msm_gem_shrinker_scan(&priv->shrinker, &sc);
+   if (priv->shrinker)
+   ret = msm_gem_shrinker_scan(priv->shrinker, &sc);
fs_reclaim_release(GFP_KERNEL);
  
  	return ret;

@@ -210,16 +209,27 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned 
long event, void *ptr)
   *
   * This function registers and sets up the msm shrinker.
   */
-void msm_gem_shrinker_init(struct drm_device *dev)
+int msm_gem_shrinker_init(struct drm_device *dev)
  {
struct msm_drm_private *priv = dev->dev_private;
-   priv->shrinker.count_objects = msm_gem_shrinker_count;
-   priv->shrinker.scan_objects = msm_gem_shrinker_scan;
-   priv->shrinker.seeks = DEFAULT_SEEKS;
-   WARN_ON(register_shrinker(&priv->shrinker, "drm-msm_gem"));
+
+   priv->shrinker = shrinker_alloc(0, "drm-msm_gem");
+   if (!priv->shrinker) {


Just "if (WARN_ON(!priv->shrinker))"


+   WARN_ON(1);
+   return -ENOMEM;
+   }
+
+   priv->shrinker->count_objects = msm_gem_shrinker_count;
+   priv->shrinker->scan_objects = msm_gem_shrinker_scan;
+   priv->shrinker->seeks = DEFAULT_SEEKS;
+   priv->shrinker->private_data = priv;
+
+   shrinker_register(priv->shrinker);
  
  	priv->vmap_notifier.notifier_call = msm_gem_shrinker_vmap;

WARN_ON(register_vmap_purge_notifier(&priv->vmap_notifier));
+
+   return 0;
  }
  
  /**

@@ -232,8 +242,8 @@ void msm_gem_s

Re: [PATCH v2 22/47] drm/i915: dynamically allocate the i915_gem_mm shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> In preparation for implementing lockless slab shrink, use new APIs to
> dynamically allocate the i915_gem_mm 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 drm_i915_private.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 21/47] mm: workingset: dynamically allocate the mm-shadow shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the mm-shadow shrinker.
> 
> Signed-off-by: Qi Zheng 
> ---
> mm/workingset.c | 26 ++
> 1 file changed, 14 insertions(+), 12 deletions(-)
> 
> diff --git a/mm/workingset.c b/mm/workingset.c
> index 4686ae363000..4bc85f739b13 100644
> --- a/mm/workingset.c
> +++ b/mm/workingset.c
> @@ -762,12 +762,7 @@ static unsigned long scan_shadow_nodes(struct shrinker 
> *shrinker,
> NULL);
> }
> 
> -static struct shrinker workingset_shadow_shrinker = {
> - .count_objects = count_shadow_nodes,
> - .scan_objects = scan_shadow_nodes,
> - .seeks = 0, /* ->count reports only fully expendable nodes */
> - .flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE,
> -};
> +static struct shrinker *workingset_shadow_shrinker;


Same as patch #17.


Re: [PATCH v2 20/47] sunrpc: dynamically allocate the sunrpc_cred shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the sunrpc_cred shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 19/47] mm: thp: dynamically allocate the thp-related shrinkers

2023-07-26 Thread Muchun Song




On 2023/7/24 17:43, Qi Zheng wrote:

Use new APIs to dynamically allocate the thp-zero and thp-deferred_split
shrinkers.

Signed-off-by: Qi Zheng 
---
  mm/huge_memory.c | 69 +++-
  1 file changed, 45 insertions(+), 24 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 8c94b34024a2..4db5a1834d81 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -65,7 +65,11 @@ unsigned long transparent_hugepage_flags __read_mostly =
(1<  
-static struct shrinker deferred_split_shrinker;

+static struct shrinker *deferred_split_shrinker;
+static unsigned long deferred_split_count(struct shrinker *shrink,
+ struct shrink_control *sc);
+static unsigned long deferred_split_scan(struct shrinker *shrink,
+struct shrink_control *sc);
  
  static atomic_t huge_zero_refcount;

  struct page *huge_zero_page __read_mostly;
@@ -229,11 +233,7 @@ static unsigned long shrink_huge_zero_page_scan(struct 
shrinker *shrink,
return 0;
  }
  
-static struct shrinker huge_zero_page_shrinker = {

-   .count_objects = shrink_huge_zero_page_count,
-   .scan_objects = shrink_huge_zero_page_scan,
-   .seeks = DEFAULT_SEEKS,
-};
+static struct shrinker *huge_zero_page_shrinker;


Same as patch #17.

  
  #ifdef CONFIG_SYSFS

  static ssize_t enabled_show(struct kobject *kobj,
@@ -454,6 +454,40 @@ static inline void hugepage_exit_sysfs(struct kobject 
*hugepage_kobj)
  }
  #endif /* CONFIG_SYSFS */
  
+static int thp_shrinker_init(void)


Better to declare it as __init.


+{
+   huge_zero_page_shrinker = shrinker_alloc(0, "thp-zero");
+   if (!huge_zero_page_shrinker)
+   return -ENOMEM;
+
+   deferred_split_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE |
+SHRINKER_MEMCG_AWARE |
+SHRINKER_NONSLAB,
+"thp-deferred_split");
+   if (!deferred_split_shrinker) {
+   shrinker_free_non_registered(huge_zero_page_shrinker);
+   return -ENOMEM;
+   }
+
+   huge_zero_page_shrinker->count_objects = shrink_huge_zero_page_count;
+   huge_zero_page_shrinker->scan_objects = shrink_huge_zero_page_scan;
+   huge_zero_page_shrinker->seeks = DEFAULT_SEEKS;
+   shrinker_register(huge_zero_page_shrinker);
+
+   deferred_split_shrinker->count_objects = deferred_split_count;
+   deferred_split_shrinker->scan_objects = deferred_split_scan;
+   deferred_split_shrinker->seeks = DEFAULT_SEEKS;
+   shrinker_register(deferred_split_shrinker);
+
+   return 0;
+}
+
+static void thp_shrinker_exit(void)


Same as here.


+{
+   shrinker_unregister(huge_zero_page_shrinker);
+   shrinker_unregister(deferred_split_shrinker);
+}
+
  static int __init hugepage_init(void)
  {
int err;
@@ -482,12 +516,9 @@ static int __init hugepage_init(void)
if (err)
goto err_slab;
  
-	err = register_shrinker(&huge_zero_page_shrinker, "thp-zero");

-   if (err)
-   goto err_hzp_shrinker;
-   err = register_shrinker(&deferred_split_shrinker, "thp-deferred_split");
+   err = thp_shrinker_init();
if (err)
-   goto err_split_shrinker;
+   goto err_shrinker;
  
  	/*

 * By default disable transparent hugepages on smaller systems,
@@ -505,10 +536,8 @@ static int __init hugepage_init(void)
  
  	return 0;

  err_khugepaged:
-   unregister_shrinker(&deferred_split_shrinker);
-err_split_shrinker:
-   unregister_shrinker(&huge_zero_page_shrinker);
-err_hzp_shrinker:
+   thp_shrinker_exit();
+err_shrinker:
khugepaged_destroy();
  err_slab:
hugepage_exit_sysfs(hugepage_kobj);
@@ -2851,7 +2880,7 @@ void deferred_split_folio(struct folio *folio)
  #ifdef CONFIG_MEMCG
if (memcg)
set_shrinker_bit(memcg, folio_nid(folio),
-deferred_split_shrinker.id);
+deferred_split_shrinker->id);
  #endif
}
spin_unlock_irqrestore(&ds_queue->split_queue_lock, flags);
@@ -2925,14 +2954,6 @@ static unsigned long deferred_split_scan(struct shrinker 
*shrink,
return split;
  }
  
-static struct shrinker deferred_split_shrinker = {

-   .count_objects = deferred_split_count,
-   .scan_objects = deferred_split_scan,
-   .seeks = DEFAULT_SEEKS,
-   .flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE |
-SHRINKER_NONSLAB,
-};
-
  #ifdef CONFIG_DEBUG_FS
  static void split_huge_pages_all(void)
  {





Re: [PATCH v2 18/47] rcu: dynamically allocate the rcu-kfree shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the rcu-kfree shrinker.
> 
> Signed-off-by: Qi Zheng 
> ---
> kernel/rcu/tree.c | 21 +
> 1 file changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 1449cb69a0e0..d068ce3567fc 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -3445,12 +3445,7 @@ kfree_rcu_shrink_scan(struct shrinker *shrink, struct 
> shrink_control *sc)
> return freed == 0 ? SHRINK_STOP : freed;
> }
> 
> -static struct shrinker kfree_rcu_shrinker = {
> - .count_objects = kfree_rcu_shrink_count,
> - .scan_objects = kfree_rcu_shrink_scan,
> - .batch = 0,
> - .seeks = DEFAULT_SEEKS,
> -};
> +static struct shrinker *kfree_rcu_shrinker;

Same as patch #17.


Re: [PATCH v2 17/47] rcu: dynamically allocate the rcu-lazy shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the rcu-lazy shrinker.
> 
> Signed-off-by: Qi Zheng 
> ---
> kernel/rcu/tree_nocb.h | 19 +++
> 1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
> index 43229d2b0c44..919f17561733 100644
> --- a/kernel/rcu/tree_nocb.h
> +++ b/kernel/rcu/tree_nocb.h
> @@ -1397,12 +1397,7 @@ lazy_rcu_shrink_scan(struct shrinker *shrink, struct 
> shrink_control *sc)
> return count ? count : SHRINK_STOP;
> }
> 
> -static struct shrinker lazy_rcu_shrinker = {
> - .count_objects = lazy_rcu_shrink_count,
> - .scan_objects = lazy_rcu_shrink_scan,
> - .batch = 0,
> - .seeks = DEFAULT_SEEKS,
> -};
> +static struct shrinker *lazy_rcu_shrinker;

Seems there is no users of this variable, maybe we could drop
this.




Re: [PATCH v2 16/47] ubifs: dynamically allocate the ubifs-slab shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the ubifs-slab shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 15/47] quota: dynamically allocate the dquota-cache shrinker

2023-07-26 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the dquota-cache shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 14/47] nfsd: dynamically allocate the nfsd-filecache shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the nfsd-filecache shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 13/47] nfs: dynamically allocate the nfs-acl shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the nfs-acl shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 12/47] NFSv4.2: dynamically allocate the nfs-xattr shrinkers

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the nfs-xattr shrinkers.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 





Re: [PATCH v2 11/47] gfs2: dynamically allocate the gfs2-qd shrinker

2023-07-25 Thread Muchun Song




On 2023/7/24 17:43, Qi Zheng wrote:

Use new APIs to dynamically allocate the gfs2-qd shrinker.

Signed-off-by: Qi Zheng 
---
  fs/gfs2/main.c  |  6 +++---
  fs/gfs2/quota.c | 26 --
  fs/gfs2/quota.h |  3 ++-
  3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index afcb32854f14..e47b1cc79f59 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -147,7 +147,7 @@ static int __init init_gfs2_fs(void)
if (!gfs2_trans_cachep)
goto fail_cachep8;
  
-	error = register_shrinker(&gfs2_qd_shrinker, "gfs2-qd");

+   error = gfs2_qd_shrinker_init();
if (error)
goto fail_shrinker;
  
@@ -196,7 +196,7 @@ static int __init init_gfs2_fs(void)

  fail_wq2:
destroy_workqueue(gfs_recovery_wq);
  fail_wq1:
-   unregister_shrinker(&gfs2_qd_shrinker);
+   gfs2_qd_shrinker_exit();
  fail_shrinker:
kmem_cache_destroy(gfs2_trans_cachep);
  fail_cachep8:
@@ -229,7 +229,7 @@ static int __init init_gfs2_fs(void)
  
  static void __exit exit_gfs2_fs(void)

  {
-   unregister_shrinker(&gfs2_qd_shrinker);
+   gfs2_qd_shrinker_exit();
gfs2_glock_exit();
gfs2_unregister_debugfs();
unregister_filesystem(&gfs2_fs_type);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 704192b73605..bc9883cea847 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -186,13 +186,27 @@ static unsigned long gfs2_qd_shrink_count(struct shrinker 
*shrink,
return vfs_pressure_ratio(list_lru_shrink_count(&gfs2_qd_lru, sc));
  }
  
-struct shrinker gfs2_qd_shrinker = {

-   .count_objects = gfs2_qd_shrink_count,
-   .scan_objects = gfs2_qd_shrink_scan,
-   .seeks = DEFAULT_SEEKS,
-   .flags = SHRINKER_NUMA_AWARE,
-};
+static struct shrinker *gfs2_qd_shrinker;
+
+int gfs2_qd_shrinker_init(void)


It's better to declare this as __init.


+{
+   gfs2_qd_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE, "gfs2-qd");
+   if (!gfs2_qd_shrinker)
+   return -ENOMEM;
+
+   gfs2_qd_shrinker->count_objects = gfs2_qd_shrink_count;
+   gfs2_qd_shrinker->scan_objects = gfs2_qd_shrink_scan;
+   gfs2_qd_shrinker->seeks = DEFAULT_SEEKS;
+
+   shrinker_register(gfs2_qd_shrinker);
  
+	return 0;

+}
+
+void gfs2_qd_shrinker_exit(void)
+{
+   shrinker_unregister(gfs2_qd_shrinker);
+}
  
  static u64 qd2index(struct gfs2_quota_data *qd)

  {
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index 21ada332d555..f9cb863373f7 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -59,7 +59,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip,
  }
  
  extern const struct quotactl_ops gfs2_quotactl_ops;

-extern struct shrinker gfs2_qd_shrinker;
+int gfs2_qd_shrinker_init(void);
+void gfs2_qd_shrinker_exit(void);
  extern struct list_lru gfs2_qd_lru;
  extern void __init gfs2_quota_hash_init(void);
  





Re: [PATCH v2 10/47] gfs2: dynamically allocate the gfs2-glock shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the gfs2-glock shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.




Re: [PATCH v2 09/47] f2fs: dynamically allocate the f2fs-shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the f2fs-shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.




Re: [PATCH v2 08/47] erofs: dynamically allocate the erofs-shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the erofs-shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.




Re: [PATCH v2 07/47] xenbus/backend: dynamically allocate the xen-backend shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the xen-backend shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.




Re: [PATCH v2 06/47] drm/ttm: dynamically allocate the drm-ttm_pool shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the drm-ttm_pool shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.




Re: [PATCH v2 04/47] kvm: mmu: dynamically allocate the x86-mmu shrinker

2023-07-25 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> Use new APIs to dynamically allocate the x86-mmu shrinker.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.




Re: [PATCH v2 03/47] mm: shrinker: add infrastructure for dynamically allocating shrinker

2023-07-25 Thread Muchun Song




On 2023/7/24 17:43, Qi Zheng wrote:

Currently, the shrinker instances can be divided into the following three
types:

a) global shrinker instance statically defined in the kernel, such as
workingset_shadow_shrinker.

b) global shrinker instance statically defined in the kernel modules, such
as mmu_shrinker in x86.

c) shrinker instance embedded in other structures.

For case a, the memory of shrinker instance is never freed. For case b,
the memory of shrinker instance will be freed after synchronize_rcu() when
the module is unloaded. For case c, the memory of shrinker instance will
be freed along with the structure it is embedded in.

In preparation for implementing lockless slab shrink, we need to
dynamically allocate those shrinker instances in case c, then the memory
can be dynamically freed alone by calling kfree_rcu().

So this commit adds the following new APIs for dynamically allocating
shrinker, and add a private_data field to struct shrinker to record and
get the original embedded structure.

1. shrinker_alloc()

Used to allocate shrinker instance itself and related memory, it will
return a pointer to the shrinker instance on success and NULL on failure.

2. shrinker_free_non_registered()

Used to destroy the non-registered shrinker instance.


At least I don't like this name. I know you want to tell others
this function only should be called when shrinker has not been
registed but allocated. Maybe shrinker_free() is more simple.
And and a comment to tell the users when to use it.



3. shrinker_register()

Used to register the shrinker instance, which is same as the current
register_shrinker_prepared().

4. shrinker_unregister()

Used to unregister and free the shrinker instance.

In order to simplify shrinker-related APIs and make shrinker more
independent of other kernel mechanisms, subsequent submissions will use
the above API to convert all shrinkers (including case a and b) to
dynamically allocated, and then remove all existing APIs.

This will also have another advantage mentioned by Dave Chinner:

```
The other advantage of this is that it will break all the existing
out of tree code and third party modules using the old API and will
no longer work with a kernel using lockless slab shrinkers. They
need to break (both at the source and binary levels) to stop bad
things from happening due to using uncoverted shrinkers in the new
setup.
```

Signed-off-by: Qi Zheng 
---
  include/linux/shrinker.h |   6 +++
  mm/shrinker.c| 113 +++
  2 files changed, 119 insertions(+)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 961cb84e51f5..296f5e163861 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -70,6 +70,8 @@ struct shrinker {
int seeks;  /* seeks to recreate an obj */
unsigned flags;
  
+	void *private_data;

+
/* These are for internal use */
struct list_head list;
  #ifdef CONFIG_MEMCG
@@ -98,6 +100,10 @@ struct shrinker {
  
  unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg,

  int priority);
+struct shrinker *shrinker_alloc(unsigned int flags, const char *fmt, ...);
+void shrinker_free_non_registered(struct shrinker *shrinker);
+void shrinker_register(struct shrinker *shrinker);
+void shrinker_unregister(struct shrinker *shrinker);
  
  extern int __printf(2, 3) prealloc_shrinker(struct shrinker *shrinker,

const char *fmt, ...);
diff --git a/mm/shrinker.c b/mm/shrinker.c
index 0a32ef42f2a7..d820e4cc5806 100644
--- a/mm/shrinker.c
+++ b/mm/shrinker.c
@@ -548,6 +548,119 @@ unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct 
mem_cgroup *memcg,
return freed;
  }
  
+struct shrinker *shrinker_alloc(unsigned int flags, const char *fmt, ...)

+{
+   struct shrinker *shrinker;
+   unsigned int size;
+   va_list __maybe_unused ap;
+   int err;
+
+   shrinker = kzalloc(sizeof(struct shrinker), GFP_KERNEL);
+   if (!shrinker)
+   return NULL;
+
+#ifdef CONFIG_SHRINKER_DEBUG
+   va_start(ap, fmt);
+   shrinker->name = kvasprintf_const(GFP_KERNEL, fmt, ap);
+   va_end(ap);
+   if (!shrinker->name)
+   goto err_name;
+#endif


So why not introduce another helper to handle this and declare it
as a void function when !CONFIG_SHRINKER_DEBUG? Something like the
following:

#ifdef CONFIG_SHRINKER_DEBUG
static int shrinker_debugfs_name_alloc(struct shrinker *shrinker, const 
char *fmt,

                                   va_list vargs)

{
    shrinker->name = kvasprintf_const(GFP_KERNEL, fmt, vargs);
    return shrinker->name ? 0 : -ENOMEM;
}
#else
static int shrinker_debugfs_name_alloc(struct shrinker *shrinker, const 
char *fmt,

                                   va_list vargs)
{
    return 0;
}
#endif


+   shrinker->flags = flags;
+
+   if (flags & SHRINKER_MEMCG_AWARE) {
+ 

Re: [PATCH v2 01/47] mm: vmscan: move shrinker-related code into a separate file

2023-07-24 Thread Muchun Song



> On Jul 25, 2023, at 11:09, Qi Zheng  wrote:
> 
> 
> 
> On 2023/7/25 10:35, Muchun Song wrote:
>>> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
>>> 
>>> The mm/vmscan.c file is too large, so separate the shrinker-related
>>> code from it into a separate file. No functional changes.
>>> 
>>> Signed-off-by: Qi Zheng 
>>> ---
>>> include/linux/shrinker.h |   3 +
>>> mm/Makefile  |   4 +-
>>> mm/shrinker.c| 707 +++
>>> mm/vmscan.c  | 701 --
>>> 4 files changed, 712 insertions(+), 703 deletions(-)
>>> create mode 100644 mm/shrinker.c
>>> 
>>> diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
>>> index 224293b2dd06..961cb84e51f5 100644
>>> --- a/include/linux/shrinker.h
>>> +++ b/include/linux/shrinker.h
>>> @@ -96,6 +96,9 @@ struct shrinker {
>>>  */
>>> #define SHRINKER_NONSLAB (1 << 3)
>>> 
>>> +unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup 
>>> *memcg,
>>> +int priority);
>> A good cleanup, vmscan.c is so huge.
>> I'd like to introduce a new header in mm/ directory and contains those
>> declarations of functions (like this and other debug function in
>> shrinker_debug.c) since they are used internally across mm.
> 
> How about putting them in the mm/internal.h file?

Either is fine to me.

> 
>> Thanks.





Re: [PATCH v2 02/47] mm: shrinker: remove redundant shrinker_rwsem in debugfs operations

2023-07-24 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> The debugfs_remove_recursive() will wait for debugfs_file_put() to return,
> so the shrinker will not be freed when doing debugfs operations (such as
> shrinker_debugfs_count_show() and shrinker_debugfs_scan_write()), so there
> is no need to hold shrinker_rwsem during debugfs operations.
> 
> Signed-off-by: Qi Zheng 

Reviewed-by: Muchun Song 

Thanks.





Re: [PATCH v2 01/47] mm: vmscan: move shrinker-related code into a separate file

2023-07-24 Thread Muchun Song



> On Jul 24, 2023, at 17:43, Qi Zheng  wrote:
> 
> The mm/vmscan.c file is too large, so separate the shrinker-related
> code from it into a separate file. No functional changes.
> 
> Signed-off-by: Qi Zheng 
> ---
> include/linux/shrinker.h |   3 +
> mm/Makefile  |   4 +-
> mm/shrinker.c| 707 +++
> mm/vmscan.c  | 701 --
> 4 files changed, 712 insertions(+), 703 deletions(-)
> create mode 100644 mm/shrinker.c
> 
> diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
> index 224293b2dd06..961cb84e51f5 100644
> --- a/include/linux/shrinker.h
> +++ b/include/linux/shrinker.h
> @@ -96,6 +96,9 @@ struct shrinker {
>  */
> #define SHRINKER_NONSLAB (1 << 3)
> 
> +unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg,
> +int priority);

A good cleanup, vmscan.c is so huge.

I'd like to introduce a new header in mm/ directory and contains those
declarations of functions (like this and other debug function in
shrinker_debug.c) since they are used internally across mm.

Thanks.