Commit ba20cd60 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

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.comSigned-off-by: default avatarMatthew Wilcox <mawilcox@microsoft.com>
Tested-by: default avatarKirill 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 061ef393
...@@ -29,6 +29,8 @@ static void *add_entries_fn(void *arg) ...@@ -29,6 +29,8 @@ static void *add_entries_fn(void *arg)
{ {
int pgoff; int pgoff;
rcu_register_thread();
while (!test_complete) { while (!test_complete) {
for (pgoff = 0; pgoff < 100; pgoff++) { for (pgoff = 0; pgoff < 100; pgoff++) {
pthread_mutex_lock(&tree_lock); pthread_mutex_lock(&tree_lock);
...@@ -38,6 +40,8 @@ static void *add_entries_fn(void *arg) ...@@ -38,6 +40,8 @@ static void *add_entries_fn(void *arg)
} }
} }
rcu_unregister_thread();
return NULL; return NULL;
} }
...@@ -53,6 +57,8 @@ static void *tagged_iteration_fn(void *arg) ...@@ -53,6 +57,8 @@ static void *tagged_iteration_fn(void *arg)
struct radix_tree_iter iter; struct radix_tree_iter iter;
void **slot; void **slot;
rcu_register_thread();
while (!test_complete) { while (!test_complete) {
rcu_read_lock(); rcu_read_lock();
radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) { radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) {
...@@ -72,12 +78,18 @@ static void *tagged_iteration_fn(void *arg) ...@@ -72,12 +78,18 @@ static void *tagged_iteration_fn(void *arg)
continue; continue;
} }
if (rand_r(&seeds[0]) % 50 == 0) if (rand_r(&seeds[0]) % 50 == 0) {
slot = radix_tree_iter_next(&iter); slot = radix_tree_iter_next(&iter);
rcu_read_unlock();
rcu_barrier();
rcu_read_lock();
}
} }
rcu_read_unlock(); rcu_read_unlock();
} }
rcu_unregister_thread();
return NULL; return NULL;
} }
...@@ -93,6 +105,8 @@ static void *untagged_iteration_fn(void *arg) ...@@ -93,6 +105,8 @@ static void *untagged_iteration_fn(void *arg)
struct radix_tree_iter iter; struct radix_tree_iter iter;
void **slot; void **slot;
rcu_register_thread();
while (!test_complete) { while (!test_complete) {
rcu_read_lock(); rcu_read_lock();
radix_tree_for_each_slot(slot, &tree, &iter, 0) { radix_tree_for_each_slot(slot, &tree, &iter, 0) {
...@@ -112,12 +126,18 @@ static void *untagged_iteration_fn(void *arg) ...@@ -112,12 +126,18 @@ static void *untagged_iteration_fn(void *arg)
continue; continue;
} }
if (rand_r(&seeds[1]) % 50 == 0) if (rand_r(&seeds[1]) % 50 == 0) {
slot = radix_tree_iter_next(&iter); slot = radix_tree_iter_next(&iter);
rcu_read_unlock();
rcu_barrier();
rcu_read_lock();
}
} }
rcu_read_unlock(); rcu_read_unlock();
} }
rcu_unregister_thread();
return NULL; return NULL;
} }
...@@ -127,6 +147,8 @@ static void *untagged_iteration_fn(void *arg) ...@@ -127,6 +147,8 @@ static void *untagged_iteration_fn(void *arg)
*/ */
static void *remove_entries_fn(void *arg) static void *remove_entries_fn(void *arg)
{ {
rcu_register_thread();
while (!test_complete) { while (!test_complete) {
int pgoff; int pgoff;
...@@ -137,6 +159,8 @@ static void *remove_entries_fn(void *arg) ...@@ -137,6 +159,8 @@ static void *remove_entries_fn(void *arg)
pthread_mutex_unlock(&tree_lock); pthread_mutex_unlock(&tree_lock);
} }
rcu_unregister_thread();
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment