Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xarray: Add definition of struct xarray

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 <willy@infradead.org>
Reviewed-by: Josef Bacik <jbacik@fb.com>

+181 -68
+8 -20
include/linux/radix-tree.h
··· 30 30 #include <linux/types.h> 31 31 #include <linux/xarray.h> 32 32 33 + /* Keep unconverted code working */ 34 + #define radix_tree_root xarray 35 + 33 36 /* 34 37 * The bottom two bits of the slot determine how the remaining bits in the 35 38 * slot are interpreted: ··· 95 92 unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; 96 93 }; 97 94 98 - /* The IDR tag is stored in the low bits of the GFP flags */ 95 + /* The IDR tag is stored in the low bits of xa_flags */ 99 96 #define ROOT_IS_IDR ((__force gfp_t)4) 100 - /* The top bits of gfp_mask are used to store the root tags */ 97 + /* The top bits of xa_flags are used to store the root tags */ 101 98 #define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT) 102 99 103 - struct radix_tree_root { 104 - spinlock_t xa_lock; 105 - gfp_t gfp_mask; 106 - struct radix_tree_node __rcu *rnode; 107 - }; 108 - 109 - #define RADIX_TREE_INIT(name, mask) { \ 110 - .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ 111 - .gfp_mask = (mask), \ 112 - .rnode = NULL, \ 113 - } 100 + #define RADIX_TREE_INIT(name, mask) XARRAY_INIT(name, mask) 114 101 115 102 #define RADIX_TREE(name, mask) \ 116 103 struct radix_tree_root name = RADIX_TREE_INIT(name, mask) 117 104 118 - #define INIT_RADIX_TREE(root, mask) \ 119 - do { \ 120 - spin_lock_init(&(root)->xa_lock); \ 121 - (root)->gfp_mask = (mask); \ 122 - (root)->rnode = NULL; \ 123 - } while (0) 105 + #define INIT_RADIX_TREE(root, mask) xa_init_flags(root, mask) 124 106 125 107 static inline bool radix_tree_empty(const struct radix_tree_root *root) 126 108 { 127 - return root->rnode == NULL; 109 + return root->xa_head == NULL; 128 110 } 129 111 130 112 /**
+70
include/linux/xarray.h
··· 10 10 */ 11 11 12 12 #include <linux/bug.h> 13 + #include <linux/compiler.h> 14 + #include <linux/kconfig.h> 13 15 #include <linux/spinlock.h> 14 16 #include <linux/types.h> 15 17 ··· 153 151 static inline bool xa_is_internal(const void *entry) 154 152 { 155 153 return ((unsigned long)entry & 3) == 2; 154 + } 155 + 156 + /** 157 + * struct xarray - The anchor of the XArray. 158 + * @xa_lock: Lock that protects the contents of the XArray. 159 + * 160 + * To use the xarray, define it statically or embed it in your data structure. 161 + * It is a very small data structure, so it does not usually make sense to 162 + * allocate it separately and keep a pointer to it in your data structure. 163 + * 164 + * You may use the xa_lock to protect your own data structures as well. 165 + */ 166 + /* 167 + * If all of the entries in the array are NULL, @xa_head is a NULL pointer. 168 + * If the only non-NULL entry in the array is at index 0, @xa_head is that 169 + * entry. If any other entry in the array is non-NULL, @xa_head points 170 + * to an @xa_node. 171 + */ 172 + struct xarray { 173 + spinlock_t xa_lock; 174 + /* private: The rest of the data structure is not to be used directly. */ 175 + gfp_t xa_flags; 176 + void __rcu * xa_head; 177 + }; 178 + 179 + #define XARRAY_INIT(name, flags) { \ 180 + .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ 181 + .xa_flags = flags, \ 182 + .xa_head = NULL, \ 183 + } 184 + 185 + /** 186 + * DEFINE_XARRAY_FLAGS() - Define an XArray with custom flags. 187 + * @name: A string that names your XArray. 188 + * @flags: XA_FLAG values. 189 + * 190 + * This is intended for file scope definitions of XArrays. It declares 191 + * and initialises an empty XArray with the chosen name and flags. It is 192 + * equivalent to calling xa_init_flags() on the array, but it does the 193 + * initialisation at compiletime instead of runtime. 194 + */ 195 + #define DEFINE_XARRAY_FLAGS(name, flags) \ 196 + struct xarray name = XARRAY_INIT(name, flags) 197 + 198 + /** 199 + * DEFINE_XARRAY() - Define an XArray. 200 + * @name: A string that names your XArray. 201 + * 202 + * This is intended for file scope definitions of XArrays. It declares 203 + * and initialises an empty XArray with the chosen name. It is equivalent 204 + * to calling xa_init() on the array, but it does the initialisation at 205 + * compiletime instead of runtime. 206 + */ 207 + #define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0) 208 + 209 + void xa_init_flags(struct xarray *, gfp_t flags); 210 + 211 + /** 212 + * xa_init() - Initialise an empty XArray. 213 + * @xa: XArray. 214 + * 215 + * An empty XArray is full of NULL entries. 216 + * 217 + * Context: Any context. 218 + */ 219 + static inline void xa_init(struct xarray *xa) 220 + { 221 + xa_init_flags(xa, 0); 156 222 } 157 223 158 224 #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock)
+1 -1
lib/Makefile
··· 18 18 KCOV_INSTRUMENT_dynamic_debug.o := n 19 19 20 20 lib-y := ctype.o string.o vsprintf.o cmdline.o \ 21 - rbtree.o radix-tree.o timerqueue.o\ 21 + rbtree.o radix-tree.o timerqueue.o xarray.o \ 22 22 idr.o int_sqrt.o extable.o \ 23 23 sha1.o chacha20.o irq_regs.o argv_split.o \ 24 24 flex_proportions.o ratelimit.o show_mem.o \
+2 -2
lib/idr.c
··· 39 39 unsigned int base = idr->idr_base; 40 40 unsigned int id = *nextid; 41 41 42 - if (WARN_ON_ONCE(!(idr->idr_rt.gfp_mask & ROOT_IS_IDR))) 43 - idr->idr_rt.gfp_mask |= IDR_RT_MARKER; 42 + if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR))) 43 + idr->idr_rt.xa_flags |= IDR_RT_MARKER; 44 44 45 45 id = (id < base) ? 0 : id - base; 46 46 radix_tree_iter_init(&iter, id);
+37 -38
lib/radix-tree.c
··· 124 124 125 125 static inline gfp_t root_gfp_mask(const struct radix_tree_root *root) 126 126 { 127 - return root->gfp_mask & (__GFP_BITS_MASK & ~GFP_ZONEMASK); 127 + return root->xa_flags & (__GFP_BITS_MASK & ~GFP_ZONEMASK); 128 128 } 129 129 130 130 static inline void tag_set(struct radix_tree_node *node, unsigned int tag, ··· 147 147 148 148 static inline void root_tag_set(struct radix_tree_root *root, unsigned tag) 149 149 { 150 - root->gfp_mask |= (__force gfp_t)(1 << (tag + ROOT_TAG_SHIFT)); 150 + root->xa_flags |= (__force gfp_t)(1 << (tag + ROOT_TAG_SHIFT)); 151 151 } 152 152 153 153 static inline void root_tag_clear(struct radix_tree_root *root, unsigned tag) 154 154 { 155 - root->gfp_mask &= (__force gfp_t)~(1 << (tag + ROOT_TAG_SHIFT)); 155 + root->xa_flags &= (__force gfp_t)~(1 << (tag + ROOT_TAG_SHIFT)); 156 156 } 157 157 158 158 static inline void root_tag_clear_all(struct radix_tree_root *root) 159 159 { 160 - root->gfp_mask &= (1 << ROOT_TAG_SHIFT) - 1; 160 + root->xa_flags &= (__force gfp_t)((1 << ROOT_TAG_SHIFT) - 1); 161 161 } 162 162 163 163 static inline int root_tag_get(const struct radix_tree_root *root, unsigned tag) 164 164 { 165 - return (__force int)root->gfp_mask & (1 << (tag + ROOT_TAG_SHIFT)); 165 + return (__force int)root->xa_flags & (1 << (tag + ROOT_TAG_SHIFT)); 166 166 } 167 167 168 168 static inline unsigned root_tags_get(const struct radix_tree_root *root) 169 169 { 170 - return (__force unsigned)root->gfp_mask >> ROOT_TAG_SHIFT; 170 + return (__force unsigned)root->xa_flags >> ROOT_TAG_SHIFT; 171 171 } 172 172 173 173 static inline bool is_idr(const struct radix_tree_root *root) 174 174 { 175 - return !!(root->gfp_mask & ROOT_IS_IDR); 175 + return !!(root->xa_flags & ROOT_IS_IDR); 176 176 } 177 177 178 178 /* ··· 291 291 /* For debug */ 292 292 static void radix_tree_dump(struct radix_tree_root *root) 293 293 { 294 - pr_debug("radix root: %p rnode %p tags %x\n", 295 - root, root->rnode, 296 - root->gfp_mask >> ROOT_TAG_SHIFT); 297 - if (!radix_tree_is_internal_node(root->rnode)) 294 + pr_debug("radix root: %p xa_head %p tags %x\n", 295 + root, root->xa_head, 296 + root->xa_flags >> ROOT_TAG_SHIFT); 297 + if (!radix_tree_is_internal_node(root->xa_head)) 298 298 return; 299 - dump_node(entry_to_node(root->rnode), 0); 299 + dump_node(entry_to_node(root->xa_head), 0); 300 300 } 301 301 302 302 static void dump_ida_node(void *entry, unsigned long index) ··· 340 340 static void ida_dump(struct ida *ida) 341 341 { 342 342 struct radix_tree_root *root = &ida->ida_rt; 343 - pr_debug("ida: %p node %p free %d\n", ida, root->rnode, 344 - root->gfp_mask >> ROOT_TAG_SHIFT); 345 - dump_ida_node(root->rnode, 0); 343 + pr_debug("ida: %p node %p free %d\n", ida, root->xa_head, 344 + root->xa_flags >> ROOT_TAG_SHIFT); 345 + dump_ida_node(root->xa_head, 0); 346 346 } 347 347 #endif 348 348 ··· 576 576 static unsigned radix_tree_load_root(const struct radix_tree_root *root, 577 577 struct radix_tree_node **nodep, unsigned long *maxindex) 578 578 { 579 - struct radix_tree_node *node = rcu_dereference_raw(root->rnode); 579 + struct radix_tree_node *node = rcu_dereference_raw(root->xa_head); 580 580 581 581 *nodep = node; 582 582 ··· 605 605 while (index > shift_maxindex(maxshift)) 606 606 maxshift += RADIX_TREE_MAP_SHIFT; 607 607 608 - entry = rcu_dereference_raw(root->rnode); 608 + entry = rcu_dereference_raw(root->xa_head); 609 609 if (!entry && (!is_idr(root) || root_tag_get(root, IDR_FREE))) 610 610 goto out; 611 611 ··· 633 633 if (radix_tree_is_internal_node(entry)) { 634 634 entry_to_node(entry)->parent = node; 635 635 } else if (xa_is_value(entry)) { 636 - /* Moving an exceptional root->rnode to a node */ 636 + /* Moving an exceptional root->xa_head to a node */ 637 637 node->exceptional = 1; 638 638 } 639 639 /* ··· 642 642 */ 643 643 node->slots[0] = (void __rcu *)entry; 644 644 entry = node_to_entry(node); 645 - rcu_assign_pointer(root->rnode, entry); 645 + rcu_assign_pointer(root->xa_head, entry); 646 646 shift += RADIX_TREE_MAP_SHIFT; 647 647 } while (shift <= maxshift); 648 648 out: ··· 659 659 bool shrunk = false; 660 660 661 661 for (;;) { 662 - struct radix_tree_node *node = rcu_dereference_raw(root->rnode); 662 + struct radix_tree_node *node = rcu_dereference_raw(root->xa_head); 663 663 struct radix_tree_node *child; 664 664 665 665 if (!radix_tree_is_internal_node(node)) ··· 695 695 * moving the node from one part of the tree to another: if it 696 696 * was safe to dereference the old pointer to it 697 697 * (node->slots[0]), it will be safe to dereference the new 698 - * one (root->rnode) as far as dependent read barriers go. 698 + * one (root->xa_head) as far as dependent read barriers go. 699 699 */ 700 - root->rnode = (void __rcu *)child; 700 + root->xa_head = (void __rcu *)child; 701 701 if (is_idr(root) && !tag_get(node, IDR_FREE, 0)) 702 702 root_tag_clear(root, IDR_FREE); 703 703 ··· 745 745 746 746 if (node->count) { 747 747 if (node_to_entry(node) == 748 - rcu_dereference_raw(root->rnode)) 749 - deleted |= radix_tree_shrink(root, 750 - update_node); 748 + rcu_dereference_raw(root->xa_head)) 749 + deleted |= radix_tree_shrink(root, update_node); 751 750 return deleted; 752 751 } 753 752 ··· 761 762 */ 762 763 if (!is_idr(root)) 763 764 root_tag_clear_all(root); 764 - root->rnode = NULL; 765 + root->xa_head = NULL; 765 766 } 766 767 767 768 WARN_ON_ONCE(!list_empty(&node->private_list)); ··· 786 787 * at position @index in the radix tree @root. 787 788 * 788 789 * Until there is more than one item in the tree, no nodes are 789 - * allocated and @root->rnode is used as a direct slot instead of 790 + * allocated and @root->xa_head is used as a direct slot instead of 790 791 * pointing to a node, in which case *@nodep will be NULL. 791 792 * 792 793 * Returns -ENOMEM, or 0 for success. ··· 796 797 void __rcu ***slotp) 797 798 { 798 799 struct radix_tree_node *node = NULL, *child; 799 - void __rcu **slot = (void __rcu **)&root->rnode; 800 + void __rcu **slot = (void __rcu **)&root->xa_head; 800 801 unsigned long maxindex; 801 802 unsigned int shift, offset = 0; 802 803 unsigned long max = index | ((1UL << order) - 1); ··· 812 813 if (error < 0) 813 814 return error; 814 815 shift = error; 815 - child = rcu_dereference_raw(root->rnode); 816 + child = rcu_dereference_raw(root->xa_head); 816 817 } 817 818 818 819 while (shift > order) { ··· 1003 1004 * tree @root. 1004 1005 * 1005 1006 * Until there is more than one item in the tree, no nodes are 1006 - * allocated and @root->rnode is used as a direct slot instead of 1007 + * allocated and @root->xa_head is used as a direct slot instead of 1007 1008 * pointing to a node, in which case *@nodep will be NULL. 1008 1009 */ 1009 1010 void *__radix_tree_lookup(const struct radix_tree_root *root, ··· 1016 1017 1017 1018 restart: 1018 1019 parent = NULL; 1019 - slot = (void __rcu **)&root->rnode; 1020 + slot = (void __rcu **)&root->xa_head; 1020 1021 radix_tree_load_root(root, &node, &maxindex); 1021 1022 if (index > maxindex) 1022 1023 return NULL; ··· 1167 1168 /* 1168 1169 * This function supports replacing exceptional entries and 1169 1170 * deleting entries, but that needs accounting against the 1170 - * node unless the slot is root->rnode. 1171 + * node unless the slot is root->xa_head. 1171 1172 */ 1172 - WARN_ON_ONCE(!node && (slot != (void __rcu **)&root->rnode) && 1173 + WARN_ON_ONCE(!node && (slot != (void __rcu **)&root->xa_head) && 1173 1174 (count || exceptional)); 1174 1175 replace_slot(slot, item, node, count, exceptional); 1175 1176 ··· 1721 1722 iter->tags = 1; 1722 1723 iter->node = NULL; 1723 1724 __set_iter_shift(iter, 0); 1724 - return (void __rcu **)&root->rnode; 1725 + return (void __rcu **)&root->xa_head; 1725 1726 } 1726 1727 1727 1728 do { ··· 2108 2109 unsigned long max) 2109 2110 { 2110 2111 struct radix_tree_node *node = NULL, *child; 2111 - void __rcu **slot = (void __rcu **)&root->rnode; 2112 + void __rcu **slot = (void __rcu **)&root->xa_head; 2112 2113 unsigned long maxindex, start = iter->next_index; 2113 2114 unsigned int shift, offset = 0; 2114 2115 ··· 2124 2125 if (error < 0) 2125 2126 return ERR_PTR(error); 2126 2127 shift = error; 2127 - child = rcu_dereference_raw(root->rnode); 2128 + child = rcu_dereference_raw(root->xa_head); 2128 2129 } 2129 2130 if (start == 0 && shift == 0) 2130 2131 shift = RADIX_TREE_MAP_SHIFT; ··· 2189 2190 */ 2190 2191 void idr_destroy(struct idr *idr) 2191 2192 { 2192 - struct radix_tree_node *node = rcu_dereference_raw(idr->idr_rt.rnode); 2193 + struct radix_tree_node *node = rcu_dereference_raw(idr->idr_rt.xa_head); 2193 2194 if (radix_tree_is_internal_node(node)) 2194 2195 radix_tree_free_nodes(node); 2195 - idr->idr_rt.rnode = NULL; 2196 + idr->idr_rt.xa_head = NULL; 2196 2197 root_tag_set(&idr->idr_rt, IDR_FREE); 2197 2198 } 2198 2199 EXPORT_SYMBOL(idr_destroy);
+44
lib/xarray.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * XArray implementation 4 + * Copyright (c) 2017 Microsoft Corporation 5 + * Author: Matthew Wilcox <willy@infradead.org> 6 + */ 7 + 8 + #include <linux/export.h> 9 + #include <linux/xarray.h> 10 + 11 + /* 12 + * Coding conventions in this file: 13 + * 14 + * @xa is used to refer to the entire xarray. 15 + * @xas is the 'xarray operation state'. It may be either a pointer to 16 + * an xa_state, or an xa_state stored on the stack. This is an unfortunate 17 + * ambiguity. 18 + * @index is the index of the entry being operated on 19 + * @mark is an xa_mark_t; a small number indicating one of the mark bits. 20 + * @node refers to an xa_node; usually the primary one being operated on by 21 + * this function. 22 + * @offset is the index into the slots array inside an xa_node. 23 + * @parent refers to the @xa_node closer to the head than @node. 24 + * @entry refers to something stored in a slot in the xarray 25 + */ 26 + 27 + /** 28 + * xa_init_flags() - Initialise an empty XArray with flags. 29 + * @xa: XArray. 30 + * @flags: XA_FLAG values. 31 + * 32 + * If you need to initialise an XArray with special flags (eg you need 33 + * to take the lock from interrupt context), use this function instead 34 + * of xa_init(). 35 + * 36 + * Context: Any context. 37 + */ 38 + void xa_init_flags(struct xarray *xa, gfp_t flags) 39 + { 40 + spin_lock_init(&xa->xa_lock); 41 + xa->xa_flags = flags; 42 + xa->xa_head = NULL; 43 + } 44 + EXPORT_SYMBOL(xa_init_flags);
+4 -1
tools/testing/radix-tree/Makefile
··· 5 5 LDFLAGS += -fsanitize=address -fsanitize=undefined 6 6 LDLIBS+= -lpthread -lurcu 7 7 TARGETS = main idr-test multiorder 8 - CORE_OFILES := radix-tree.o idr.o linux.o test.o find_bit.o 8 + CORE_OFILES := xarray.o radix-tree.o idr.o linux.o test.o find_bit.o 9 9 OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression3.o \ 10 10 tag_check.o multiorder.o idr-test.o iteration_check.o benchmark.o 11 11 ··· 35 35 $(OFILES): Makefile *.h */*.h generated/map-shift.h \ 36 36 ../../include/linux/*.h \ 37 37 ../../include/asm/*.h \ 38 + ../../../include/linux/xarray.h \ 38 39 ../../../include/linux/radix-tree.h \ 39 40 ../../../include/linux/idr.h 40 41 ··· 44 43 45 44 idr.c: ../../../lib/idr.c 46 45 sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@ 46 + 47 + xarray.o: ../../../lib/xarray.c 47 48 48 49 generated/map-shift.h: 49 50 @if ! grep -qws $(SHIFT) generated/map-shift.h; then \
+1
tools/testing/radix-tree/linux/bug.h
··· 1 + #include <stdio.h> 1 2 #include "asm/bug.h"
+1
tools/testing/radix-tree/linux/kconfig.h
··· 1 + #include "../../../../include/linux/kconfig.h"
+3 -3
tools/testing/radix-tree/multiorder.c
··· 192 192 193 193 assert(item_insert_order(&tree, 0, order) == 0); 194 194 195 - node = tree.rnode; 195 + node = tree.xa_head; 196 196 197 197 assert(item_insert(&tree, index) == 0); 198 - assert(node != tree.rnode); 198 + assert(node != tree.xa_head); 199 199 200 200 assert(item_delete(&tree, index) != 0); 201 - assert(node == tree.rnode); 201 + assert(node == tree.xa_head); 202 202 203 203 for (i = 0; i < max; i++) { 204 204 struct item *item = item_lookup(&tree, i);
+3 -3
tools/testing/radix-tree/test.c
··· 281 281 282 282 void verify_tag_consistency(struct radix_tree_root *root, unsigned int tag) 283 283 { 284 - struct radix_tree_node *node = root->rnode; 284 + struct radix_tree_node *node = root->xa_head; 285 285 if (!radix_tree_is_internal_node(node)) 286 286 return; 287 287 verify_node(node, tag, !!root_tag_get(root, tag)); ··· 311 311 } 312 312 } 313 313 assert(radix_tree_gang_lookup(root, (void **)items, 0, 32) == 0); 314 - assert(root->rnode == NULL); 314 + assert(root->xa_head == NULL); 315 315 } 316 316 317 317 void tree_verify_min_height(struct radix_tree_root *root, int maxindex) 318 318 { 319 319 unsigned shift; 320 - struct radix_tree_node *node = root->rnode; 320 + struct radix_tree_node *node = root->xa_head; 321 321 if (!radix_tree_is_internal_node(node)) { 322 322 assert(maxindex == 0); 323 323 return;
+7
tools/testing/radix-tree/xarray.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * xarray.c: Userspace shim for XArray test-suite 4 + * Copyright (c) 2018 Matthew Wilcox <willy@infradead.org> 5 + */ 6 + 7 + #include "../../../lib/xarray.c"