| From 20a901a68b41eed3ea9cfd10d79e36aa16b42c0e Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 15 Jun 2023 11:19:46 +0000 |
| Subject: NFSv4.2: fix wrong shrinker_id |
| |
| From: Qi Zheng <zhengqi.arch@bytedance.com> |
| |
| [ Upstream commit 7f7ab336898f281e58540ef781a8fb375acc32a9 ] |
| |
| Currently, the list_lru::shrinker_id corresponding to the nfs4_xattr |
| shrinkers is wrong: |
| |
| >>> prog["nfs4_xattr_cache_lru"].shrinker_id |
| (int)0 |
| >>> prog["nfs4_xattr_entry_lru"].shrinker_id |
| (int)0 |
| >>> prog["nfs4_xattr_large_entry_lru"].shrinker_id |
| (int)0 |
| >>> prog["nfs4_xattr_cache_shrinker"].id |
| (int)18 |
| >>> prog["nfs4_xattr_entry_shrinker"].id |
| (int)19 |
| >>> prog["nfs4_xattr_large_entry_shrinker"].id |
| (int)20 |
| |
| This is not what we expect, which will cause these shrinkers |
| not to be found in shrink_slab_memcg(). |
| |
| We should assign shrinker::id before calling list_lru_init_memcg(), |
| so that the corresponding list_lru::shrinker_id will be assigned |
| the correct value like below: |
| |
| >>> prog["nfs4_xattr_cache_lru"].shrinker_id |
| (int)16 |
| >>> prog["nfs4_xattr_entry_lru"].shrinker_id |
| (int)17 |
| >>> prog["nfs4_xattr_large_entry_lru"].shrinker_id |
| (int)18 |
| >>> prog["nfs4_xattr_cache_shrinker"].id |
| (int)16 |
| >>> prog["nfs4_xattr_entry_shrinker"].id |
| (int)17 |
| >>> prog["nfs4_xattr_large_entry_shrinker"].id |
| (int)18 |
| |
| So just do it. |
| |
| Fixes: 95ad37f90c33 ("NFSv4.2: add client side xattr caching.") |
| Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com> |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/nfs/nfs42xattr.c | 79 +++++++++++++++++++++++++-------------------- |
| 1 file changed, 44 insertions(+), 35 deletions(-) |
| |
| diff --git a/fs/nfs/nfs42xattr.c b/fs/nfs/nfs42xattr.c |
| index 76ae118342066..911f634ba3da7 100644 |
| --- a/fs/nfs/nfs42xattr.c |
| +++ b/fs/nfs/nfs42xattr.c |
| @@ -991,6 +991,29 @@ static void nfs4_xattr_cache_init_once(void *p) |
| INIT_LIST_HEAD(&cache->dispose); |
| } |
| |
| +static int nfs4_xattr_shrinker_init(struct shrinker *shrinker, |
| + struct list_lru *lru, const char *name) |
| +{ |
| + int ret = 0; |
| + |
| + ret = register_shrinker(shrinker, name); |
| + if (ret) |
| + return ret; |
| + |
| + ret = list_lru_init_memcg(lru, shrinker); |
| + if (ret) |
| + unregister_shrinker(shrinker); |
| + |
| + return ret; |
| +} |
| + |
| +static void nfs4_xattr_shrinker_destroy(struct shrinker *shrinker, |
| + struct list_lru *lru) |
| +{ |
| + unregister_shrinker(shrinker); |
| + list_lru_destroy(lru); |
| +} |
| + |
| int __init nfs4_xattr_cache_init(void) |
| { |
| int ret = 0; |
| @@ -1002,44 +1025,30 @@ int __init nfs4_xattr_cache_init(void) |
| if (nfs4_xattr_cache_cachep == NULL) |
| return -ENOMEM; |
| |
| - ret = list_lru_init_memcg(&nfs4_xattr_large_entry_lru, |
| - &nfs4_xattr_large_entry_shrinker); |
| - if (ret) |
| - goto out4; |
| - |
| - ret = list_lru_init_memcg(&nfs4_xattr_entry_lru, |
| - &nfs4_xattr_entry_shrinker); |
| - if (ret) |
| - goto out3; |
| - |
| - ret = list_lru_init_memcg(&nfs4_xattr_cache_lru, |
| - &nfs4_xattr_cache_shrinker); |
| - if (ret) |
| - goto out2; |
| - |
| - ret = register_shrinker(&nfs4_xattr_cache_shrinker, "nfs-xattr_cache"); |
| + ret = nfs4_xattr_shrinker_init(&nfs4_xattr_cache_shrinker, |
| + &nfs4_xattr_cache_lru, |
| + "nfs-xattr_cache"); |
| if (ret) |
| goto out1; |
| |
| - ret = register_shrinker(&nfs4_xattr_entry_shrinker, "nfs-xattr_entry"); |
| + ret = nfs4_xattr_shrinker_init(&nfs4_xattr_entry_shrinker, |
| + &nfs4_xattr_entry_lru, |
| + "nfs-xattr_entry"); |
| if (ret) |
| - goto out; |
| + goto out2; |
| |
| - ret = register_shrinker(&nfs4_xattr_large_entry_shrinker, |
| - "nfs-xattr_large_entry"); |
| + ret = nfs4_xattr_shrinker_init(&nfs4_xattr_large_entry_shrinker, |
| + &nfs4_xattr_large_entry_lru, |
| + "nfs-xattr_large_entry"); |
| if (!ret) |
| return 0; |
| |
| - unregister_shrinker(&nfs4_xattr_entry_shrinker); |
| -out: |
| - unregister_shrinker(&nfs4_xattr_cache_shrinker); |
| -out1: |
| - list_lru_destroy(&nfs4_xattr_cache_lru); |
| + nfs4_xattr_shrinker_destroy(&nfs4_xattr_entry_shrinker, |
| + &nfs4_xattr_entry_lru); |
| out2: |
| - list_lru_destroy(&nfs4_xattr_entry_lru); |
| -out3: |
| - list_lru_destroy(&nfs4_xattr_large_entry_lru); |
| -out4: |
| + nfs4_xattr_shrinker_destroy(&nfs4_xattr_cache_shrinker, |
| + &nfs4_xattr_cache_lru); |
| +out1: |
| kmem_cache_destroy(nfs4_xattr_cache_cachep); |
| |
| return ret; |
| @@ -1047,11 +1056,11 @@ int __init nfs4_xattr_cache_init(void) |
| |
| void nfs4_xattr_cache_exit(void) |
| { |
| - unregister_shrinker(&nfs4_xattr_large_entry_shrinker); |
| - unregister_shrinker(&nfs4_xattr_entry_shrinker); |
| - unregister_shrinker(&nfs4_xattr_cache_shrinker); |
| - list_lru_destroy(&nfs4_xattr_large_entry_lru); |
| - list_lru_destroy(&nfs4_xattr_entry_lru); |
| - list_lru_destroy(&nfs4_xattr_cache_lru); |
| + nfs4_xattr_shrinker_destroy(&nfs4_xattr_large_entry_shrinker, |
| + &nfs4_xattr_large_entry_lru); |
| + nfs4_xattr_shrinker_destroy(&nfs4_xattr_entry_shrinker, |
| + &nfs4_xattr_entry_lru); |
| + nfs4_xattr_shrinker_destroy(&nfs4_xattr_cache_shrinker, |
| + &nfs4_xattr_cache_lru); |
| kmem_cache_destroy(nfs4_xattr_cache_cachep); |
| } |
| -- |
| 2.39.2 |
| |