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.
Unified · Split
| @@ -30,6 +30,9 @@ · 29 unmodified lines | ||
| 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: |
| @@ -92,36 +95,21 @@ struct radix_tree_node { · 56 unmodified lines | ||
| 92 | 95 | unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; |
| 93 | 96 | }; |
| 94 | 97 | |
| 95 | −/* The IDR tag is stored in the low bits of the GFP flags */ | |
| 98 | +/* The IDR tag is stored in the low bits of xa_flags */ | |
| 96 | 99 | #define ROOT_IS_IDR ((__force gfp_t)4) |
| 97 | −/* The top bits of gfp_mask are used to store the root tags */ | |
| 100 | +/* The top bits of xa_flags are used to store the root tags */ | |
| 98 | 101 | #define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT) |
| 99 | 102 | |
| 100 | −struct radix_tree_root { | |
| 101 | − spinlock_t xa_lock; | |
| 102 | − gfp_t gfp_mask; | |
| 103 | − struct radix_tree_node __rcu *rnode; | |
| 104 | −}; | |
| 105 | − | |
| 106 | −#define RADIX_TREE_INIT(name, mask) { \ | |
| 107 | − .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ | |
| 108 | − .gfp_mask = (mask), \ | |
| 109 | − .rnode = NULL, \ | |
| 110 | −} | |
| 103 | +#define RADIX_TREE_INIT(name, mask) XARRAY_INIT(name, mask) | |
| 111 | 104 | |
| 112 | 105 | #define RADIX_TREE(name, mask) \ |
| 113 | 106 | struct radix_tree_root name = RADIX_TREE_INIT(name, mask) |
| 114 | 107 | |
| 115 | −#define INIT_RADIX_TREE(root, mask) \ | |
| 116 | −do { \ | |
| 117 | − spin_lock_init(&(root)->xa_lock); \ | |
| 118 | − (root)->gfp_mask = (mask); \ | |
| 119 | − (root)->rnode = NULL; \ | |
| 120 | −} while (0) | |
| 108 | +#define INIT_RADIX_TREE(root, mask) xa_init_flags(root, mask) | |
| 121 | 109 | |
| 122 | 110 | static inline bool radix_tree_empty(const struct radix_tree_root *root) |
| 123 | 111 | { |
| 124 | − return root->rnode == NULL; | |
| 112 | + return root->xa_head == NULL; | |
| 125 | 113 | } |
| 126 | 114 | |
| 127 | 115 | /** |
| @@ -10,6 +10,8 @@ · 9 unmodified lines | ||
| 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,6 +155,74 @@ static inline bool xa_is_internal(const void *entry) · 137 unmodified lines | ||
| 153 | 155 | return ((unsigned long)entry & 3) == 2; |
| 154 | 156 | } |
| 155 | 157 | |
| 158 | +/** | |
| 159 | + * struct xarray - The anchor of the XArray. | |
| 160 | + * @xa_lock: Lock that protects the contents of the XArray. | |
| 161 | + * | |
| 162 | + * To use the xarray, define it statically or embed it in your data structure. | |
| 163 | + * It is a very small data structure, so it does not usually make sense to | |
| 164 | + * allocate it separately and keep a pointer to it in your data structure. | |
| 165 | + * | |
| 166 | + * You may use the xa_lock to protect your own data structures as well. | |
| 167 | + */ | |
| 168 | +/* | |
| 169 | + * If all of the entries in the array are NULL, @xa_head is a NULL pointer. | |
| 170 | + * If the only non-NULL entry in the array is at index 0, @xa_head is that | |
| 171 | + * entry. If any other entry in the array is non-NULL, @xa_head points | |
| 172 | + * to an @xa_node. | |
| 173 | + */ | |
| 174 | +struct xarray { | |
| 175 | + spinlock_t xa_lock; | |
| 176 | +/* private: The rest of the data structure is not to be used directly. */ | |
| 177 | + gfp_t xa_flags; | |
| 178 | + void __rcu * xa_head; | |
| 179 | +}; | |
| 180 | + | |
| 181 | +#define XARRAY_INIT(name, flags) { \ | |
| 182 | + .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ | |
| 183 | + .xa_flags = flags, \ | |
| 184 | + .xa_head = NULL, \ | |
| 185 | +} | |
| 186 | + | |
| 187 | +/** | |
| 188 | + * DEFINE_XARRAY_FLAGS() - Define an XArray with custom flags. | |
| 189 | + * @name: A string that names your XArray. | |
| 190 | + * @flags: XA_FLAG values. | |
| 191 | + * | |
| 192 | + * This is intended for file scope definitions of XArrays. It declares | |
| 193 | + * and initialises an empty XArray with the chosen name and flags. It is | |
| 194 | + * equivalent to calling xa_init_flags() on the array, but it does the | |
| 195 | + * initialisation at compiletime instead of runtime. | |
| 196 | + */ | |
| 197 | +#define DEFINE_XARRAY_FLAGS(name, flags) \ | |
| 198 | + struct xarray name = XARRAY_INIT(name, flags) | |
| 199 | + | |
| 200 | +/** | |
| 201 | + * DEFINE_XARRAY() - Define an XArray. | |
| 202 | + * @name: A string that names your XArray. | |
| 203 | + * | |
| 204 | + * This is intended for file scope definitions of XArrays. It declares | |
| 205 | + * and initialises an empty XArray with the chosen name. It is equivalent | |
| 206 | + * to calling xa_init() on the array, but it does the initialisation at | |
| 207 | + * compiletime instead of runtime. | |
| 208 | + */ | |
| 209 | +#define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0) | |
| 210 | + | |
| 211 | +void xa_init_flags(struct xarray *, gfp_t flags); | |
| 212 | + | |
| 213 | +/** | |
| 214 | + * xa_init() - Initialise an empty XArray. | |
| 215 | + * @xa: XArray. | |
| 216 | + * | |
| 217 | + * An empty XArray is full of NULL entries. | |
| 218 | + * | |
| 219 | + * Context: Any context. | |
| 220 | + */ | |
| 221 | +static inline void xa_init(struct xarray *xa) | |
| 222 | +{ | |
| 223 | + xa_init_flags(xa, 0); | |
| 224 | +} | |
| 225 | + | |
| 156 | 226 | #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) |
| 157 | 227 | #define xa_lock(xa) spin_lock(&(xa)->xa_lock) |
| 158 | 228 | #define xa_unlock(xa) spin_unlock(&(xa)->xa_lock) |
| @@ -18,7 +18,7 @@ KCOV_INSTRUMENT_debugobjects.o := n · 17 unmodified lines | ||
| 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 \ |
| @@ -39,8 +39,8 @@ int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid, · 38 unmodified lines | ||
| 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); |
| @@ -124,7 +124,7 @@ static unsigned int radix_tree_descend(const struct radix_tree_node *parent, · 123 unmodified lines | ||
| 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,32 +147,32 @@ static inline int tag_get(const struct radix_tree_node *node, unsigned int tag, · 16 unmodified lines | ||
| 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,12 +291,12 @@ static void dump_node(struct radix_tree_node *node, unsigned long index) · 112 unmodified lines | ||
| 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,9 +340,9 @@ static void dump_ida_node(void *entry, unsigned long index) · 37 unmodified lines | ||
| 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,7 +576,7 @@ int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order) · 227 unmodified lines | ||
| 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,7 +605,7 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp, · 22 unmodified lines | ||
| 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,7 +633,7 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp, · 21 unmodified lines | ||
| 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,7 +642,7 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp, · 2 unmodified lines | ||
| 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,7 +659,7 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root, · 10 unmodified lines | ||
| 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,9 +695,9 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root, · 29 unmodified lines | ||
| 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,9 +745,8 @@ static bool delete_node(struct radix_tree_root *root, · 41 unmodified lines | ||
| 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 | |
| @@ -762,7 +761,7 @@ static bool delete_node(struct radix_tree_root *root, · 8 unmodified lines | ||
| 762 | 761 | */ |
| 763 | 762 | if (!is_idr(root)) |
| 764 | 763 | root_tag_clear_all(root); |
| 765 | − root->rnode = NULL; | |
| 764 | + root->xa_head = NULL; | |
| 766 | 765 | } |
| 767 | 766 | |
| 768 | 767 | WARN_ON_ONCE(!list_empty(&node->private_list)); |
| @@ -787,7 +786,7 @@ static bool delete_node(struct radix_tree_root *root, · 18 unmodified lines | ||
| 787 | 786 | * at position @index in the radix tree @root. |
| 788 | 787 | * |
| 789 | 788 | * Until there is more than one item in the tree, no nodes are |
| 790 | − * allocated and @root->rnode is used as a direct slot instead of | |
| 789 | + * allocated and @root->xa_head is used as a direct slot instead of | |
| 791 | 790 | * pointing to a node, in which case *@nodep will be NULL. |
| 792 | 791 | * |
| 793 | 792 | * Returns -ENOMEM, or 0 for success. |
| @@ -797,7 +796,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index, · 3 unmodified lines | ||
| 797 | 796 | void __rcu ***slotp) |
| 798 | 797 | { |
| 799 | 798 | struct radix_tree_node *node = NULL, *child; |
| 800 | − void __rcu **slot = (void __rcu **)&root->rnode; | |
| 799 | + void __rcu **slot = (void __rcu **)&root->xa_head; | |
| 801 | 800 | unsigned long maxindex; |
| 802 | 801 | unsigned int shift, offset = 0; |
| 803 | 802 | unsigned long max = index | ((1UL << order) - 1); |
| @@ -813,7 +812,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index, · 9 unmodified lines | ||
| 813 | 812 | if (error < 0) |
| 814 | 813 | return error; |
| 815 | 814 | shift = error; |
| 816 | − child = rcu_dereference_raw(root->rnode); | |
| 815 | + child = rcu_dereference_raw(root->xa_head); | |
| 817 | 816 | } |
| 818 | 817 | |
| 819 | 818 | while (shift > order) { |
| @@ -1004,7 +1003,7 @@ EXPORT_SYMBOL(__radix_tree_insert); · 184 unmodified lines | ||
| 1004 | 1003 | * tree @root. |
| 1005 | 1004 | * |
| 1006 | 1005 | * Until there is more than one item in the tree, no nodes are |
| 1007 | − * allocated and @root->rnode is used as a direct slot instead of | |
| 1006 | + * allocated and @root->xa_head is used as a direct slot instead of | |
| 1008 | 1007 | * pointing to a node, in which case *@nodep will be NULL. |
| 1009 | 1008 | */ |
| 1010 | 1009 | void *__radix_tree_lookup(const struct radix_tree_root *root, |
| @@ -1017,7 +1016,7 @@ void *__radix_tree_lookup(const struct radix_tree_root *root, · 6 unmodified lines | ||
| 1017 | 1016 | |
| 1018 | 1017 | restart: |
| 1019 | 1018 | parent = NULL; |
| 1020 | − slot = (void __rcu **)&root->rnode; | |
| 1019 | + slot = (void __rcu **)&root->xa_head; | |
| 1021 | 1020 | radix_tree_load_root(root, &node, &maxindex); |
| 1022 | 1021 | if (index > maxindex) |
| 1023 | 1022 | return NULL; |
| @@ -1168,9 +1167,9 @@ void __radix_tree_replace(struct radix_tree_root *root, · 144 unmodified lines | ||
| 1168 | 1167 | /* |
| 1169 | 1168 | * This function supports replacing exceptional entries and |
| 1170 | 1169 | * deleting entries, but that needs accounting against the |
| 1171 | − * node unless the slot is root->rnode. | |
| 1170 | + * node unless the slot is root->xa_head. | |
| 1172 | 1171 | */ |
| 1173 | − WARN_ON_ONCE(!node && (slot != (void __rcu **)&root->rnode) && | |
| 1172 | + WARN_ON_ONCE(!node && (slot != (void __rcu **)&root->xa_head) && | |
| 1174 | 1173 | (count || exceptional)); |
| 1175 | 1174 | replace_slot(slot, item, node, count, exceptional); |
| 1176 | 1175 | |
| @@ -1722,7 +1721,7 @@ void __rcu **radix_tree_next_chunk(const struct radix_tree_root *root, · 545 unmodified lines | ||
| 1722 | 1721 | iter->tags = 1; |
| 1723 | 1722 | iter->node = NULL; |
| 1724 | 1723 | __set_iter_shift(iter, 0); |
| 1725 | − return (void __rcu **)&root->rnode; | |
| 1724 | + return (void __rcu **)&root->xa_head; | |
| 1726 | 1725 | } |
| 1727 | 1726 | |
| 1728 | 1727 | do { |
| @@ -2109,7 +2108,7 @@ void __rcu **idr_get_free(struct radix_tree_root *root, · 380 unmodified lines | ||
| 2109 | 2108 | unsigned long max) |
| 2110 | 2109 | { |
| 2111 | 2110 | struct radix_tree_node *node = NULL, *child; |
| 2112 | − void __rcu **slot = (void __rcu **)&root->rnode; | |
| 2111 | + void __rcu **slot = (void __rcu **)&root->xa_head; | |
| 2113 | 2112 | unsigned long maxindex, start = iter->next_index; |
| 2114 | 2113 | unsigned int shift, offset = 0; |
| 2115 | 2114 | |
| @@ -2125,7 +2124,7 @@ void __rcu **idr_get_free(struct radix_tree_root *root, · 9 unmodified lines | ||
| 2125 | 2124 | if (error < 0) |
| 2126 | 2125 | return ERR_PTR(error); |
| 2127 | 2126 | shift = error; |
| 2128 | − child = rcu_dereference_raw(root->rnode); | |
| 2127 | + child = rcu_dereference_raw(root->xa_head); | |
| 2129 | 2128 | } |
| 2130 | 2129 | if (start == 0 && shift == 0) |
| 2131 | 2130 | shift = RADIX_TREE_MAP_SHIFT; |
| @@ -2190,10 +2189,10 @@ void __rcu **idr_get_free(struct radix_tree_root *root, · 58 unmodified lines | ||
| 2190 | 2189 | */ |
| 2191 | 2190 | void idr_destroy(struct idr *idr) |
| 2192 | 2191 | { |
| 2193 | − struct radix_tree_node *node = rcu_dereference_raw(idr->idr_rt.rnode); | |
| 2192 | + struct radix_tree_node *node = rcu_dereference_raw(idr->idr_rt.xa_head); | |
| 2194 | 2193 | if (radix_tree_is_internal_node(node)) |
| 2195 | 2194 | radix_tree_free_nodes(node); |
| 2196 | − idr->idr_rt.rnode = NULL; | |
| 2195 | + idr->idr_rt.xa_head = NULL; | |
| 2197 | 2196 | root_tag_set(&idr->idr_rt, IDR_FREE); |
| 2198 | 2197 | } |
| 2199 | 2198 | EXPORT_SYMBOL(idr_destroy); |
| @@ -0,0 +1,44 @@ | ||
| 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); | |
| @@ -5,7 +5,7 @@ CFLAGS += -I. -I../../include -g -Og -Wall -D_LGPL_SOURCE -fsanitize=address \ · 4 unmodified lines | ||
| 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,6 +35,7 @@ vpath %.c ../../lib · 23 unmodified lines | ||
| 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,6 +45,8 @@ radix-tree.c: ../../../lib/radix-tree.c · 3 unmodified lines | ||
| 44 | 45 | idr.c: ../../../lib/idr.c |
| 45 | 46 | sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@ |
| 46 | 47 | |
| 48 | +xarray.o: ../../../lib/xarray.c | |
| 49 | + | |
| 47 | 50 | generated/map-shift.h: |
| 48 | 51 | @if ! grep -qws $(SHIFT) generated/map-shift.h; then \ |
| 49 | 52 | echo "#define XA_CHUNK_SHIFT $(SHIFT)" > \ |
| @@ -1 +1,2 @@ | ||
| 1 | +#include <stdio.h> | |
| 1 | 2 | #include "asm/bug.h" |
| @@ -0,0 +1 @@ | ||
| 1 | +#include "../../../../include/linux/kconfig.h" | |
| @@ -192,13 +192,13 @@ static void multiorder_shrink(unsigned long index, int order) · 191 unmodified lines | ||
| 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); |
| @@ -281,7 +281,7 @@ static int verify_node(struct radix_tree_node *slot, unsigned int tag, · 280 unmodified lines | ||
| 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,13 +311,13 @@ void item_kill_tree(struct radix_tree_root *root) · 23 unmodified lines | ||
| 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; |
| @@ -0,0 +1,7 @@ | ||
| 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" | |