Re: [PATCH v6 05/99] xarray: Add definition of struct xarray
Mathhew, Just a minor question. On Wed, 2018-01-17 at 12:20 -0800, Matthew Wilcox wrote: > This is a direct replacement for struct radix_tree_root. Some of the > struct members have changed name; convert those, and use a #define so > that radix_tree users continue to work without change. > > Signed-off-by: Matthew Wilcox> --- a/include/linux/xarray.h > +++ b/include/linux/xarray.h > @@ -10,6 +10,8 @@ > */ > > #include > +#include > +#include The top Makefile includes linux/kconfig.h globally. (See the odd USERINCLUDE variable, which is actually part of the LINUXINCLUDE variable, but split off to make things confusing.) Why do you need to include linux/kconfig.h here? > #include > #include Thanks, Paul Bolle
Re: [PATCH v6 05/99] xarray: Add definition of struct xarray
Mathhew, Just a minor question. On Wed, 2018-01-17 at 12:20 -0800, Matthew Wilcox wrote: > This is a direct replacement for struct radix_tree_root. Some of the > struct members have changed name; convert those, and use a #define so > that radix_tree users continue to work without change. > > Signed-off-by: Matthew Wilcox > --- a/include/linux/xarray.h > +++ b/include/linux/xarray.h > @@ -10,6 +10,8 @@ > */ > > #include > +#include > +#include The top Makefile includes linux/kconfig.h globally. (See the odd USERINCLUDE variable, which is actually part of the LINUXINCLUDE variable, but split off to make things confusing.) Why do you need to include linux/kconfig.h here? > #include > #include Thanks, Paul Bolle
[PATCH v6 05/99] xarray: Add definition of struct xarray
From: Matthew WilcoxThis is a direct replacement for struct radix_tree_root. Some of the struct members have changed name; convert those, and use a #define so that radix_tree users continue to work without change. Signed-off-by: Matthew Wilcox --- include/linux/radix-tree.h | 33 -- include/linux/xarray.h | 59 + lib/Makefile | 2 +- lib/idr.c| 4 +- lib/radix-tree.c | 75 lib/xarray.c | 42 ++ tools/include/linux/spinlock.h | 1 + tools/testing/radix-tree/.gitignore | 1 + tools/testing/radix-tree/Makefile| 8 +++- tools/testing/radix-tree/linux/bug.h | 1 + tools/testing/radix-tree/linux/kconfig.h | 1 + tools/testing/radix-tree/linux/xarray.h | 2 + tools/testing/radix-tree/multiorder.c| 6 +-- tools/testing/radix-tree/test.c | 6 +-- 14 files changed, 168 insertions(+), 73 deletions(-) create mode 100644 lib/xarray.c create mode 100644 tools/testing/radix-tree/linux/kconfig.h create mode 100644 tools/testing/radix-tree/linux/xarray.h diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 87f35fe00e55..c8a33e9e9a3c 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -30,6 +30,9 @@ #include #include +/* Keep unconverted code working */ +#define radix_tree_rootxarray + /* * The bottom two bits of the slot determine how the remaining bits in the * slot are interpreted: @@ -59,10 +62,7 @@ static inline bool radix_tree_is_internal_node(void *ptr) #define RADIX_TREE_MAX_TAGS 3 -#ifndef RADIX_TREE_MAP_SHIFT -#define RADIX_TREE_MAP_SHIFT (CONFIG_BASE_SMALL ? 4 : 6) -#endif - +#define RADIX_TREE_MAP_SHIFT XA_CHUNK_SHIFT #define RADIX_TREE_MAP_SIZE(1UL << RADIX_TREE_MAP_SHIFT) #define RADIX_TREE_MAP_MASK(RADIX_TREE_MAP_SIZE-1) @@ -95,36 +95,21 @@ struct radix_tree_node { unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; }; -/* The IDR tag is stored in the low bits of the GFP flags */ +/* The IDR tag is stored in the low bits of xa_flags */ #define ROOT_IS_IDR((__force gfp_t)4) -/* The top bits of gfp_mask are used to store the root tags */ +/* The top bits of xa_flags are used to store the root tags */ #define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT) -struct radix_tree_root { - spinlock_t xa_lock; - gfp_t gfp_mask; - struct radix_tree_node __rcu *rnode; -}; - -#define RADIX_TREE_INIT(name, mask){ \ - .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ - .gfp_mask = (mask), \ - .rnode = NULL, \ -} +#define RADIX_TREE_INIT(name, mask)XARRAY_INIT_FLAGS(name, mask) #define RADIX_TREE(name, mask) \ struct radix_tree_root name = RADIX_TREE_INIT(name, mask) -#define INIT_RADIX_TREE(root, mask)\ -do { \ - spin_lock_init(&(root)->xa_lock); \ - (root)->gfp_mask = (mask); \ - (root)->rnode = NULL; \ -} while (0) +#define INIT_RADIX_TREE(root, mask) xa_init_flags(root, mask) static inline bool radix_tree_empty(const struct radix_tree_root *root) { - return root->rnode == NULL; + return root->xa_head == NULL; } /** diff --git a/include/linux/xarray.h b/include/linux/xarray.h index c308152fde7f..3d2f1fafb7ec 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -10,6 +10,8 @@ */ #include +#include +#include #include #include @@ -99,6 +101,63 @@ static inline bool xa_is_internal(const void *entry) return ((unsigned long)entry & 3) == 2; } +/** + * struct xarray - The anchor of the XArray. + * @xa_lock: Lock that protects the contents of the XArray. + * + * To use the xarray, define it statically or embed it in your data structure. + * It is a very small data structure, so it does not usually make sense to + * allocate it separately and keep a pointer to it in your data structure. + * + * You may use the xa_lock to protect your own data structures as well. + */ +/* + * If all of the entries in the array are NULL, @xa_head is a NULL pointer. + * If the only non-NULL entry in the array is at index 0, @xa_head is that + * entry. If any other entry in the array is non-NULL, @xa_head points + * to an @xa_node. + */ +struct xarray { + spinlock_t xa_lock; +/* private: The rest of the data structure is not to be used directly. */ + gfp_t xa_flags; +
[PATCH v6 05/99] xarray: Add definition of struct xarray
From: Matthew Wilcox This is a direct replacement for struct radix_tree_root. Some of the struct members have changed name; convert those, and use a #define so that radix_tree users continue to work without change. Signed-off-by: Matthew Wilcox --- include/linux/radix-tree.h | 33 -- include/linux/xarray.h | 59 + lib/Makefile | 2 +- lib/idr.c| 4 +- lib/radix-tree.c | 75 lib/xarray.c | 42 ++ tools/include/linux/spinlock.h | 1 + tools/testing/radix-tree/.gitignore | 1 + tools/testing/radix-tree/Makefile| 8 +++- tools/testing/radix-tree/linux/bug.h | 1 + tools/testing/radix-tree/linux/kconfig.h | 1 + tools/testing/radix-tree/linux/xarray.h | 2 + tools/testing/radix-tree/multiorder.c| 6 +-- tools/testing/radix-tree/test.c | 6 +-- 14 files changed, 168 insertions(+), 73 deletions(-) create mode 100644 lib/xarray.c create mode 100644 tools/testing/radix-tree/linux/kconfig.h create mode 100644 tools/testing/radix-tree/linux/xarray.h diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 87f35fe00e55..c8a33e9e9a3c 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -30,6 +30,9 @@ #include #include +/* Keep unconverted code working */ +#define radix_tree_rootxarray + /* * The bottom two bits of the slot determine how the remaining bits in the * slot are interpreted: @@ -59,10 +62,7 @@ static inline bool radix_tree_is_internal_node(void *ptr) #define RADIX_TREE_MAX_TAGS 3 -#ifndef RADIX_TREE_MAP_SHIFT -#define RADIX_TREE_MAP_SHIFT (CONFIG_BASE_SMALL ? 4 : 6) -#endif - +#define RADIX_TREE_MAP_SHIFT XA_CHUNK_SHIFT #define RADIX_TREE_MAP_SIZE(1UL << RADIX_TREE_MAP_SHIFT) #define RADIX_TREE_MAP_MASK(RADIX_TREE_MAP_SIZE-1) @@ -95,36 +95,21 @@ struct radix_tree_node { unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; }; -/* The IDR tag is stored in the low bits of the GFP flags */ +/* The IDR tag is stored in the low bits of xa_flags */ #define ROOT_IS_IDR((__force gfp_t)4) -/* The top bits of gfp_mask are used to store the root tags */ +/* The top bits of xa_flags are used to store the root tags */ #define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT) -struct radix_tree_root { - spinlock_t xa_lock; - gfp_t gfp_mask; - struct radix_tree_node __rcu *rnode; -}; - -#define RADIX_TREE_INIT(name, mask){ \ - .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ - .gfp_mask = (mask), \ - .rnode = NULL, \ -} +#define RADIX_TREE_INIT(name, mask)XARRAY_INIT_FLAGS(name, mask) #define RADIX_TREE(name, mask) \ struct radix_tree_root name = RADIX_TREE_INIT(name, mask) -#define INIT_RADIX_TREE(root, mask)\ -do { \ - spin_lock_init(&(root)->xa_lock); \ - (root)->gfp_mask = (mask); \ - (root)->rnode = NULL; \ -} while (0) +#define INIT_RADIX_TREE(root, mask) xa_init_flags(root, mask) static inline bool radix_tree_empty(const struct radix_tree_root *root) { - return root->rnode == NULL; + return root->xa_head == NULL; } /** diff --git a/include/linux/xarray.h b/include/linux/xarray.h index c308152fde7f..3d2f1fafb7ec 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -10,6 +10,8 @@ */ #include +#include +#include #include #include @@ -99,6 +101,63 @@ static inline bool xa_is_internal(const void *entry) return ((unsigned long)entry & 3) == 2; } +/** + * struct xarray - The anchor of the XArray. + * @xa_lock: Lock that protects the contents of the XArray. + * + * To use the xarray, define it statically or embed it in your data structure. + * It is a very small data structure, so it does not usually make sense to + * allocate it separately and keep a pointer to it in your data structure. + * + * You may use the xa_lock to protect your own data structures as well. + */ +/* + * If all of the entries in the array are NULL, @xa_head is a NULL pointer. + * If the only non-NULL entry in the array is at index 0, @xa_head is that + * entry. If any other entry in the array is non-NULL, @xa_head points + * to an @xa_node. + */ +struct xarray { + spinlock_t xa_lock; +/* private: The rest of the data structure is not to be used directly. */ + gfp_t xa_flags; + void __rcu *xa_head; +}; + +#define