diff options
Diffstat (limited to 'tools/testing/radix-tree/regression3.c')
| -rw-r--r-- | tools/testing/radix-tree/regression3.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/tools/testing/radix-tree/regression3.c b/tools/testing/radix-tree/regression3.c new file mode 100644 index 000000000000..17d3ba5f4a0a --- /dev/null +++ b/tools/testing/radix-tree/regression3.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Regression3 | ||
| 3 | * Description: | ||
| 4 | * Helper radix_tree_iter_retry resets next_index to the current index. | ||
| 5 | * In following radix_tree_next_slot current chunk size becomes zero. | ||
| 6 | * This isn't checked and it tries to dereference null pointer in slot. | ||
| 7 | * | ||
| 8 | * Running: | ||
| 9 | * This test should run to completion immediately. The above bug would | ||
| 10 | * cause it to segfault. | ||
| 11 | * | ||
| 12 | * Upstream commit: | ||
| 13 | * Not yet | ||
| 14 | */ | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/gfp.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/radix-tree.h> | ||
| 19 | #include <stdlib.h> | ||
| 20 | #include <stdio.h> | ||
| 21 | |||
| 22 | #include "regression.h" | ||
| 23 | |||
| 24 | void regression3_test(void) | ||
| 25 | { | ||
| 26 | RADIX_TREE(root, GFP_KERNEL); | ||
| 27 | void *ptr = (void *)4ul; | ||
| 28 | struct radix_tree_iter iter; | ||
| 29 | void **slot; | ||
| 30 | bool first; | ||
| 31 | |||
| 32 | printf("running regression test 3 (should take milliseconds)\n"); | ||
| 33 | |||
| 34 | radix_tree_insert(&root, 0, ptr); | ||
| 35 | radix_tree_tag_set(&root, 0, 0); | ||
| 36 | |||
| 37 | first = true; | ||
| 38 | radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) { | ||
| 39 | // printk("tagged %ld %p\n", iter.index, *slot); | ||
| 40 | if (first) { | ||
| 41 | radix_tree_insert(&root, 1, ptr); | ||
| 42 | radix_tree_tag_set(&root, 1, 0); | ||
| 43 | first = false; | ||
| 44 | } | ||
| 45 | if (radix_tree_deref_retry(*slot)) { | ||
| 46 | // printk("retry %ld\n", iter.index); | ||
| 47 | slot = radix_tree_iter_retry(&iter); | ||
| 48 | continue; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | radix_tree_delete(&root, 1); | ||
| 52 | |||
| 53 | first = true; | ||
| 54 | radix_tree_for_each_slot(slot, &root, &iter, 0) { | ||
| 55 | // printk("slot %ld %p\n", iter.index, *slot); | ||
| 56 | if (first) { | ||
| 57 | radix_tree_insert(&root, 1, ptr); | ||
| 58 | first = false; | ||
| 59 | } | ||
| 60 | if (radix_tree_deref_retry(*slot)) { | ||
| 61 | // printk("retry %ld\n", iter.index); | ||
| 62 | slot = radix_tree_iter_retry(&iter); | ||
| 63 | continue; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | radix_tree_delete(&root, 1); | ||
| 67 | |||
| 68 | first = true; | ||
| 69 | radix_tree_for_each_contig(slot, &root, &iter, 0) { | ||
| 70 | // printk("contig %ld %p\n", iter.index, *slot); | ||
| 71 | if (first) { | ||
| 72 | radix_tree_insert(&root, 1, ptr); | ||
| 73 | first = false; | ||
| 74 | } | ||
| 75 | if (radix_tree_deref_retry(*slot)) { | ||
| 76 | // printk("retry %ld\n", iter.index); | ||
| 77 | slot = radix_tree_iter_retry(&iter); | ||
| 78 | continue; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | radix_tree_delete(&root, 0); | ||
| 83 | radix_tree_delete(&root, 1); | ||
| 84 | |||
| 85 | printf("regression test 3 passed\n"); | ||
| 86 | } | ||
