aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2016-05-20 20:02:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commit070c5ac2740b5db89d381a09fb03b2480b2f7a74 (patch)
tree1ad983222d48c155f20d6f1e03d759484e873823 /tools/testing
parenteb73f7f3300c144c4b886dd56ea4c3d2b2d58249 (diff)
radix-tree: fix radix_tree_range_tag_if_tagged() for multiorder entries
I had previously decided that tagging a single multiorder entry would count as tagging 2^order entries for the purposes of 'nr_to_tag'. I now believe that decision to be a mistake, and it should count as a single entry. That's more likely to be what callers expect. When walking back up the tree from a newly-tagged entry, the current code assumed we were starting from the lowest level of the tree; if we have a multiorder entry with an order at least RADIX_TREE_MAP_SHIFT in size then we need to shift the index by 'shift' before we start walking back up the tree, or we will end up not setting tags on higher entries, and then mistakenly thinking that entries below a certain point in the tree are not tagged. If the first index we examine is a sibling entry of a tagged multiorder entry, we were not tagging it. We need to examine the canonical entry, and the easiest way to do that is to use radix_tree_descend(). We then have to skip over sibling slots when looking for the next entry in the tree or we will end up walking back to the canonical entry. Add several tests for radix_tree_range_tag_if_tagged(). Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Reviewed-by: Ross Zwisler <ross.zwisler@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> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/testing')
-rw-r--r--tools/testing/radix-tree/multiorder.c25
-rw-r--r--tools/testing/radix-tree/tag_check.c10
2 files changed, 34 insertions, 1 deletions
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c
index fc934578e1ef..c061f4bd6c05 100644
--- a/tools/testing/radix-tree/multiorder.c
+++ b/tools/testing/radix-tree/multiorder.c
@@ -26,6 +26,7 @@ static void __multiorder_tag_test(int index, int order)
26{ 26{
27 RADIX_TREE(tree, GFP_KERNEL); 27 RADIX_TREE(tree, GFP_KERNEL);
28 int base, err, i; 28 int base, err, i;
29 unsigned long first = 0;
29 30
30 /* our canonical entry */ 31 /* our canonical entry */
31 base = index & ~((1 << order) - 1); 32 base = index & ~((1 << order) - 1);
@@ -59,13 +60,16 @@ static void __multiorder_tag_test(int index, int order)
59 assert(!radix_tree_tag_get(&tree, i, 1)); 60 assert(!radix_tree_tag_get(&tree, i, 1));
60 } 61 }
61 62
63 assert(radix_tree_range_tag_if_tagged(&tree, &first, ~0UL, 10, 0, 1) == 1);
62 assert(radix_tree_tag_clear(&tree, index, 0)); 64 assert(radix_tree_tag_clear(&tree, index, 0));
63 65
64 for_each_index(i, base, order) { 66 for_each_index(i, base, order) {
65 assert(!radix_tree_tag_get(&tree, i, 0)); 67 assert(!radix_tree_tag_get(&tree, i, 0));
66 assert(!radix_tree_tag_get(&tree, i, 1)); 68 assert(radix_tree_tag_get(&tree, i, 1));
67 } 69 }
68 70
71 assert(radix_tree_tag_clear(&tree, index, 1));
72
69 assert(!radix_tree_tagged(&tree, 0)); 73 assert(!radix_tree_tagged(&tree, 0));
70 assert(!radix_tree_tagged(&tree, 1)); 74 assert(!radix_tree_tagged(&tree, 1));
71 75
@@ -244,6 +248,7 @@ void multiorder_tagged_iteration(void)
244 RADIX_TREE(tree, GFP_KERNEL); 248 RADIX_TREE(tree, GFP_KERNEL);
245 struct radix_tree_iter iter; 249 struct radix_tree_iter iter;
246 void **slot; 250 void **slot;
251 unsigned long first = 0;
247 int i; 252 int i;
248 253
249 printf("Multiorder tagged iteration test\n"); 254 printf("Multiorder tagged iteration test\n");
@@ -280,6 +285,24 @@ void multiorder_tagged_iteration(void)
280 i++; 285 i++;
281 } 286 }
282 287
288 radix_tree_range_tag_if_tagged(&tree, &first, ~0UL,
289 MT_NUM_ENTRIES, 1, 2);
290
291 i = 0;
292 radix_tree_for_each_tagged(slot, &tree, &iter, 1, 2) {
293 assert(iter.index == tag_index[i]);
294 i++;
295 }
296
297 first = 1;
298 radix_tree_range_tag_if_tagged(&tree, &first, ~0UL,
299 MT_NUM_ENTRIES, 1, 0);
300 i = 0;
301 radix_tree_for_each_tagged(slot, &tree, &iter, 0, 0) {
302 assert(iter.index == tag_index[i]);
303 i++;
304 }
305
283 item_kill_tree(&tree); 306 item_kill_tree(&tree);
284} 307}
285 308
diff --git a/tools/testing/radix-tree/tag_check.c b/tools/testing/radix-tree/tag_check.c
index 83136be552a0..b7447ceb75e9 100644
--- a/tools/testing/radix-tree/tag_check.c
+++ b/tools/testing/radix-tree/tag_check.c
@@ -12,6 +12,7 @@
12static void 12static void
13__simple_checks(struct radix_tree_root *tree, unsigned long index, int tag) 13__simple_checks(struct radix_tree_root *tree, unsigned long index, int tag)
14{ 14{
15 unsigned long first = 0;
15 int ret; 16 int ret;
16 17
17 item_check_absent(tree, index); 18 item_check_absent(tree, index);
@@ -22,6 +23,10 @@ __simple_checks(struct radix_tree_root *tree, unsigned long index, int tag)
22 item_tag_set(tree, index, tag); 23 item_tag_set(tree, index, tag);
23 ret = item_tag_get(tree, index, tag); 24 ret = item_tag_get(tree, index, tag);
24 assert(ret != 0); 25 assert(ret != 0);
26 ret = radix_tree_range_tag_if_tagged(tree, &first, ~0UL, 10, tag, !tag);
27 assert(ret == 1);
28 ret = item_tag_get(tree, index, !tag);
29 assert(ret != 0);
25 ret = item_delete(tree, index); 30 ret = item_delete(tree, index);
26 assert(ret != 0); 31 assert(ret != 0);
27 item_insert(tree, index); 32 item_insert(tree, index);
@@ -304,6 +309,7 @@ static void single_check(void)
304 struct item *items[BATCH]; 309 struct item *items[BATCH];
305 RADIX_TREE(tree, GFP_KERNEL); 310 RADIX_TREE(tree, GFP_KERNEL);
306 int ret; 311 int ret;
312 unsigned long first = 0;
307 313
308 item_insert(&tree, 0); 314 item_insert(&tree, 0);
309 item_tag_set(&tree, 0, 0); 315 item_tag_set(&tree, 0, 0);
@@ -313,6 +319,10 @@ static void single_check(void)
313 assert(ret == 0); 319 assert(ret == 0);
314 verify_tag_consistency(&tree, 0); 320 verify_tag_consistency(&tree, 0);
315 verify_tag_consistency(&tree, 1); 321 verify_tag_consistency(&tree, 1);
322 ret = radix_tree_range_tag_if_tagged(&tree, &first, 10, 10, 0, 1);
323 assert(ret == 1);
324 ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 1);
325 assert(ret == 1);
316 item_kill_tree(&tree); 326 item_kill_tree(&tree);
317} 327}
318 328