Whamcloud - gitweb
LU-8130 libcfs: don't use radix tree for xarray 62/56762/2
authorJames Simmons <jsimmons@infradead.org>
Wed, 23 Oct 2024 00:19:44 +0000 (17:19 -0700)
committerOleg Drokin <green@whamcloud.com>
Tue, 5 Nov 2024 06:29:00 +0000 (06:29 +0000)
For newer kernels the radix tree is totally based on Xarray. For Lustre
support for RHEL7 we backported Xarray but it still was using the
radix tree. Their is a mismatch between what the radix tree expects
and using a struct xa_node when allocating and freeing memory. Instead
abandon all use of the radix tree with Xarray. We use our own private
kmem cache which is based on radix tree but it uses xa_node.

Lustre-change: https://review.whamcloud.com/51840
Lustre-commit: 778791dd7da107710c2311935a24cfd7e7a5fd85

LU-17052 libcfs: fix build for old kernel

Fix build for kernel v4.17 to v4.19.
These old kernels already have xarray.h and #include by fs.h but
don't have full xarray support. It is needed to #include libcfs's
xarray.h also to contain xarray support.

Rename the header define macro to ensure libcfs's xarray.h will be
included。

Lustre-change: https://review.whamcloud.com/52090
Lustre-commit: 778791dd7da107710c2311935a24cfd7e7a5fd85

Test-Parameters: trivial
Test-Parameters: testlist=sanityn envdefinitions=ONLY=77,ONLY_REPEAT=20
Fixes: 84e12028be9a ("LU-9859 libcfs: add support for Xarray")
Fixes: 778791dd7da1 ("LU-8130 libcfs: don't use radix tree for xarray")
Signed-off-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: Xinliang Liu <xinliang.liu@linaro.org>
Change-Id: I87607aa0e55a4aca039f2fef5a76fbff0bedd9b3
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56762
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Yang Sheng <ys@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/include/libcfs/linux/xarray.h
libcfs/libcfs/linux/linux-prim.c
libcfs/libcfs/linux/xarray.c

index 74397ab..b252aaf 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
-#ifndef _LINUX_XARRAY_H
-#define _LINUX_XARRAY_H
+#ifndef _LINUX_XARRAY_LUSTRE_H
+#define _LINUX_XARRAY_LUSTRE_H
 /*
  * eXtensible Arrays
  * Copyright (c) 2017 Microsoft Corporation
@@ -1763,4 +1763,4 @@ static inline void *xas_next(struct xa_state *xas)
 }
 #endif /* !HAVE_XARRAY_SUPPORT */
 
-#endif /* _LINUX_XARRAY_H */
+#endif /* _LINUX_XARRAY_LUSTRE_H */
index 5f2f6ae..7203ee3 100644 (file)
@@ -49,6 +49,9 @@
 #include <libcfs/linux/linux-time.h>
 #include <libcfs/linux/linux-wait.h>
 #include <libcfs/linux/linux-misc.h>
+#ifndef HAVE_XARRAY_SUPPORT
+#include <libcfs/linux/xarray.h>
+#endif
 
 #ifndef HAVE_KTIME_GET_TS64
 void ktime_get_ts64(struct timespec64 *ts)
@@ -117,7 +120,15 @@ int cfs_apply_workqueue_attrs(struct workqueue_struct *wq,
 EXPORT_SYMBOL_GPL(cfs_apply_workqueue_attrs);
 
 #ifndef HAVE_XARRAY_SUPPORT
-struct kmem_cache (*radix_tree_node_cachep);
+struct kmem_cache *xarray_cachep;
+
+static void xarray_node_ctor(void *arg)
+{
+       struct xa_node *node = arg;
+
+       memset(node, 0, sizeof(*node));
+       INIT_LIST_HEAD(&node->private_list);
+}
 #endif
 
 void __init cfs_arch_init(void)
@@ -128,8 +139,10 @@ void __init cfs_arch_init(void)
        cfs_apply_workqueue_attrs_t =
                (void *)cfs_kallsyms_lookup_name("apply_workqueue_attrs");
 #ifndef HAVE_XARRAY_SUPPORT
-       radix_tree_node_cachep =
-               (void *)cfs_kallsyms_lookup_name("radix_tree_node_cachep");
+       xarray_cachep = kmem_cache_create("xarray_cache",
+                                         sizeof(struct xa_node), 0,
+                                         SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
+                                         xarray_node_ctor);
 #endif
 }
 
