diff options
-rw-r--r-- | lib/radix-tree.c | 14 | ||||
-rw-r--r-- | tools/testing/radix-tree/multiorder.c | 12 |
2 files changed, 22 insertions, 4 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index f14ada9830ca..ff460423ff4b 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -165,6 +165,11 @@ static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag) | |||
165 | return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT)); | 165 | return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT)); |
166 | } | 166 | } |
167 | 167 | ||
168 | static inline unsigned root_tags_get(struct radix_tree_root *root) | ||
169 | { | ||
170 | return (__force unsigned)root->gfp_mask >> __GFP_BITS_SHIFT; | ||
171 | } | ||
172 | |||
168 | /* | 173 | /* |
169 | * Returns 1 if any slot in the node has this tag set. | 174 | * Returns 1 if any slot in the node has this tag set. |
170 | * Otherwise returns 0. | 175 | * Otherwise returns 0. |
@@ -604,12 +609,13 @@ int __radix_tree_insert(struct radix_tree_root *root, unsigned long index, | |||
604 | rcu_assign_pointer(*slot, item); | 609 | rcu_assign_pointer(*slot, item); |
605 | 610 | ||
606 | if (node) { | 611 | if (node) { |
612 | unsigned offset = get_slot_offset(node, slot); | ||
607 | node->count++; | 613 | node->count++; |
608 | BUG_ON(tag_get(node, 0, index & RADIX_TREE_MAP_MASK)); | 614 | BUG_ON(tag_get(node, 0, offset)); |
609 | BUG_ON(tag_get(node, 1, index & RADIX_TREE_MAP_MASK)); | 615 | BUG_ON(tag_get(node, 1, offset)); |
616 | BUG_ON(tag_get(node, 2, offset)); | ||
610 | } else { | 617 | } else { |
611 | BUG_ON(root_tag_get(root, 0)); | 618 | BUG_ON(root_tags_get(root)); |
612 | BUG_ON(root_tag_get(root, 1)); | ||
613 | } | 619 | } |
614 | 620 | ||
615 | return 0; | 621 | return 0; |
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c index 71f34a047002..0a311a5f39de 100644 --- a/tools/testing/radix-tree/multiorder.c +++ b/tools/testing/radix-tree/multiorder.c | |||
@@ -81,6 +81,17 @@ static void multiorder_shrink(unsigned long index, int order) | |||
81 | item_check_absent(&tree, i); | 81 | item_check_absent(&tree, i); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void multiorder_insert_bug(void) | ||
85 | { | ||
86 | RADIX_TREE(tree, GFP_KERNEL); | ||
87 | |||
88 | item_insert(&tree, 0); | ||
89 | radix_tree_tag_set(&tree, 0, 0); | ||
90 | item_insert_order(&tree, 3 << 6, 6); | ||
91 | |||
92 | item_kill_tree(&tree); | ||
93 | } | ||
94 | |||
84 | void multiorder_checks(void) | 95 | void multiorder_checks(void) |
85 | { | 96 | { |
86 | int i; | 97 | int i; |
@@ -94,4 +105,5 @@ void multiorder_checks(void) | |||
94 | for (i = 0; i < 15; i++) | 105 | for (i = 0; i < 15; i++) |
95 | multiorder_shrink((1UL << (i + RADIX_TREE_MAP_SHIFT)), i); | 106 | multiorder_shrink((1UL << (i + RADIX_TREE_MAP_SHIFT)), i); |
96 | 107 | ||
108 | multiorder_insert_bug(); | ||
97 | } | 109 | } |