aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/radix-tree/regression3.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/radix-tree/regression3.c')
-rw-r--r--tools/testing/radix-tree/regression3.c86
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
24void 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}