Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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: 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
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -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;
}