mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
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>
This commit is contained in:
parent
061ef3936b
commit
ba20cd60c9
1 changed files with 26 additions and 2 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rcu_unregister_thread();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
pthread_mutex_unlock(&tree_lock);
|
pthread_mutex_unlock(&tree_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rcu_unregister_thread();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue