NFSv4.2: fix wrong shrinker_id
authorQi Zheng <zhengqi.arch@bytedance.com>
Thu, 15 Jun 2023 11:19:46 +0000 (11:19 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jul 2023 14:21:43 +0000 (16:21 +0200)
[ 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

index 76ae118..911f634 100644 (file)
@@ -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 @@ out4:
 
 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);
 }