aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-09-22 16:14:30 -0400
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:46:48 -0400
commit3a08cd52c37c793ffc199f6fc2ecfc368e284b2d (patch)
tree36a77e103ef0c6061ed3ec5f18b8865bb87947ef /lib
parent542980aa9318edcfb68aa7bf6eacf2814dc137dd (diff)
radix tree: Remove multiorder support
All users have now been converted to the XArray. Removing the support reduces code size and ensures new users will use the XArray instead. Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/radix-tree.c215
2 files changed, 13 insertions, 206 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 40bfa6ccd294..a9965f4af4dd 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -405,10 +405,6 @@ config XARRAY_MULTI
405 Support entries which occupy multiple consecutive indices in the 405 Support entries which occupy multiple consecutive indices in the
406 XArray. 406 XArray.
407 407
408config RADIX_TREE_MULTIORDER
409 bool
410 select XARRAY_MULTI
411
412config ASSOCIATIVE_ARRAY 408config ASSOCIATIVE_ARRAY
413 bool 409 bool
414 help 410 help
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index f107dd2698e3..1106bb6aa01e 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -110,11 +110,6 @@ static unsigned int radix_tree_descend(const struct radix_tree_node *parent,
110 unsigned int offset = (index >> parent->shift) & RADIX_TREE_MAP_MASK; 110 unsigned int offset = (index >> parent->shift) & RADIX_TREE_MAP_MASK;
111 void __rcu **entry = rcu_dereference_raw(parent->slots[offset]); 111 void __rcu **entry = rcu_dereference_raw(parent->slots[offset]);
112 112
113 if (xa_is_sibling(entry)) {
114 offset = xa_to_sibling(entry);
115 entry = rcu_dereference_raw(parent->slots[offset]);
116 }
117
118 *nodep = (void *)entry; 113 *nodep = (void *)entry;
119 return offset; 114 return offset;
120} 115}
@@ -229,7 +224,7 @@ radix_tree_find_next_bit(struct radix_tree_node *node, unsigned int tag,
229 224
230static unsigned int iter_offset(const struct radix_tree_iter *iter) 225static unsigned int iter_offset(const struct radix_tree_iter *iter)
231{ 226{
232 return (iter->index >> iter_shift(iter)) & RADIX_TREE_MAP_MASK; 227 return iter->index & RADIX_TREE_MAP_MASK;
233} 228}
234 229
235/* 230/*
@@ -506,16 +501,13 @@ static inline bool radix_tree_shrink(struct radix_tree_root *root)
506 501
507 /* 502 /*
508 * The candidate node has more than one child, or its child 503 * The candidate node has more than one child, or its child
509 * is not at the leftmost slot, or the child is a multiorder 504 * is not at the leftmost slot, we cannot shrink.
510 * entry, we cannot shrink.
511 */ 505 */
512 if (node->count != 1) 506 if (node->count != 1)
513 break; 507 break;
514 child = rcu_dereference_raw(node->slots[0]); 508 child = rcu_dereference_raw(node->slots[0]);
515 if (!child) 509 if (!child)
516 break; 510 break;
517 if (!radix_tree_is_internal_node(child) && node->shift)
518 break;
519 511
520 /* 512 /*
521 * For an IDR, we must not shrink entry 0 into the root in 513 * For an IDR, we must not shrink entry 0 into the root in
@@ -613,7 +605,6 @@ static bool delete_node(struct radix_tree_root *root,
613 * __radix_tree_create - create a slot in a radix tree 605 * __radix_tree_create - create a slot in a radix tree
614 * @root: radix tree root 606 * @root: radix tree root
615 * @index: index key 607 * @index: index key
616 * @order: index occupies 2^order aligned slots
617 * @nodep: returns node 608 * @nodep: returns node
618 * @slotp: returns slot 609 * @slotp: returns slot
619 * 610 *
@@ -627,21 +618,19 @@ static bool delete_node(struct radix_tree_root *root,
627 * Returns -ENOMEM, or 0 for success. 618 * Returns -ENOMEM, or 0 for success.
628 */ 619 */
629static int __radix_tree_create(struct radix_tree_root *root, 620static int __radix_tree_create(struct radix_tree_root *root,
630 unsigned long index, unsigned order, 621 unsigned long index, struct radix_tree_node **nodep,
631 struct radix_tree_node **nodep, void __rcu ***slotp) 622 void __rcu ***slotp)
632{ 623{
633 struct radix_tree_node *node = NULL, *child; 624 struct radix_tree_node *node = NULL, *child;
634 void __rcu **slot = (void __rcu **)&root->xa_head; 625 void __rcu **slot = (void __rcu **)&root->xa_head;
635 unsigned long maxindex; 626 unsigned long maxindex;
636 unsigned int shift, offset = 0; 627 unsigned int shift, offset = 0;
637 unsigned long max = index | ((1UL << order) - 1); 628 unsigned long max = index;
638 gfp_t gfp = root_gfp_mask(root); 629 gfp_t gfp = root_gfp_mask(root);
639 630
640 shift = radix_tree_load_root(root, &child, &maxindex); 631 shift = radix_tree_load_root(root, &child, &maxindex);
641 632
642 /* Make sure the tree is high enough. */ 633 /* Make sure the tree is high enough. */
643 if (order > 0 && max == ((1UL << order) - 1))
644 max++;
645 if (max > maxindex) { 634 if (max > maxindex) {
646 int error = radix_tree_extend(root, gfp, max, shift); 635 int error = radix_tree_extend(root, gfp, max, shift);
647 if (error < 0) 636 if (error < 0)
@@ -650,7 +639,7 @@ static int __radix_tree_create(struct radix_tree_root *root,
650 child = rcu_dereference_raw(root->xa_head); 639 child = rcu_dereference_raw(root->xa_head);
651 } 640 }
652 641
653 while (shift > order) { 642 while (shift > 0) {
654 shift -= RADIX_TREE_MAP_SHIFT; 643 shift -= RADIX_TREE_MAP_SHIFT;
655 if (child == NULL) { 644 if (child == NULL) {
656 /* Have to add a child node. */ 645 /* Have to add a child node. */
@@ -711,70 +700,8 @@ static void radix_tree_free_nodes(struct radix_tree_node *node)
711 } 700 }
712} 701}
713 702
714#ifdef CONFIG_RADIX_TREE_MULTIORDER
715static inline int insert_entries(struct radix_tree_node *node,
716 void __rcu **slot, void *item, unsigned order, bool replace)
717{
718 void *sibling;
719 unsigned i, n, tag, offset, tags = 0;
720
721 if (node) {
722 if (order > node->shift)
723 n = 1 << (order - node->shift);
724 else
725 n = 1;
726 offset = get_slot_offset(node, slot);
727 } else {
728 n = 1;
729 offset = 0;
730 }
731
732 if (n > 1) {
733 offset = offset & ~(n - 1);
734 slot = &node->slots[offset];
735 }
736 sibling = xa_mk_sibling(offset);
737
738 for (i = 0; i < n; i++) {
739 if (slot[i]) {
740 if (replace) {
741 node->count--;
742 for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++)
743 if (tag_get(node, tag, offset + i))
744 tags |= 1 << tag;
745 } else
746 return -EEXIST;
747 }
748 }
749
750 for (i = 0; i < n; i++) {
751 struct radix_tree_node *old = rcu_dereference_raw(slot[i]);
752 if (i) {
753 rcu_assign_pointer(slot[i], sibling);
754 for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++)
755 if (tags & (1 << tag))
756 tag_clear(node, tag, offset + i);
757 } else {
758 rcu_assign_pointer(slot[i], item);
759 for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++)
760 if (tags & (1 << tag))
761 tag_set(node, tag, offset);
762 }
763 if (xa_is_node(old))
764 radix_tree_free_nodes(old);
765 if (xa_is_value(old))
766 node->nr_values--;
767 }
768 if (node) {
769 node->count += n;
770 if (xa_is_value(item))
771 node->nr_values += n;
772 }
773 return n;
774}
775#else
776static inline int insert_entries(struct radix_tree_node *node, 703static inline int insert_entries(struct radix_tree_node *node,
777 void __rcu **slot, void *item, unsigned order, bool replace) 704 void __rcu **slot, void *item, bool replace)
778{ 705{
779 if (*slot) 706 if (*slot)
780 return -EEXIST; 707 return -EEXIST;
@@ -786,19 +713,17 @@ static inline int insert_entries(struct radix_tree_node *node,
786 } 713 }
787 return 1; 714 return 1;
788} 715}
789#endif
790 716
791/** 717/**
792 * __radix_tree_insert - insert into a radix tree 718 * __radix_tree_insert - insert into a radix tree
793 * @root: radix tree root 719 * @root: radix tree root
794 * @index: index key 720 * @index: index key
795 * @order: key covers the 2^order indices around index
796 * @item: item to insert 721 * @item: item to insert
797 * 722 *
798 * Insert an item into the radix tree at position @index. 723 * Insert an item into the radix tree at position @index.
799 */ 724 */
800int __radix_tree_insert(struct radix_tree_root *root, unsigned long index, 725int radix_tree_insert(struct radix_tree_root *root, unsigned long index,
801 unsigned order, void *item) 726 void *item)
802{ 727{
803 struct radix_tree_node *node; 728 struct radix_tree_node *node;
804 void __rcu **slot; 729 void __rcu **slot;
@@ -806,11 +731,11 @@ int __radix_tree_insert(struct radix_tree_root *root, unsigned long index,
806 731
807 BUG_ON(radix_tree_is_internal_node(item)); 732 BUG_ON(radix_tree_is_internal_node(item));
808 733
809 error = __radix_tree_create(root, index, order, &node, &slot); 734 error = __radix_tree_create(root, index, &node, &slot);
810 if (error) 735 if (error)
811 return error; 736 return error;
812 737
813 error = insert_entries(node, slot, item, order, false); 738 error = insert_entries(node, slot, item, false);
814 if (error < 0) 739 if (error < 0)
815 return error; 740 return error;
816 741
@@ -825,7 +750,7 @@ int __radix_tree_insert(struct radix_tree_root *root, unsigned long index,
825 750
826 return 0; 751 return 0;
827} 752}
828EXPORT_SYMBOL(__radix_tree_insert); 753EXPORT_SYMBOL(radix_tree_insert);
829 754
830/** 755/**
831 * __radix_tree_lookup - lookup an item in a radix tree 756 * __radix_tree_lookup - lookup an item in a radix tree
@@ -917,32 +842,12 @@ void *radix_tree_lookup(const struct radix_tree_root *root, unsigned long index)
917} 842}
918EXPORT_SYMBOL(radix_tree_lookup); 843EXPORT_SYMBOL(radix_tree_lookup);
919 844
920static inline void replace_sibling_entries(struct radix_tree_node *node,
921 void __rcu **slot, int count, int values)
922{
923#ifdef CONFIG_RADIX_TREE_MULTIORDER
924 unsigned offset = get_slot_offset(node, slot);
925 void *ptr = xa_mk_sibling(offset);
926
927 while (++offset < RADIX_TREE_MAP_SIZE) {
928 if (rcu_dereference_raw(node->slots[offset]) != ptr)
929 break;
930 if (count < 0) {
931 node->slots[offset] = NULL;
932 node->count--;
933 }
934 node->nr_values += values;
935 }
936#endif
937}
938
939static void replace_slot(void __rcu **slot, void *item, 845static void replace_slot(void __rcu **slot, void *item,
940 struct radix_tree_node *node, int count, int values) 846 struct radix_tree_node *node, int count, int values)
941{ 847{
942 if (node && (count || values)) { 848 if (node && (count || values)) {
943 node->count += count; 849 node->count += count;
944 node->nr_values += values; 850 node->nr_values += values;
945 replace_sibling_entries(node, slot, count, values);
946 } 851 }
947 852
948 rcu_assign_pointer(*slot, item); 853 rcu_assign_pointer(*slot, item);
@@ -1223,14 +1128,6 @@ int radix_tree_tag_get(const struct radix_tree_root *root,
1223} 1128}
1224EXPORT_SYMBOL(radix_tree_tag_get); 1129EXPORT_SYMBOL(radix_tree_tag_get);
1225 1130
1226static inline void __set_iter_shift(struct radix_tree_iter *iter,
1227 unsigned int shift)
1228{
1229#ifdef CONFIG_RADIX_TREE_MULTIORDER
1230 iter->shift = shift;
1231#endif
1232}
1233
1234/* Construct iter->tags bit-mask from node->tags[tag] array */ 1131/* Construct iter->tags bit-mask from node->tags[tag] array */
1235static void set_iter_tags(struct radix_tree_iter *iter, 1132static void set_iter_tags(struct radix_tree_iter *iter,
1236 struct radix_tree_node *node, unsigned offset, 1133 struct radix_tree_node *node, unsigned offset,
@@ -1257,92 +1154,11 @@ static void set_iter_tags(struct radix_tree_iter *iter,
1257 } 1154 }
1258} 1155}
1259 1156
1260#ifdef CONFIG_RADIX_TREE_MULTIORDER
1261static void __rcu **skip_siblings(struct radix_tree_node **nodep,
1262 void __rcu **slot, struct radix_tree_iter *iter)
1263{
1264 while (iter->index < iter->next_index) {
1265 *nodep = rcu_dereference_raw(*slot);
1266 if (*nodep && !xa_is_sibling(*nodep))
1267 return slot;
1268 slot++;
1269 iter->index = __radix_tree_iter_add(iter, 1);
1270 iter->tags >>= 1;
1271 }
1272
1273 *nodep = NULL;
1274 return NULL;
1275}
1276
1277void __rcu **__radix_tree_next_slot(void __rcu **slot,
1278 struct radix_tree_iter *iter, unsigned flags)
1279{
1280 unsigned tag = flags & RADIX_TREE_ITER_TAG_MASK;
1281 struct radix_tree_node *node;
1282
1283 slot = skip_siblings(&node, slot, iter);
1284
1285 while (radix_tree_is_internal_node(node)) {
1286 unsigned offset;
1287 unsigned long next_index;
1288
1289 if (node == RADIX_TREE_RETRY)
1290 return slot;
1291 node = entry_to_node(node);
1292 iter->node = node;
1293 iter->shift = node->shift;
1294
1295 if (flags & RADIX_TREE_ITER_TAGGED) {
1296 offset = radix_tree_find_next_bit(node, tag, 0);
1297 if (offset == RADIX_TREE_MAP_SIZE)
1298 return NULL;
1299 slot = &node->slots[offset];
1300 iter->index = __radix_tree_iter_add(iter, offset);
1301 set_iter_tags(iter, node, offset, tag);
1302 node = rcu_dereference_raw(*slot);
1303 } else {
1304 offset = 0;
1305 slot = &node->slots[0];
1306 for (;;) {
1307 node = rcu_dereference_raw(*slot);
1308 if (node)
1309 break;
1310 slot++;
1311 offset++;
1312 if (offset == RADIX_TREE_MAP_SIZE)
1313 return NULL;
1314 }
1315 iter->index = __radix_tree_iter_add(iter, offset);
1316 }
1317 if ((flags & RADIX_TREE_ITER_CONTIG) && (offset > 0))
1318 goto none;
1319 next_index = (iter->index | shift_maxindex(iter->shift)) + 1;
1320 if (next_index < iter->next_index)
1321 iter->next_index = next_index;
1322 }
1323
1324 return slot;
1325 none:
1326 iter->next_index = 0;
1327 return NULL;
1328}
1329EXPORT_SYMBOL(__radix_tree_next_slot);
1330#else
1331static void __rcu **skip_siblings(struct radix_tree_node **nodep,
1332 void __rcu **slot, struct radix_tree_iter *iter)
1333{
1334 return slot;
1335}
1336#endif
1337
1338void __rcu **radix_tree_iter_resume(void __rcu **slot, 1157void __rcu **radix_tree_iter_resume(void __rcu **slot,
1339 struct radix_tree_iter *iter) 1158 struct radix_tree_iter *iter)
1340{ 1159{
1341 struct radix_tree_node *node;
1342
1343 slot++; 1160 slot++;
1344 iter->index = __radix_tree_iter_add(iter, 1); 1161 iter->index = __radix_tree_iter_add(iter, 1);
1345 skip_siblings(&node, slot, iter);
1346 iter->next_index = iter->index; 1162 iter->next_index = iter->index;
1347 iter->tags = 0; 1163 iter->tags = 0;
1348 return NULL; 1164 return NULL;
@@ -1393,7 +1209,6 @@ void __rcu **radix_tree_next_chunk(const struct radix_tree_root *root,
1393 iter->next_index = maxindex + 1; 1209 iter->next_index = maxindex + 1;
1394 iter->tags = 1; 1210 iter->tags = 1;
1395 iter->node = NULL; 1211 iter->node = NULL;
1396 __set_iter_shift(iter, 0);
1397 return (void __rcu **)&root->xa_head; 1212 return (void __rcu **)&root->xa_head;
1398 } 1213 }
1399 1214
@@ -1414,8 +1229,6 @@ void __rcu **radix_tree_next_chunk(const struct radix_tree_root *root,
1414 while (++offset < RADIX_TREE_MAP_SIZE) { 1229 while (++offset < RADIX_TREE_MAP_SIZE) {
1415 void *slot = rcu_dereference_raw( 1230 void *slot = rcu_dereference_raw(
1416 node->slots[offset]); 1231 node->slots[offset]);
1417 if (xa_is_sibling(slot))
1418 continue;
1419 if (slot) 1232 if (slot)
1420 break; 1233 break;
1421 } 1234 }
@@ -1436,10 +1249,9 @@ void __rcu **radix_tree_next_chunk(const struct radix_tree_root *root,
1436 } while (node->shift && radix_tree_is_internal_node(child)); 1249 } while (node->shift && radix_tree_is_internal_node(child));
1437 1250
1438 /* Update the iterator state */ 1251 /* Update the iterator state */
1439 iter->index = (index &~ node_maxindex(node)) | (offset << node->shift); 1252 iter->index = (index &~ node_maxindex(node)) | offset;
1440 iter->next_index = (index | node_maxindex(node)) + 1; 1253 iter->next_index = (index | node_maxindex(node)) + 1;
1441 iter->node = node; 1254 iter->node = node;
1442 __set_iter_shift(iter, node->shift);
1443 1255
1444 if (flags & RADIX_TREE_ITER_TAGGED) 1256 if (flags & RADIX_TREE_ITER_TAGGED)
1445 set_iter_tags(iter, node, offset, tag); 1257 set_iter_tags(iter, node, offset, tag);
@@ -1750,7 +1562,6 @@ void __rcu **idr_get_free(struct radix_tree_root *root,
1750 else 1562 else
1751 iter->next_index = 1; 1563 iter->next_index = 1;
1752 iter->node = node; 1564 iter->node = node;
1753 __set_iter_shift(iter, shift);
1754 set_iter_tags(iter, node, offset, IDR_FREE); 1565 set_iter_tags(iter, node, offset, IDR_FREE);
1755 1566
1756 return slot; 1567 return slot;