aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2017-11-07 16:30:10 -0500
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:45:53 -0400
commitf8d5d0cc145cc21bfc56ef807dc28102aebbf228 (patch)
tree0fcba575e83fb02fd2cb49df1ce1cc55bcd927d3 /lib
parent02c02bf12c5d838603eed44195d3e91f094e2ab2 (diff)
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile2
-rw-r--r--lib/idr.c4
-rw-r--r--lib/radix-tree.c75
-rw-r--r--lib/xarray.c44
4 files changed, 84 insertions, 41 deletions
diff --git a/lib/Makefile b/lib/Makefile
index ca3f7ebb900d..057385f1f145 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -18,7 +18,7 @@ KCOV_INSTRUMENT_debugobjects.o := n
18KCOV_INSTRUMENT_dynamic_debug.o := n 18KCOV_INSTRUMENT_dynamic_debug.o := n
19 19
20lib-y := ctype.o string.o vsprintf.o cmdline.o \ 20lib-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 idr.o int_sqrt.o extable.o \ 22 idr.o int_sqrt.o extable.o \
23 sha1.o chacha20.o irq_regs.o argv_split.o \ 23 sha1.o chacha20.o irq_regs.o argv_split.o \
24 flex_proportions.o ratelimit.o show_mem.o \ 24 flex_proportions.o ratelimit.o show_mem.o \
diff --git a/lib/idr.c b/lib/idr.c
index 88419fbc5737..9a366b5be2c2 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -39,8 +39,8 @@ int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,
39 unsigned int base = idr->idr_base; 39 unsigned int base = idr->idr_base;
40 unsigned int id = *nextid; 40 unsigned int id = *nextid;
41 41
42 if (WARN_ON_ONCE(!(idr->idr_rt.gfp_mask & ROOT_IS_IDR))) 42 if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR)))
43 idr->idr_rt.gfp_mask |= IDR_RT_MARKER; 43 idr->idr_rt.xa_flags |= IDR_RT_MARKER;
44 44
45 id = (id < base) ? 0 : id - base; 45 id = (id < base) ? 0 : id - base;
46 radix_tree_iter_init(&iter, id); 46 radix_tree_iter_init(&iter, id);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 59b28111eabc..299d4bdba109 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -124,7 +124,7 @@ static unsigned int radix_tree_descend(const struct radix_tree_node *parent,
124 124
125static inline gfp_t root_gfp_mask(const struct radix_tree_root *root) 125static 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
130static inline void tag_set(struct radix_tree_node *node, unsigned int tag, 130static 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,
147 147
148static inline void root_tag_set(struct radix_tree_root *root, unsigned tag) 148static 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
153static inline void root_tag_clear(struct radix_tree_root *root, unsigned tag) 153static 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
158static inline void root_tag_clear_all(struct radix_tree_root *root) 158static 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
163static inline int root_tag_get(const struct radix_tree_root *root, unsigned tag) 163static 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
168static inline unsigned root_tags_get(const struct radix_tree_root *root) 168static 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
173static inline bool is_idr(const struct radix_tree_root *root) 173static 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)
291/* For debug */ 291/* For debug */
292static void radix_tree_dump(struct radix_tree_root *root) 292static void radix_tree_dump(struct radix_tree_root *root)
293{ 293{
294 pr_debug("radix root: %p rnode %p tags %x\n", 294 pr_debug("radix root: %p xa_head %p tags %x\n",
295 root, root->rnode, 295 root, root->xa_head,
296 root->gfp_mask >> ROOT_TAG_SHIFT); 296 root->xa_flags >> ROOT_TAG_SHIFT);
297 if (!radix_tree_is_internal_node(root->rnode)) 297 if (!radix_tree_is_internal_node(root->xa_head))
298 return; 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
302static void dump_ida_node(void *entry, unsigned long index) 302static void dump_ida_node(void *entry, unsigned long index)
@@ -340,9 +340,9 @@ static void dump_ida_node(void *entry, unsigned long index)
340static void ida_dump(struct ida *ida) 340static void ida_dump(struct ida *ida)
341{ 341{
342 struct radix_tree_root *root = &ida->ida_rt; 342 struct radix_tree_root *root = &ida->ida_rt;
343 pr_debug("ida: %p node %p free %d\n", ida, root->rnode, 343 pr_debug("ida: %p node %p free %d\n", ida, root->xa_head,
344 root->gfp_mask >> ROOT_TAG_SHIFT); 344 root->xa_flags >> ROOT_TAG_SHIFT);
345 dump_ida_node(root->rnode, 0); 345 dump_ida_node(root->xa_head, 0);
346} 346}
347#endif 347#endif
348 348
@@ -576,7 +576,7 @@ int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order)
576static unsigned radix_tree_load_root(const struct radix_tree_root *root, 576static unsigned radix_tree_load_root(const struct radix_tree_root *root,
577 struct radix_tree_node **nodep, unsigned long *maxindex) 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 *nodep = node; 581 *nodep = node;
582 582
@@ -605,7 +605,7 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp,
605 while (index > shift_maxindex(maxshift)) 605 while (index > shift_maxindex(maxshift))
606 maxshift += RADIX_TREE_MAP_SHIFT; 606 maxshift += RADIX_TREE_MAP_SHIFT;
607 607
608 entry = rcu_dereference_raw(root->rnode); 608 entry = rcu_dereference_raw(root->xa_head);
609 if (!entry && (!is_idr(root) || root_tag_get(root, IDR_FREE))) 609 if (!entry && (!is_idr(root) || root_tag_get(root, IDR_FREE)))
610 goto out; 610 goto out;
611 611
@@ -633,7 +633,7 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp,
633 if (radix_tree_is_internal_node(entry)) { 633 if (radix_tree_is_internal_node(entry)) {
634 entry_to_node(entry)->parent = node; 634 entry_to_node(entry)->parent = node;
635 } else if (xa_is_value(entry)) { 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 node->exceptional = 1; 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,
642 */ 642 */
643 node->slots[0] = (void __rcu *)entry; 643 node->slots[0] = (void __rcu *)entry;
644 entry = node_to_entry(node); 644 entry = node_to_entry(node);
645 rcu_assign_pointer(root->rnode, entry); 645 rcu_assign_pointer(root->xa_head, entry);
646 shift += RADIX_TREE_MAP_SHIFT; 646 shift += RADIX_TREE_MAP_SHIFT;
647 } while (shift <= maxshift); 647 } while (shift <= maxshift);
648out: 648out:
@@ -659,7 +659,7 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root,
659 bool shrunk = false; 659 bool shrunk = false;
660 660
661 for (;;) { 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 struct radix_tree_node *child; 663 struct radix_tree_node *child;
664 664
665 if (!radix_tree_is_internal_node(node)) 665 if (!radix_tree_is_internal_node(node))
@@ -695,9 +695,9 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root,
695 * moving the node from one part of the tree to another: if it 695 * moving the node from one part of the tree to another: if it
696 * was safe to dereference the old pointer to it 696 * was safe to dereference the old pointer to it
697 * (node->slots[0]), it will be safe to dereference the new 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 if (is_idr(root) && !tag_get(node, IDR_FREE, 0)) 701 if (is_idr(root) && !tag_get(node, IDR_FREE, 0))
702 root_tag_clear(root, IDR_FREE); 702 root_tag_clear(root, IDR_FREE);
703 703
@@ -745,9 +745,8 @@ static bool delete_node(struct radix_tree_root *root,
745 745
746 if (node->count) { 746 if (node->count) {
747 if (node_to_entry(node) == 747 if (node_to_entry(node) ==
748 rcu_dereference_raw(root->rnode)) 748 rcu_dereference_raw(root->xa_head))
749 deleted |= radix_tree_shrink(root, 749 deleted |= radix_tree_shrink(root, update_node);
750 update_node);
751 return deleted; 750 return deleted;
752 } 751 }
753 752
@@ -762,7 +761,7 @@ static bool delete_node(struct radix_tree_root *root,
762 */ 761 */
763 if (!is_idr(root)) 762 if (!is_idr(root))
764 root_tag_clear_all(root); 763 root_tag_clear_all(root);
765 root->rnode = NULL; 764 root->xa_head = NULL;
766 } 765 }
767 766
768 WARN_ON_ONCE(!list_empty(&node->private_list)); 767 WARN_ON_ONCE(!list_empty(&node->private_list));
@@ -787,7 +786,7 @@ static bool delete_node(struct radix_tree_root *root,
787 * at position @index in the radix tree @root. 786 * at position @index in the radix tree @root.
788 * 787 *
789 * Until there is more than one item in the tree, no nodes are 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 * pointing to a node, in which case *@nodep will be NULL. 790 * pointing to a node, in which case *@nodep will be NULL.
792 * 791 *
793 * Returns -ENOMEM, or 0 for success. 792 * Returns -ENOMEM, or 0 for success.
@@ -797,7 +796,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
797 void __rcu ***slotp) 796 void __rcu ***slotp)
798{ 797{
799 struct radix_tree_node *node = NULL, *child; 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 unsigned long maxindex; 800 unsigned long maxindex;
802 unsigned int shift, offset = 0; 801 unsigned int shift, offset = 0;
803 unsigned long max = index | ((1UL << order) - 1); 802 unsigned long max = index | ((1UL << order) - 1);
@@ -813,7 +812,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
813 if (error < 0) 812 if (error < 0)
814 return error; 813 return error;
815 shift = error; 814 shift = error;
816 child = rcu_dereference_raw(root->rnode); 815 child = rcu_dereference_raw(root->xa_head);
817 } 816 }
818 817
819 while (shift > order) { 818 while (shift > order) {
@@ -1004,7 +1003,7 @@ EXPORT_SYMBOL(__radix_tree_insert);
1004 * tree @root. 1003 * tree @root.
1005 * 1004 *
1006 * Until there is more than one item in the tree, no nodes are 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 * pointing to a node, in which case *@nodep will be NULL. 1007 * pointing to a node, in which case *@nodep will be NULL.
1009 */ 1008 */
1010void *__radix_tree_lookup(const struct radix_tree_root *root, 1009void *__radix_tree_lookup(const struct radix_tree_root *root,
@@ -1017,7 +1016,7 @@ void *__radix_tree_lookup(const struct radix_tree_root *root,
1017 1016
1018 restart: 1017 restart:
1019 parent = NULL; 1018 parent = NULL;
1020 slot = (void __rcu **)&root->rnode; 1019 slot = (void __rcu **)&root->xa_head;
1021 radix_tree_load_root(root, &node, &maxindex); 1020 radix_tree_load_root(root, &node, &maxindex);
1022 if (index > maxindex) 1021 if (index > maxindex)
1023 return NULL; 1022 return NULL;
@@ -1168,9 +1167,9 @@ void __radix_tree_replace(struct radix_tree_root *root,
1168 /* 1167 /*
1169 * This function supports replacing exceptional entries and 1168 * This function supports replacing exceptional entries and
1170 * deleting entries, but that needs accounting against the 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 (count || exceptional)); 1173 (count || exceptional));
1175 replace_slot(slot, item, node, count, exceptional); 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,
1722 iter->tags = 1; 1721 iter->tags = 1;
1723 iter->node = NULL; 1722 iter->node = NULL;
1724 __set_iter_shift(iter, 0); 1723 __set_iter_shift(iter, 0);
1725 return (void __rcu **)&root->rnode; 1724 return (void __rcu **)&root->xa_head;
1726 } 1725 }
1727 1726
1728 do { 1727 do {
@@ -2109,7 +2108,7 @@ void __rcu **idr_get_free(struct radix_tree_root *root,
2109 unsigned long max) 2108 unsigned long max)
2110{ 2109{
2111 struct radix_tree_node *node = NULL, *child; 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 unsigned long maxindex, start = iter->next_index; 2112 unsigned long maxindex, start = iter->next_index;
2114 unsigned int shift, offset = 0; 2113 unsigned int shift, offset = 0;
2115 2114
@@ -2125,7 +2124,7 @@ void __rcu **idr_get_free(struct radix_tree_root *root,
2125 if (error < 0) 2124 if (error < 0)
2126 return ERR_PTR(error); 2125 return ERR_PTR(error);
2127 shift = error; 2126 shift = error;
2128 child = rcu_dereference_raw(root->rnode); 2127 child = rcu_dereference_raw(root->xa_head);
2129 } 2128 }
2130 if (start == 0 && shift == 0) 2129 if (start == 0 && shift == 0)
2131 shift = RADIX_TREE_MAP_SHIFT; 2130 shift = RADIX_TREE_MAP_SHIFT;
@@ -2190,10 +2189,10 @@ void __rcu **idr_get_free(struct radix_tree_root *root,
2190 */ 2189 */
2191void idr_destroy(struct idr *idr) 2190void 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 if (radix_tree_is_internal_node(node)) 2193 if (radix_tree_is_internal_node(node))
2195 radix_tree_free_nodes(node); 2194 radix_tree_free_nodes(node);
2196 idr->idr_rt.rnode = NULL; 2195 idr->idr_rt.xa_head = NULL;
2197 root_tag_set(&idr->idr_rt, IDR_FREE); 2196 root_tag_set(&idr->idr_rt, IDR_FREE);
2198} 2197}
2199EXPORT_SYMBOL(idr_destroy); 2198EXPORT_SYMBOL(idr_destroy);
diff --git a/lib/xarray.c b/lib/xarray.c
new file mode 100644
index 000000000000..862f4c64c754
--- /dev/null
+++ b/lib/xarray.c
@@ -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 */
38void 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}
44EXPORT_SYMBOL(xa_init_flags);