index fea97fe..5bc9d76 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/export.h>
 #include <linux/list.h>
 #include <linux/slab.h>
-#include <linux/radix-tree.h>
 #include <libcfs/linux/xarray.h>
 
 /*
@@ -252,18 +251,18 @@ void *xas_load(struct xa_state *xas)
 EXPORT_SYMBOL_GPL(xas_load);
 
 /* Move the radix tree node cache here */
-extern struct kmem_cache *radix_tree_node_cachep;
+extern struct kmem_cache *xarray_cachep;
 
-static inline void tag_clear(struct radix_tree_node *node, unsigned int tag,
+static inline void tag_clear(struct xa_node *node, unsigned int tag,
                             int offset)
 {
        __clear_bit(offset, node->tags[tag]);
 }
 
-static void radix_tree_node_rcu_free(struct rcu_head *head)
+static void xarray_node_rcu_free(struct rcu_head *head)
 {
-       struct radix_tree_node *node =
-               container_of(head, struct radix_tree_node, rcu_head);
+       struct xa_node *node =
+               container_of(head, struct xa_node, rcu_head);
        int i;
 
        /*
@@ -271,13 +270,13 @@ static void radix_tree_node_rcu_free(struct rcu_head *head)
         * can leave us with a non-NULL entry in the first slot, so clear
         * that here to make sure.
         */
-       for (i = 0; i < RADIX_TREE_MAX_TAGS; i++)
+       for (i = 0; i < XA_MAX_MARKS; i++)
                tag_clear(node, i, 0);
 
        node->slots[0] = NULL;
        node->count = 0;
 
-       kmem_cache_free(radix_tree_node_cachep, node);
+       kmem_cache_free(xarray_cachep, node);
 }
 
 #define XA_RCU_FREE    ((struct xarray *)1)
@@ -286,7 +285,7 @@ static void xa_node_free(struct xa_node *node)
 {
        XA_NODE_BUG_ON(node, !list_empty(&node->private_list));
        node->array = XA_RCU_FREE;
-       call_rcu(&node->rcu_head, radix_tree_node_rcu_free);
+       call_rcu(&node->rcu_head, xarray_node_rcu_free);
 }
 
 /*
@@ -302,7 +301,7 @@ static void xas_destroy(struct xa_state *xas)
        if (!node)
                return;
        XA_NODE_BUG_ON(node, !list_empty(&node->private_list));
-       kmem_cache_free(radix_tree_node_cachep, node);
+       kmem_cache_free(xarray_cachep, node);
        xas->xa_alloc = NULL;
 }
 
@@ -334,7 +333,7 @@ bool xas_nomem(struct xa_state *xas, gfp_t gfp)
        if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
                gfp |= __GFP_ACCOUNT;
 #endif
-       xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+       xas->xa_alloc = kmem_cache_alloc(xarray_cachep, gfp);
        if (!xas->xa_alloc)
                return false;
        XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list));
@@ -367,10 +366,10 @@ static bool __xas_nomem(struct xa_state *xas, gfp_t gfp)
 #endif
        if (gfpflags_allow_blocking(gfp)) {
                xas_unlock_type(xas, lock_type);
-               xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+               xas->xa_alloc = kmem_cache_alloc(xarray_cachep, gfp);
                xas_lock_type(xas, lock_type);
        } else {
-               xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+               xas->xa_alloc = kmem_cache_alloc(xarray_cachep, gfp);
        }
        if (!xas->xa_alloc)
                return false;
@@ -403,7 +402,7 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift)
                if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
                        gfp |= __GFP_ACCOUNT;
 #endif
-               node = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+               node = kmem_cache_alloc(xarray_cachep, gfp);
                if (!node) {
                        xas_set_err(xas, -ENOMEM);
                        return NULL;