summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2016-05-20 20:03:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commit9e85d811196583126785a0405d0c879ae7a9eb2f (patch)
tree44919d0e37d0d4d2bc97d6152e313dd64a75365c
parentd604c324524bf61c68182bb27db64656a78fe911 (diff)
radix-tree: make radix_tree_descend() more useful
Now that the shift amount is stored in the node, radix_tree_descend() can calculate offset itself from index, which removes several lines of code from each of the tree walkers. Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Kirill Shutemov <kirill.shutemov@linux.intel.com> Cc: Jan Kara <jack@suse.com> Cc: Neil Brown <neilb@suse.de> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--lib/radix-tree.c78
1 files changed, 26 insertions, 52 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index c7114d233b38..8b7d8459bb9d 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -94,9 +94,10 @@ static inline unsigned long get_slot_offset(struct radix_tree_node *parent,
94 return slot - parent->slots; 94 return slot - parent->slots;
95} 95}
96 96
97static unsigned radix_tree_descend(struct radix_tree_node *parent, 97static unsigned int radix_tree_descend(struct radix_tree_node *parent,
98 struct radix_tree_node **nodep, unsigned offset) 98 struct radix_tree_node **nodep, unsigned long index)
99{ 99{
100 unsigned int offset = (index >> parent->shift) & RADIX_TREE_MAP_MASK;
100 void **entry = rcu_dereference_raw(parent->slots[offset]); 101 void **entry = rcu_dereference_raw(parent->slots[offset]);
101 102
102#ifdef CONFIG_RADIX_TREE_MULTIORDER 103#ifdef CONFIG_RADIX_TREE_MULTIORDER
@@ -536,8 +537,7 @@ int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
536 537
537 /* Go a level down */ 538 /* Go a level down */
538 node = entry_to_node(child); 539 node = entry_to_node(child);
539 offset = (index >> shift) & RADIX_TREE_MAP_MASK; 540 offset = radix_tree_descend(node, &child, index);
540 offset = radix_tree_descend(node, &child, offset);
541 slot = &node->slots[offset]; 541 slot = &node->slots[offset];
542 } 542 }
543 543
@@ -625,13 +625,12 @@ void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index,
625{ 625{
626 struct radix_tree_node *node, *parent; 626 struct radix_tree_node *node, *parent;
627 unsigned long maxindex; 627 unsigned long maxindex;
628 unsigned int shift;
629 void **slot; 628 void **slot;
630 629
631 restart: 630 restart:
632 parent = NULL; 631 parent = NULL;
633 slot = (void **)&root->rnode; 632 slot = (void **)&root->rnode;
634 shift = radix_tree_load_root(root, &node, &maxindex); 633 radix_tree_load_root(root, &node, &maxindex);
635 if (index > maxindex) 634 if (index > maxindex)
636 return NULL; 635 return NULL;
637 636
@@ -641,9 +640,7 @@ void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index,
641 if (node == RADIX_TREE_RETRY) 640 if (node == RADIX_TREE_RETRY)
642 goto restart; 641 goto restart;
643 parent = entry_to_node(node); 642 parent = entry_to_node(node);
644 shift -= RADIX_TREE_MAP_SHIFT; 643 offset = radix_tree_descend(parent, &node, index);
645 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
646 offset = radix_tree_descend(parent, &node, offset);
647 slot = parent->slots + offset; 644 slot = parent->slots + offset;
648 } 645 }
649 646
@@ -713,19 +710,15 @@ void *radix_tree_tag_set(struct radix_tree_root *root,
713{ 710{
714 struct radix_tree_node *node, *parent; 711 struct radix_tree_node *node, *parent;
715 unsigned long maxindex; 712 unsigned long maxindex;
716 unsigned int shift;
717 713
718 shift = radix_tree_load_root(root, &node, &maxindex); 714 radix_tree_load_root(root, &node, &maxindex);
719 BUG_ON(index > maxindex); 715 BUG_ON(index > maxindex);
720 716
721 while (radix_tree_is_internal_node(node)) { 717 while (radix_tree_is_internal_node(node)) {
722 unsigned offset; 718 unsigned offset;
723 719
724 shift -= RADIX_TREE_MAP_SHIFT;
725 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
726
727 parent = entry_to_node(node); 720 parent = entry_to_node(node);
728 offset = radix_tree_descend(parent, &node, offset); 721 offset = radix_tree_descend(parent, &node, index);
729 BUG_ON(!node); 722 BUG_ON(!node);
730 723
731 if (!tag_get(parent, tag, offset)) 724 if (!tag_get(parent, tag, offset))
@@ -779,21 +772,17 @@ void *radix_tree_tag_clear(struct radix_tree_root *root,
779{ 772{
780 struct radix_tree_node *node, *parent; 773 struct radix_tree_node *node, *parent;
781 unsigned long maxindex; 774 unsigned long maxindex;
782 unsigned int shift;
783 int uninitialized_var(offset); 775 int uninitialized_var(offset);
784 776
785 shift = radix_tree_load_root(root, &node, &maxindex); 777 radix_tree_load_root(root, &node, &maxindex);
786 if (index > maxindex) 778 if (index > maxindex)
787 return NULL; 779 return NULL;
788 780
789 parent = NULL; 781 parent = NULL;
790 782
791 while (radix_tree_is_internal_node(node)) { 783 while (radix_tree_is_internal_node(node)) {
792 shift -= RADIX_TREE_MAP_SHIFT;
793 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
794
795 parent = entry_to_node(node); 784 parent = entry_to_node(node);
796 offset = radix_tree_descend(parent, &node, offset); 785 offset = radix_tree_descend(parent, &node, index);
797 } 786 }
798 787
799 if (node) 788 if (node)
@@ -823,25 +812,21 @@ int radix_tree_tag_get(struct radix_tree_root *root,
823{ 812{
824 struct radix_tree_node *node, *parent; 813 struct radix_tree_node *node, *parent;
825 unsigned long maxindex; 814 unsigned long maxindex;
826 unsigned int shift;
827 815
828 if (!root_tag_get(root, tag)) 816 if (!root_tag_get(root, tag))
829 return 0; 817 return 0;
830 818
831 shift = radix_tree_load_root(root, &node, &maxindex); 819 radix_tree_load_root(root, &node, &maxindex);
832 if (index > maxindex) 820 if (index > maxindex)
833 return 0; 821 return 0;
834 if (node == NULL) 822 if (node == NULL)
835 return 0; 823 return 0;
836 824
837 while (radix_tree_is_internal_node(node)) { 825 while (radix_tree_is_internal_node(node)) {
838 int offset; 826 unsigned offset;
839
840 shift -= RADIX_TREE_MAP_SHIFT;
841 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
842 827
843 parent = entry_to_node(node); 828 parent = entry_to_node(node);
844 offset = radix_tree_descend(parent, &node, offset); 829 offset = radix_tree_descend(parent, &node, index);
845 830
846 if (!node) 831 if (!node)
847 return 0; 832 return 0;
@@ -874,7 +859,7 @@ static inline void __set_iter_shift(struct radix_tree_iter *iter,
874void **radix_tree_next_chunk(struct radix_tree_root *root, 859void **radix_tree_next_chunk(struct radix_tree_root *root,
875 struct radix_tree_iter *iter, unsigned flags) 860 struct radix_tree_iter *iter, unsigned flags)
876{ 861{
877 unsigned shift, tag = flags & RADIX_TREE_ITER_TAG_MASK; 862 unsigned tag = flags & RADIX_TREE_ITER_TAG_MASK;
878 struct radix_tree_node *node, *child; 863 struct radix_tree_node *node, *child;
879 unsigned long index, offset, maxindex; 864 unsigned long index, offset, maxindex;
880 865
@@ -895,7 +880,7 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
895 return NULL; 880 return NULL;
896 881
897 restart: 882 restart:
898 shift = radix_tree_load_root(root, &child, &maxindex); 883 radix_tree_load_root(root, &child, &maxindex);
899 if (index > maxindex) 884 if (index > maxindex)
900 return NULL; 885 return NULL;
901 if (!child) 886 if (!child)
@@ -912,9 +897,7 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
912 897
913 do { 898 do {
914 node = entry_to_node(child); 899 node = entry_to_node(child);
915 shift -= RADIX_TREE_MAP_SHIFT; 900 offset = radix_tree_descend(node, &child, index);
916 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
917 offset = radix_tree_descend(node, &child, offset);
918 901
919 if ((flags & RADIX_TREE_ITER_TAGGED) ? 902 if ((flags & RADIX_TREE_ITER_TAGGED) ?
920 !tag_get(node, tag, offset) : !child) { 903 !tag_get(node, tag, offset) : !child) {
@@ -936,7 +919,7 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
936 break; 919 break;
937 } 920 }
938 index &= ~node_maxindex(node); 921 index &= ~node_maxindex(node);
939 index += offset << shift; 922 index += offset << node->shift;
940 /* Overflow after ~0UL */ 923 /* Overflow after ~0UL */
941 if (!index) 924 if (!index)
942 return NULL; 925 return NULL;
@@ -952,7 +935,7 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
952 /* Update the iterator state */ 935 /* Update the iterator state */
953 iter->index = (index &~ node_maxindex(node)) | (offset << node->shift); 936 iter->index = (index &~ node_maxindex(node)) | (offset << node->shift);
954 iter->next_index = (index | node_maxindex(node)) + 1; 937 iter->next_index = (index | node_maxindex(node)) + 1;
955 __set_iter_shift(iter, shift); 938 __set_iter_shift(iter, node->shift);
956 939
957 /* Construct iter->tags bit-mask from node->tags[tag] array */ 940 /* Construct iter->tags bit-mask from node->tags[tag] array */
958 if (flags & RADIX_TREE_ITER_TAGGED) { 941 if (flags & RADIX_TREE_ITER_TAGGED) {
@@ -1010,10 +993,10 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1010{ 993{
1011 struct radix_tree_node *parent, *node, *child; 994 struct radix_tree_node *parent, *node, *child;
1012 unsigned long maxindex; 995 unsigned long maxindex;
1013 unsigned int shift = radix_tree_load_root(root, &child, &maxindex);
1014 unsigned long tagged = 0; 996 unsigned long tagged = 0;
1015 unsigned long index = *first_indexp; 997 unsigned long index = *first_indexp;
1016 998
999 radix_tree_load_root(root, &child, &maxindex);
1017 last_index = min(last_index, maxindex); 1000 last_index = min(last_index, maxindex);
1018 if (index > last_index) 1001 if (index > last_index)
1019 return 0; 1002 return 0;
@@ -1030,11 +1013,9 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1030 } 1013 }
1031 1014
1032 node = entry_to_node(child); 1015 node = entry_to_node(child);
1033 shift -= RADIX_TREE_MAP_SHIFT;
1034 1016
1035 for (;;) { 1017 for (;;) {
1036 unsigned offset = (index >> shift) & RADIX_TREE_MAP_MASK; 1018 unsigned offset = radix_tree_descend(node, &child, index);
1037 offset = radix_tree_descend(node, &child, offset);
1038 if (!child) 1019 if (!child)
1039 goto next; 1020 goto next;
1040 if (!tag_get(node, iftag, offset)) 1021 if (!tag_get(node, iftag, offset))
@@ -1042,7 +1023,6 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1042 /* Sibling slots never have tags set on them */ 1023 /* Sibling slots never have tags set on them */
1043 if (radix_tree_is_internal_node(child)) { 1024 if (radix_tree_is_internal_node(child)) {
1044 node = entry_to_node(child); 1025 node = entry_to_node(child);
1045 shift -= RADIX_TREE_MAP_SHIFT;
1046 continue; 1026 continue;
1047 } 1027 }
1048 1028
@@ -1063,12 +1043,12 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1063 tag_set(parent, settag, offset); 1043 tag_set(parent, settag, offset);
1064 } 1044 }
1065 next: 1045 next:
1066 /* Go to next item at level determined by 'shift' */ 1046 /* Go to next entry in node */
1067 index = ((index >> shift) + 1) << shift; 1047 index = ((index >> node->shift) + 1) << node->shift;
1068 /* Overflow can happen when last_index is ~0UL... */ 1048 /* Overflow can happen when last_index is ~0UL... */
1069 if (index > last_index || !index) 1049 if (index > last_index || !index)
1070 break; 1050 break;
1071 offset = (index >> shift) & RADIX_TREE_MAP_MASK; 1051 offset = (index >> node->shift) & RADIX_TREE_MAP_MASK;
1072 while (offset == 0) { 1052 while (offset == 0) {
1073 /* 1053 /*
1074 * We've fully scanned this node. Go up. Because 1054 * We've fully scanned this node. Go up. Because
@@ -1076,8 +1056,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1076 * we do below cannot wander astray. 1056 * we do below cannot wander astray.
1077 */ 1057 */
1078 node = node->parent; 1058 node = node->parent;
1079 shift += RADIX_TREE_MAP_SHIFT; 1059 offset = (index >> node->shift) & RADIX_TREE_MAP_MASK;
1080 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
1081 } 1060 }
1082 if (is_sibling_entry(node, node->slots[offset])) 1061 if (is_sibling_entry(node, node->slots[offset]))
1083 goto next; 1062 goto next;
@@ -1275,13 +1254,10 @@ struct locate_info {
1275static unsigned long __locate(struct radix_tree_node *slot, void *item, 1254static unsigned long __locate(struct radix_tree_node *slot, void *item,
1276 unsigned long index, struct locate_info *info) 1255 unsigned long index, struct locate_info *info)
1277{ 1256{
1278 unsigned int shift;
1279 unsigned long i; 1257 unsigned long i;
1280 1258
1281 shift = slot->shift + RADIX_TREE_MAP_SHIFT;
1282
1283 do { 1259 do {
1284 shift -= RADIX_TREE_MAP_SHIFT; 1260 unsigned int shift = slot->shift;
1285 1261
1286 for (i = (index >> shift) & RADIX_TREE_MAP_MASK; 1262 for (i = (index >> shift) & RADIX_TREE_MAP_MASK;
1287 i < RADIX_TREE_MAP_SIZE; 1263 i < RADIX_TREE_MAP_SIZE;
@@ -1304,9 +1280,7 @@ static unsigned long __locate(struct radix_tree_node *slot, void *item,
1304 slot = node; 1280 slot = node;
1305 break; 1281 break;
1306 } 1282 }
1307 if (i == RADIX_TREE_MAP_SIZE) 1283 } while (i < RADIX_TREE_MAP_SIZE);
1308 break;
1309 } while (shift);
1310 1284
1311out: 1285out:
1312 if ((index == 0) && (i == RADIX_TREE_MAP_SIZE)) 1286 if ((index == 0) && (i == RADIX_TREE_MAP_SIZE))