aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorGravatar Matthew Wilcox <mawilcox@microsoft.com> 2016-12-14 15:08:11 -0800
committerGravatar Linus Torvalds <torvalds@linux-foundation.org> 2016-12-14 16:04:09 -0800
commitba20cd60c97945f0de9fe313f869b3a5855e1503 (patch)
tree35a39c27248705e7c736c9ee5bfa1d22d69a3a2e /tools
parentradix tree test suite: make runs more reproducible (diff)
downloadlinux-ba20cd60c97945f0de9fe313f869b3a5855e1503.tar.gz
linux-ba20cd60c97945f0de9fe313f869b3a5855e1503.tar.bz2
linux-ba20cd60c97945f0de9fe313f869b3a5855e1503.zip
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')
-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)
{
int pgoff;
+ rcu_register_thread();
+
while (!test_complete) {
for (pgoff = 0; pgoff < 100; pgoff++) {
pthread_mutex_lock(&tree_lock);
@@ -38,6 +40,8 @@ static void *add_entries_fn(void *arg)
}
}
+ rcu_unregister_thread();
+
return NULL;
}
@@ -53,6 +57,8 @@ static void *tagged_iteration_fn(void *arg)
struct radix_tree_iter iter;
void **slot;
+ rcu_register_thread();
+
while (!test_complete) {
rcu_read_lock();
radix_tree_for_each_tagged(slot, &tree, &iter, 0, TAG) {
@@ -72,12 +78,18 @@ static void *tagged_iteration_fn(void *arg)
continue;
}
- if (rand_r(&seeds[0]) % 50 == 0)
+ if (rand_r(&seeds[0]) % 50 == 0) {
slot = radix_tree_iter_next(&iter);
+ rcu_read_unlock();
+ rcu_barrier();
+ rcu_read_lock();
+ }
}
rcu_read_unlock();
}
+ rcu_unregister_thread();
+
return NULL;
}
@@ -93,6 +105,8 @@ static void *untagged_iteration_fn(void *arg)
struct radix_tree_iter iter;
void **slot;
+ rcu_register_thread();
+
while (!test_complete) {
rcu_read_lock();
radix_tree_for_each_slot(slot, &tree, &iter, 0) {
@@ -112,12 +126,18 @@ static void *untagged_iteration_fn(void *arg)
continue;
}
- if (rand_r(&seeds[1]) % 50 == 0)
+ if (rand_r(&seeds[1]) % 50 == 0) {
slot = radix_tree_iter_next(&iter);
+ rcu_read_unlock();
+ rcu_barrier();
+ rcu_read_lock();
+ }
}
rcu_read_unlock();
}
+ rcu_unregister_thread();
+
return NULL;
}
@@ -127,6 +147,8 @@ static void *untagged_iteration_fn(void *arg)
*/
static void *remove_entries_fn(void *arg)
{
+ rcu_register_thread();
+
while (!test_complete) {
int pgoff;
@@ -137,6 +159,8 @@ static void *remove_entries_fn(void *arg)
pthread_mutex_unlock(&tree_lock);
}
+ rcu_unregister_thread();
+
return NULL;
}