aboutsummaryrefslogtreecommitdiff
path: root/tests/rcutorture.c
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2020-02-25 12:46:55 +0000
committerAlex Bennée <alex.bennee@linaro.org>2020-02-25 17:42:59 +0000
commita74c82c8dc73560d856dfabd22a6abb40ac907dc (patch)
tree6ab9a80460a5f218fb2ce4d0f6e242c05ccd70fc /tests/rcutorture.c
parentea70ccff651d10625cb051521d7ac029874008c3 (diff)
downloadqemu-a74c82c8dc73560d856dfabd22a6abb40ac907dc.zip
qemu-a74c82c8dc73560d856dfabd22a6abb40ac907dc.tar.gz
qemu-a74c82c8dc73560d856dfabd22a6abb40ac907dc.tar.bz2
tests/rcutorture: mild documenting refactor of update thread
This is mainly to help with reasoning what the test is trying to do. We can move rcu_stress_idx to a local variable as there is only ever one updater thread. I've also added an assert to catch the case where we end up updating the current structure to itself which is the only way I can see the mberror cases we are seeing on Travis. We shall see if the rcutorture test failures go away now. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20200225124710.14152-5-alex.bennee@linaro.org>
Diffstat (limited to 'tests/rcutorture.c')
-rw-r--r--tests/rcutorture.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/tests/rcutorture.c b/tests/rcutorture.c
index 256d24e..732f03a 100644
--- a/tests/rcutorture.c
+++ b/tests/rcutorture.c
@@ -230,13 +230,12 @@ static void uperftest(int nupdaters, int duration)
#define RCU_STRESS_PIPE_LEN 10
struct rcu_stress {
- int pipe_count;
+ int age; /* how many update cycles while not rcu_stress_current */
int mbtest;
};
struct rcu_stress rcu_stress_array[RCU_STRESS_PIPE_LEN] = { { 0 } };
struct rcu_stress *rcu_stress_current;
-int rcu_stress_idx;
int n_mberror;
/* Updates protected by counts_mutex */
@@ -261,7 +260,7 @@ static void *rcu_read_stress_test(void *arg)
while (goflag == GOFLAG_RUN) {
rcu_read_lock();
p = atomic_rcu_read(&rcu_stress_current);
- if (p->mbtest == 0) {
+ if (atomic_read(&p->mbtest) == 0) {
n_mberror++;
}
rcu_read_lock();
@@ -269,7 +268,7 @@ static void *rcu_read_stress_test(void *arg)
garbage++;
}
rcu_read_unlock();
- pc = p->pipe_count;
+ pc = atomic_read(&p->age);
rcu_read_unlock();
if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {
pc = RCU_STRESS_PIPE_LEN;
@@ -288,32 +287,52 @@ static void *rcu_read_stress_test(void *arg)
return NULL;
}
+/*
+ * Stress Test Updater
+ *
+ * The updater cycles around updating rcu_stress_current to point at
+ * one of the rcu_stress_array_entries and resets it's age. It
+ * then increments the age of all the other entries. The age
+ * will be read under an rcu_read_lock() and distribution of values
+ * calculated. The final result gives an indication of how many
+ * previously current rcu_stress entries are in flight until the RCU
+ * cycle complete.
+ */
static void *rcu_update_stress_test(void *arg)
{
- int i;
- struct rcu_stress *p;
+ int i, rcu_stress_idx = 0;
+ struct rcu_stress *cp = atomic_read(&rcu_stress_current);
rcu_register_thread();
-
*(struct rcu_reader_data **)arg = &rcu_reader;
+
while (goflag == GOFLAG_INIT) {
g_usleep(1000);
}
+
while (goflag == GOFLAG_RUN) {
- i = rcu_stress_idx + 1;
- if (i >= RCU_STRESS_PIPE_LEN) {
- i = 0;
+ struct rcu_stress *p;
+ rcu_stress_idx++;
+ if (rcu_stress_idx >= RCU_STRESS_PIPE_LEN) {
+ rcu_stress_idx = 0;
}
- p = &rcu_stress_array[i];
- p->mbtest = 0;
+ p = &rcu_stress_array[rcu_stress_idx];
+ /* catching up with ourselves would be a bug */
+ assert(p != cp);
+ atomic_set(&p->mbtest, 0);
smp_mb();
- p->pipe_count = 0;
- p->mbtest = 1;
+ atomic_set(&p->age, 0);
+ atomic_set(&p->mbtest, 1);
atomic_rcu_set(&rcu_stress_current, p);
- rcu_stress_idx = i;
+ cp = p;
+ /*
+ * New RCU structure is now live, update pipe counts on old
+ * ones.
+ */
for (i = 0; i < RCU_STRESS_PIPE_LEN; i++) {
if (i != rcu_stress_idx) {
- rcu_stress_array[i].pipe_count++;
+ atomic_set(&rcu_stress_array[i].age,
+ rcu_stress_array[i].age + 1);
}
}
synchronize_rcu();
@@ -346,7 +365,7 @@ static void stresstest(int nreaders, int duration)
int i;
rcu_stress_current = &rcu_stress_array[0];
- rcu_stress_current->pipe_count = 0;
+ rcu_stress_current->age = 0;
rcu_stress_current->mbtest = 1;
for (i = 0; i < nreaders; i++) {
create_thread(rcu_read_stress_test);
@@ -376,7 +395,7 @@ static void gtest_stress(int nreaders, int duration)
int i;
rcu_stress_current = &rcu_stress_array[0];
- rcu_stress_current->pipe_count = 0;
+ rcu_stress_current->age = 0;
rcu_stress_current->mbtest = 1;
for (i = 0; i < nreaders; i++) {
create_thread(rcu_read_stress_test);