Skip to content

Commit

Permalink
radix-tree tests: add test for radix_tree_iter_next
Browse files Browse the repository at this point in the history
Without fix test crashes inside tagged iteration.

Signed-off-by: Konstantin Khlebnikov <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
koct9i authored and torvalds committed Mar 17, 2016
1 parent 2d6f45b commit 7475851
Showing 1 changed file with 39 additions and 8 deletions.
47 changes: 39 additions & 8 deletions tools/testing/radix-tree/regression3.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
* In following radix_tree_next_slot current chunk size becomes zero.
* This isn't checked and it tries to dereference null pointer in slot.
*
* Helper radix_tree_iter_next reset slot to NULL and next_index to index + 1,
* for tagger iteraction it also must reset cached tags in iterator to abort
* next radix_tree_next_slot and go to slow-path into radix_tree_next_chunk.
*
* Running:
* This test should run to completion immediately. The above bug would
* cause it to segfault.
Expand All @@ -24,26 +28,27 @@
void regression3_test(void)
{
RADIX_TREE(root, GFP_KERNEL);
void *ptr = (void *)4ul;
void *ptr0 = (void *)4ul;
void *ptr = (void *)8ul;
struct radix_tree_iter iter;
void **slot;
bool first;

printf("running regression test 3 (should take milliseconds)\n");

radix_tree_insert(&root, 0, ptr);
radix_tree_insert(&root, 0, ptr0);
radix_tree_tag_set(&root, 0, 0);

first = true;
radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
// printk("tagged %ld %p\n", iter.index, *slot);
printf("tagged %ld %p\n", iter.index, *slot);
if (first) {
radix_tree_insert(&root, 1, ptr);
radix_tree_tag_set(&root, 1, 0);
first = false;
}
if (radix_tree_deref_retry(*slot)) {
// printk("retry %ld\n", iter.index);
printf("retry at %ld\n", iter.index);
slot = radix_tree_iter_retry(&iter);
continue;
}
Expand All @@ -52,13 +57,13 @@ void regression3_test(void)

first = true;
radix_tree_for_each_slot(slot, &root, &iter, 0) {
// printk("slot %ld %p\n", iter.index, *slot);
printf("slot %ld %p\n", iter.index, *slot);
if (first) {
radix_tree_insert(&root, 1, ptr);
first = false;
}
if (radix_tree_deref_retry(*slot)) {
// printk("retry %ld\n", iter.index);
printk("retry at %ld\n", iter.index);
slot = radix_tree_iter_retry(&iter);
continue;
}
Expand All @@ -67,18 +72,44 @@ void regression3_test(void)

first = true;
radix_tree_for_each_contig(slot, &root, &iter, 0) {
// printk("contig %ld %p\n", iter.index, *slot);
printk("contig %ld %p\n", iter.index, *slot);
if (first) {
radix_tree_insert(&root, 1, ptr);
first = false;
}
if (radix_tree_deref_retry(*slot)) {
// printk("retry %ld\n", iter.index);
printk("retry at %ld\n", iter.index);
slot = radix_tree_iter_retry(&iter);
continue;
}
}

radix_tree_for_each_slot(slot, &root, &iter, 0) {
printf("slot %ld %p\n", iter.index, *slot);
if (!iter.index) {
printf("next at %ld\n", iter.index);
slot = radix_tree_iter_next(&iter);
}
}

radix_tree_for_each_contig(slot, &root, &iter, 0) {
printf("contig %ld %p\n", iter.index, *slot);
if (!iter.index) {
printf("next at %ld\n", iter.index);
slot = radix_tree_iter_next(&iter);
}
}

radix_tree_tag_set(&root, 0, 0);
radix_tree_tag_set(&root, 1, 0);
radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
printf("tagged %ld %p\n", iter.index, *slot);
if (!iter.index) {
printf("next at %ld\n", iter.index);
slot = radix_tree_iter_next(&iter);
}
}

radix_tree_delete(&root, 0);
radix_tree_delete(&root, 1);

Expand Down

0 comments on commit 7475851

Please sign in to comment.