aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMatthew Wilcox <mawilcox@microsoft.com>2016-12-14 18:09:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 19:04:10 -0500
commit3e3cdc68bede179a957fcd6be7b833a83df4e5de (patch)
tree8ae1c50d586265c06d5d7ac58e1df08d0c409740 /tools
parenta90eb3a2a405cf7e96093ed531a285067dfdbc9d (diff)
radix tree test suite: check multiorder iteration
The random iteration test only inserts order-0 entries currently. Update it to insert entries of order between 7 and 0. Also make the maximum index configurable, make some variables static, make the test duration variable, remove some useless spinning, and add a fifth thread which calls tag_tagged_items(). Link: http://lkml.kernel.org/r/1480369871-5271-62-git-send-email-mawilcox@linuxonhyperv.com Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com> Tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Matthew Wilcox <mawilcox@microsoft.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/radix-tree/iteration_check.c80
-rw-r--r--tools/testing/radix-tree/main.c3
-rw-r--r--tools/testing/radix-tree/multiorder.c23
-rw-r--r--tools/testing/radix-tree/test.h2
4 files changed, 73 insertions, 35 deletions
diff --git a/tools/testing/radix-tree/iteration_check.c b/tools/testing/radix-tree/iteration_check.c
index f328a66899b4..7572b7ed930e 100644
--- a/tools/testing/radix-tree/iteration_check.c
+++ b/tools/testing/radix-tree/iteration_check.c
@@ -16,26 +16,36 @@
16#include <pthread.h> 16#include <pthread.h>
17#include "test.h" 17#include "test.h"
18 18
19#define NUM_THREADS 4 19#define NUM_THREADS 5
20#define TAG 0 20#define MAX_IDX 100
21#define TAG 0
22#define NEW_TAG 1
23
21static pthread_mutex_t tree_lock = PTHREAD_MUTEX_INITIALIZER; 24static pthread_mutex_t tree_lock = PTHREAD_MUTEX_INITIALIZER;
22static pthread_t threads[NUM_THREADS]; 25static pthread_t threads[NUM_THREADS];
23static unsigned int seeds[3]; 26static unsigned int seeds[3];
24RADIX_TREE(tree, GFP_KERNEL); 27static RADIX_TREE(tree, GFP_KERNEL);
25bool test_complete; 28static bool test_complete;
29static int max_order;
26 30
27/* relentlessly fill the tree with tagged entries */ 31/* relentlessly fill the tree with tagged entries */
28static void *add_entries_fn(void *arg) 32static void *add_entries_fn(void *arg)
29{ 33{
30 int pgoff;
31
32 rcu_register_thread(); 34 rcu_register_thread();
33 35
34 while (!test_complete) { 36 while (!test_complete) {
35 for (pgoff = 0; pgoff < 100; pgoff++) { 37 unsigned long pgoff;
38 int order;
39
40 for (pgoff = 0; pgoff < MAX_IDX; pgoff++) {
36 pthread_mutex_lock(&tree_lock); 41 pthread_mutex_lock(&tree_lock);
37 if (item_insert(&tree, pgoff) == 0) 42 for (order = max_order; order >= 0; order--) {
38 item_tag_set(&tree, pgoff, TAG); 43 if (item_insert_order(&tree, pgoff, order)
44 == 0) {
45 item_tag_set(&tree, pgoff, TAG);
46 break;
47 }
48 }
39 pthread_mutex_unlock(&tree_lock); 49 pthread_mutex_unlock(&tree_lock);
40 } 50 }
41 } 51 }
@@ -62,14 +72,7 @@ static void *tagged_iteration_fn(void *arg)
62 while (!test_complete) { 72 while (!test_complete) {
63 rcu_read_lock(); 73 rcu_read_lock();
64 radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) { 74 radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) {
65 void *entry; 75 void *entry = radix_tree_deref_slot(slot);
66 int i;
67
68 /* busy wait to let removals happen */
69 for (i = 0; i < 1000000; i++)
70 ;
71
72 entry = radix_tree_deref_slot(slot);
73 if (unlikely(!entry)) 76 if (unlikely(!entry))
74 continue; 77 continue;
75 78
@@ -110,14 +113,7 @@ static void *untagged_iteration_fn(void *arg)
110 while (!test_complete) { 113 while (!test_complete) {
111 rcu_read_lock(); 114 rcu_read_lock();
112 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 115 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
113 void *entry; 116 void *entry = radix_tree_deref_slot(slot);
114 int i;
115
116 /* busy wait to let removals happen */
117 for (i = 0; i < 1000000; i++)
118 ;
119
120 entry = radix_tree_deref_slot(slot);
121 if (unlikely(!entry)) 117 if (unlikely(!entry))
122 continue; 118 continue;
123 119
@@ -152,7 +148,7 @@ static void *remove_entries_fn(void *arg)
152 while (!test_complete) { 148 while (!test_complete) {
153 int pgoff; 149 int pgoff;
154 150
155 pgoff = rand_r(&seeds[2]) % 100; 151 pgoff = rand_r(&seeds[2]) % MAX_IDX;
156 152
157 pthread_mutex_lock(&tree_lock); 153 pthread_mutex_lock(&tree_lock);
158 item_delete(&tree, pgoff); 154 item_delete(&tree, pgoff);
@@ -164,36 +160,54 @@ static void *remove_entries_fn(void *arg)
164 return NULL; 160 return NULL;
165} 161}
166 162
163static void *tag_entries_fn(void *arg)
164{
165 rcu_register_thread();
166
167 while (!test_complete) {
168 tag_tagged_items(&tree, &tree_lock, 0, MAX_IDX, 10, TAG,
169 NEW_TAG);
170 }
171 rcu_unregister_thread();
172 return NULL;
173}
174
167/* This is a unit test for a bug found by the syzkaller tester */ 175/* This is a unit test for a bug found by the syzkaller tester */
168void iteration_test(void) 176void iteration_test(unsigned order, unsigned test_duration)
169{ 177{
170 int i; 178 int i;
171 179
172 printf("Running iteration tests for 10 seconds\n"); 180 printf("Running %siteration tests for %d seconds\n",
181 order > 0 ? "multiorder " : "", test_duration);
173 182
183 max_order = order;
174 test_complete = false; 184 test_complete = false;
175 185
176 for (i = 0; i < 3; i++) 186 for (i = 0; i < 3; i++)
177 seeds[i] = rand(); 187 seeds[i] = rand();
178 188
179 if (pthread_create(&threads[0], NULL, tagged_iteration_fn, NULL)) { 189 if (pthread_create(&threads[0], NULL, tagged_iteration_fn, NULL)) {
180 perror("pthread_create"); 190 perror("create tagged iteration thread");
181 exit(1); 191 exit(1);
182 } 192 }
183 if (pthread_create(&threads[1], NULL, untagged_iteration_fn, NULL)) { 193 if (pthread_create(&threads[1], NULL, untagged_iteration_fn, NULL)) {
184 perror("pthread_create"); 194 perror("create untagged iteration thread");
185 exit(1); 195 exit(1);
186 } 196 }
187 if (pthread_create(&threads[2], NULL, add_entries_fn, NULL)) { 197 if (pthread_create(&threads[2], NULL, add_entries_fn, NULL)) {
188 perror("pthread_create"); 198 perror("create add entry thread");
189 exit(1); 199 exit(1);
190 } 200 }
191 if (pthread_create(&threads[3], NULL, remove_entries_fn, NULL)) { 201 if (pthread_create(&threads[3], NULL, remove_entries_fn, NULL)) {
192 perror("pthread_create"); 202 perror("create remove entry thread");
203 exit(1);
204 }
205 if (pthread_create(&threads[4], NULL, tag_entries_fn, NULL)) {
206 perror("create tag entry thread");
193 exit(1); 207 exit(1);
194 } 208 }
195 209
196 sleep(10); 210 sleep(test_duration);
197 test_complete = true; 211 test_complete = true;
198 212
199 for (i = 0; i < NUM_THREADS; i++) { 213 for (i = 0; i < NUM_THREADS; i++) {
diff --git a/tools/testing/radix-tree/main.c b/tools/testing/radix-tree/main.c
index 170175ca4105..f7e9801a6754 100644
--- a/tools/testing/radix-tree/main.c
+++ b/tools/testing/radix-tree/main.c
@@ -350,7 +350,8 @@ int main(int argc, char **argv)
350 regression1_test(); 350 regression1_test();
351 regression2_test(); 351 regression2_test();
352 regression3_test(); 352 regression3_test();
353 iteration_test(); 353 iteration_test(0, 10);
354 iteration_test(7, 20);
354 single_thread_tests(long_run); 355 single_thread_tests(long_run);
355 356
356 /* Free any remaining preallocated nodes */ 357 /* Free any remaining preallocated nodes */
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c
index 9757b8928bd4..08b4e16dc86f 100644
--- a/tools/testing/radix-tree/multiorder.c
+++ b/tools/testing/radix-tree/multiorder.c
@@ -75,8 +75,27 @@ static void __multiorder_tag_test(int index, int order)
75 item_kill_tree(&tree); 75 item_kill_tree(&tree);
76} 76}
77 77
78static void __multiorder_tag_test2(unsigned order, unsigned long index2)
79{
80 RADIX_TREE(tree, GFP_KERNEL);
81 unsigned long index = (1 << order);
82 index2 += index;
83
84 assert(item_insert_order(&tree, 0, order) == 0);
85 assert(item_insert(&tree, index2) == 0);
86
87 assert(radix_tree_tag_set(&tree, 0, 0));
88 assert(radix_tree_tag_set(&tree, index2, 0));
89
90 assert(tag_tagged_items(&tree, NULL, 0, ~0UL, 10, 0, 1) == 2);
91
92 item_kill_tree(&tree);
93}
94
78static void multiorder_tag_tests(void) 95static void multiorder_tag_tests(void)
79{ 96{
97 int i, j;
98
80 /* test multi-order entry for indices 0-7 with no sibling pointers */ 99 /* test multi-order entry for indices 0-7 with no sibling pointers */
81 __multiorder_tag_test(0, 3); 100 __multiorder_tag_test(0, 3);
82 __multiorder_tag_test(5, 3); 101 __multiorder_tag_test(5, 3);
@@ -116,6 +135,10 @@ static void multiorder_tag_tests(void)
116 __multiorder_tag_test(300, 8); 135 __multiorder_tag_test(300, 8);
117 136
118 __multiorder_tag_test(0x12345678UL, 8); 137 __multiorder_tag_test(0x12345678UL, 8);
138
139 for (i = 1; i < 10; i++)
140 for (j = 0; j < (10 << i); j++)
141 __multiorder_tag_test2(i, j);
119} 142}
120 143
121static void multiorder_check(unsigned long index, int order) 144static void multiorder_check(unsigned long index, int order)
diff --git a/tools/testing/radix-tree/test.h b/tools/testing/radix-tree/test.h
index 7c2611caa6d2..056a23b56467 100644
--- a/tools/testing/radix-tree/test.h
+++ b/tools/testing/radix-tree/test.h
@@ -32,7 +32,7 @@ unsigned long find_item(struct radix_tree_root *, void *item);
32 32
33void tag_check(void); 33void tag_check(void);
34void multiorder_checks(void); 34void multiorder_checks(void);
35void iteration_test(void); 35void iteration_test(unsigned order, unsigned duration);
36void benchmark(void); 36void benchmark(void);
37 37
38struct item * 38struct item *