aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/radix-tree/iteration_check.c
diff options
context:
space:
mode:
authorMatthew Wilcox <mawilcox@microsoft.com>2016-12-14 18:08:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 19:04:09 -0500
commitba20cd60c97945f0de9fe313f869b3a5855e1503 (patch)
tree35a39c27248705e7c736c9ee5bfa1d22d69a3a2e /tools/testing/radix-tree/iteration_check.c
parent061ef3936b16edc8f779d403d569392505665ed5 (diff)
radix tree test suite: iteration test misuses RCU
Each thread needs to register itself with RCU, otherwise the reading thread's read lock has no effect and the freeing thread will free the memory in the tree without waiting for the read lock to be dropped. Link: http://lkml.kernel.org/r/1480369871-5271-42-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/testing/radix-tree/iteration_check.c')
-rw-r--r--tools/testing/radix-tree/iteration_check.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/tools/testing/radix-tree/iteration_check.c b/tools/testing/radix-tree/iteration_check.c
index 11d570c3fc83..df71cb841385 100644
--- a/tools/testing/radix-tree/iteration_check.c
+++ b/tools/testing/radix-tree/iteration_check.c
@@ -29,6 +29,8 @@ static void *add_entries_fn(void *arg)
29{ 29{
30 int pgoff; 30 int pgoff;
31 31
32 rcu_register_thread();
33
32 while (!test_complete) { 34 while (!test_complete) {
33 for (pgoff = 0; pgoff < 100; pgoff++) { 35 for (pgoff = 0; pgoff < 100; pgoff++) {
34 pthread_mutex_lock(&tree_lock); 36 pthread_mutex_lock(&tree_lock);
@@ -38,6 +40,8 @@ static void *add_entries_fn(void *arg)
38 } 40 }
39 } 41 }
40 42
43 rcu_unregister_thread();
44
41 return NULL; 45 return NULL;
42} 46}
43 47
@@ -53,6 +57,8 @@ static void *tagged_iteration_fn(void *arg)
53 struct radix_tree_iter iter; 57 struct radix_tree_iter iter;
54 void **slot; 58 void **slot;
55 59
60 rcu_register_thread();
61
56 while (!test_complete) { 62 while (!test_complete) {
57 rcu_read_lock(); 63 rcu_read_lock();
58 radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) { 64 radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) {
@@ -72,12 +78,18 @@ static void *tagged_iteration_fn(void *arg)
72 continue; 78 continue;
73 } 79 }
74 80
75 if (rand_r(&seeds[0]) % 50 == 0) 81 if (rand_r(&seeds[0]) % 50 == 0) {
76 slot = radix_tree_iter_next(&iter); 82 slot = radix_tree_iter_next(&iter);
83 rcu_read_unlock();
84 rcu_barrier();
85 rcu_read_lock();
86 }
77 } 87 }
78 rcu_read_unlock(); 88 rcu_read_unlock();
79 } 89 }
80 90
91 rcu_unregister_thread();
92
81 return NULL; 93 return NULL;
82} 94}
83 95
@@ -93,6 +105,8 @@ static void *untagged_iteration_fn(void *arg)
93 struct radix_tree_iter iter; 105 struct radix_tree_iter iter;
94 void **slot; 106 void **slot;
95 107
108 rcu_register_thread();
109
96 while (!test_complete) { 110 while (!test_complete) {
97 rcu_read_lock(); 111 rcu_read_lock();
98 radix_tree_for_each_slot(slot, &tree, &iter, 0) { 112 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
@@ -112,12 +126,18 @@ static void *untagged_iteration_fn(void *arg)
112 continue; 126 continue;
113 } 127 }
114 128
115 if (rand_r(&seeds[1]) % 50 == 0) 129 if (rand_r(&seeds[1]) % 50 == 0) {
116 slot = radix_tree_iter_next(&iter); 130 slot = radix_tree_iter_next(&iter);
131 rcu_read_unlock();
132 rcu_barrier();
133 rcu_read_lock();
134 }
117 } 135 }
118 rcu_read_unlock(); 136 rcu_read_unlock();
119 } 137 }
120 138
139 rcu_unregister_thread();
140
121 return NULL; 141 return NULL;
122} 142}
123 143
@@ -127,6 +147,8 @@ static void *untagged_iteration_fn(void *arg)
127 */ 147 */
128static void *remove_entries_fn(void *arg) 148static void *remove_entries_fn(void *arg)
129{ 149{
150 rcu_register_thread();
151
130 while (!test_complete) { 152 while (!test_complete) {
131 int pgoff; 153 int pgoff;
132 154
@@ -137,6 +159,8 @@ static void *remove_entries_fn(void *arg)
137 pthread_mutex_unlock(&tree_lock); 159 pthread_mutex_unlock(&tree_lock);
138 } 160 }
139 161
162 rcu_unregister_thread();
163
140 return NULL; 164 return NULL;
141} 165}
142 166