提交 8a5956ad 编写于 作者: P Paolo Bonzini

rcu tests: fix compilation on 32-bit ppc

32-bit PPC cannot do atomic operations on long long.  Inside the loops,
we are already using local counters that are summed at the end of
the run---with some exceptions (rcu_stress_count for rcutorture,
n_nodes for test-rcu-list): fix them to use the same technique.
For test-rcu-list, remove the mostly unused member "val" from the
list.  Then, use a mutex to protect the global counts.

Performance does not matter there because every thread will only enter
the critical section once.

Remaining uses of atomic instructions are for ints or pointers.
Reported-by: NAndreas Faerber <afaerber@suse.de>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 549c4e49
...@@ -82,6 +82,7 @@ static volatile int goflag = GOFLAG_INIT; ...@@ -82,6 +82,7 @@ static volatile int goflag = GOFLAG_INIT;
#define RCU_READ_RUN 1000 #define RCU_READ_RUN 1000
#define NR_THREADS 100 #define NR_THREADS 100
static QemuMutex counts_mutex;
static QemuThread threads[NR_THREADS]; static QemuThread threads[NR_THREADS];
static struct rcu_reader_data *data[NR_THREADS]; static struct rcu_reader_data *data[NR_THREADS];
static int n_threads; static int n_threads;
...@@ -130,7 +131,9 @@ static void *rcu_read_perf_test(void *arg) ...@@ -130,7 +131,9 @@ static void *rcu_read_perf_test(void *arg)
} }
n_reads_local += RCU_READ_RUN; n_reads_local += RCU_READ_RUN;
} }
atomic_add(&n_reads, n_reads_local); qemu_mutex_lock(&counts_mutex);
n_reads += n_reads_local;
qemu_mutex_unlock(&counts_mutex);
rcu_unregister_thread(); rcu_unregister_thread();
return NULL; return NULL;
...@@ -151,7 +154,9 @@ static void *rcu_update_perf_test(void *arg) ...@@ -151,7 +154,9 @@ static void *rcu_update_perf_test(void *arg)
synchronize_rcu(); synchronize_rcu();
n_updates_local++; n_updates_local++;
} }
atomic_add(&n_updates, n_updates_local); qemu_mutex_lock(&counts_mutex);
n_updates += n_updates_local;
qemu_mutex_unlock(&counts_mutex);
rcu_unregister_thread(); rcu_unregister_thread();
return NULL; return NULL;
...@@ -241,6 +246,7 @@ static void *rcu_read_stress_test(void *arg) ...@@ -241,6 +246,7 @@ static void *rcu_read_stress_test(void *arg)
struct rcu_stress *p; struct rcu_stress *p;
int pc; int pc;
long long n_reads_local = 0; long long n_reads_local = 0;
long long rcu_stress_local[RCU_STRESS_PIPE_LEN + 1] = { 0 };
volatile int garbage = 0; volatile int garbage = 0;
rcu_register_thread(); rcu_register_thread();
...@@ -265,13 +271,18 @@ static void *rcu_read_stress_test(void *arg) ...@@ -265,13 +271,18 @@ static void *rcu_read_stress_test(void *arg)
if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) { if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {
pc = RCU_STRESS_PIPE_LEN; pc = RCU_STRESS_PIPE_LEN;
} }
atomic_inc(&rcu_stress_count[pc]); rcu_stress_local[pc]++;
n_reads_local++; n_reads_local++;
if ((++itercnt % 0x1000) == 0) { if ((++itercnt % 0x1000) == 0) {
synchronize_rcu(); synchronize_rcu();
} }
} }
atomic_add(&n_reads, n_reads_local); qemu_mutex_lock(&counts_mutex);
n_reads += n_reads_local;
for (i = 0; i <= RCU_STRESS_PIPE_LEN; i++) {
rcu_stress_count[i] += rcu_stress_local[i];
}
qemu_mutex_unlock(&counts_mutex);
rcu_unregister_thread(); rcu_unregister_thread();
return NULL; return NULL;
...@@ -419,6 +430,7 @@ int main(int argc, char *argv[]) ...@@ -419,6 +430,7 @@ int main(int argc, char *argv[])
int nreaders = 1; int nreaders = 1;
int duration = 1; int duration = 1;
qemu_mutex_init(&counts_mutex);
if (argc >= 2 && argv[1][0] == '-') { if (argc >= 2 && argv[1][0] == '-') {
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
if (g_test_quick()) { if (g_test_quick()) {
......
...@@ -35,16 +35,15 @@ ...@@ -35,16 +35,15 @@
* Test variables. * Test variables.
*/ */
long long n_reads = 0LL; static QemuMutex counts_mutex;
long long n_updates = 0LL; static long long n_reads = 0LL;
long long n_reclaims = 0LL; static long long n_updates = 0LL;
long long n_nodes_removed = 0LL; static long long n_reclaims = 0LL;
long long n_nodes = 0LL; static long long n_nodes_removed = 0LL;
int g_test_in_charge = 0; static long long n_nodes = 0LL;
static int g_test_in_charge = 0;
int nthreadsrunning; static int nthreadsrunning;
char argsbuf[64];
#define GOFLAG_INIT 0 #define GOFLAG_INIT 0
#define GOFLAG_RUN 1 #define GOFLAG_RUN 1
...@@ -92,21 +91,21 @@ static void wait_all_threads(void) ...@@ -92,21 +91,21 @@ static void wait_all_threads(void)
struct list_element { struct list_element {
QLIST_ENTRY(list_element) entry; QLIST_ENTRY(list_element) entry;
struct rcu_head rcu; struct rcu_head rcu;
long long val;
}; };
static void reclaim_list_el(struct rcu_head *prcu) static void reclaim_list_el(struct rcu_head *prcu)
{ {
struct list_element *el = container_of(prcu, struct list_element, rcu); struct list_element *el = container_of(prcu, struct list_element, rcu);
g_free(el); g_free(el);
atomic_add(&n_reclaims, 1); /* Accessed only from call_rcu thread. */
n_reclaims++;
} }
static QLIST_HEAD(q_list_head, list_element) Q_list_head; static QLIST_HEAD(q_list_head, list_element) Q_list_head;
static void *rcu_q_reader(void *arg) static void *rcu_q_reader(void *arg)
{ {
long long j, n_reads_local = 0; long long n_reads_local = 0;
struct list_element *el; struct list_element *el;
*(struct rcu_reader_data **)arg = &rcu_reader; *(struct rcu_reader_data **)arg = &rcu_reader;
...@@ -118,8 +117,6 @@ static void *rcu_q_reader(void *arg) ...@@ -118,8 +117,6 @@ static void *rcu_q_reader(void *arg)
while (goflag == GOFLAG_RUN) { while (goflag == GOFLAG_RUN) {
rcu_read_lock(); rcu_read_lock();
QLIST_FOREACH_RCU(el, &Q_list_head, entry) { QLIST_FOREACH_RCU(el, &Q_list_head, entry) {
j = atomic_read(&el->val);
(void)j;
n_reads_local++; n_reads_local++;
if (goflag == GOFLAG_STOP) { if (goflag == GOFLAG_STOP) {
break; break;
...@@ -129,7 +126,9 @@ static void *rcu_q_reader(void *arg) ...@@ -129,7 +126,9 @@ static void *rcu_q_reader(void *arg)
g_usleep(100); g_usleep(100);
} }
atomic_add(&n_reads, n_reads_local); qemu_mutex_lock(&counts_mutex);
n_reads += n_reads_local;
qemu_mutex_unlock(&counts_mutex);
return NULL; return NULL;
} }
...@@ -137,6 +136,7 @@ static void *rcu_q_reader(void *arg) ...@@ -137,6 +136,7 @@ static void *rcu_q_reader(void *arg)
static void *rcu_q_updater(void *arg) static void *rcu_q_updater(void *arg)
{ {
int j, target_el; int j, target_el;
long long n_nodes_local = 0;
long long n_updates_local = 0; long long n_updates_local = 0;
long long n_removed_local = 0; long long n_removed_local = 0;
struct list_element *el, *prev_el; struct list_element *el, *prev_el;
...@@ -170,8 +170,7 @@ static void *rcu_q_updater(void *arg) ...@@ -170,8 +170,7 @@ static void *rcu_q_updater(void *arg)
j++; j++;
if (target_el == j) { if (target_el == j) {
prev_el = g_new(struct list_element, 1); prev_el = g_new(struct list_element, 1);
atomic_add(&n_nodes, 1); n_nodes += n_nodes_local;
prev_el->val = atomic_read(&n_nodes);
QLIST_INSERT_BEFORE_RCU(el, prev_el, entry); QLIST_INSERT_BEFORE_RCU(el, prev_el, entry);
break; break;
} }
...@@ -181,8 +180,11 @@ static void *rcu_q_updater(void *arg) ...@@ -181,8 +180,11 @@ static void *rcu_q_updater(void *arg)
synchronize_rcu(); synchronize_rcu();
} }
synchronize_rcu(); synchronize_rcu();
atomic_add(&n_updates, n_updates_local); qemu_mutex_lock(&counts_mutex);
atomic_add(&n_nodes_removed, n_removed_local); n_nodes += n_nodes_local;
n_updates += n_updates_local;
n_nodes_removed += n_removed_local;
qemu_mutex_unlock(&counts_mutex);
return NULL; return NULL;
} }
...@@ -194,10 +196,11 @@ static void rcu_qtest_init(void) ...@@ -194,10 +196,11 @@ static void rcu_qtest_init(void)
srand(time(0)); srand(time(0));
for (i = 0; i < RCU_Q_LEN; i++) { for (i = 0; i < RCU_Q_LEN; i++) {
new_el = g_new(struct list_element, 1); new_el = g_new(struct list_element, 1);
new_el->val = i;
QLIST_INSERT_HEAD_RCU(&Q_list_head, new_el, entry); QLIST_INSERT_HEAD_RCU(&Q_list_head, new_el, entry);
} }
atomic_add(&n_nodes, RCU_Q_LEN); qemu_mutex_lock(&counts_mutex);
n_nodes += RCU_Q_LEN;
qemu_mutex_unlock(&counts_mutex);
} }
static void rcu_qtest_run(int duration, int nreaders) static void rcu_qtest_run(int duration, int nreaders)
...@@ -233,7 +236,9 @@ static void rcu_qtest(const char *test, int duration, int nreaders) ...@@ -233,7 +236,9 @@ static void rcu_qtest(const char *test, int duration, int nreaders)
call_rcu1(&prev_el->rcu, reclaim_list_el); call_rcu1(&prev_el->rcu, reclaim_list_el);
n_removed_local++; n_removed_local++;
} }
atomic_add(&n_nodes_removed, n_removed_local); qemu_mutex_lock(&counts_mutex);
n_nodes_removed += n_removed_local;
qemu_mutex_unlock(&counts_mutex);
synchronize_rcu(); synchronize_rcu();
while (n_nodes_removed > n_reclaims) { while (n_nodes_removed > n_reclaims) {
g_usleep(100); g_usleep(100);
...@@ -277,6 +282,7 @@ int main(int argc, char *argv[]) ...@@ -277,6 +282,7 @@ int main(int argc, char *argv[])
{ {
int duration = 0, readers = 0; int duration = 0, readers = 0;
qemu_mutex_init(&counts_mutex);
if (argc >= 2) { if (argc >= 2) {
if (argv[1][0] == '-') { if (argv[1][0] == '-') {
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册