From patchwork Sun Mar 22 08:26:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 453105 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AA90114007F for ; Sun, 22 Mar 2015 19:27:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=gmail.com header.i=@gmail.com header.b=VmScizCG; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: from localhost ([::1]:50176 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YZbEA-0001gs-8j for incoming@patchwork.ozlabs.org; Sun, 22 Mar 2015 04:27:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59065) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YZbDr-0001Q4-Ua for qemu-devel@nongnu.org; Sun, 22 Mar 2015 04:27:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YZbDm-0005oA-MS for qemu-devel@nongnu.org; Sun, 22 Mar 2015 04:27:03 -0400 Received: from mail-wi0-x22a.google.com ([2a00:1450:400c:c05::22a]:33425) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YZbDm-0005nZ-C9 for qemu-devel@nongnu.org; Sun, 22 Mar 2015 04:26:58 -0400 Received: by wixw10 with SMTP id w10so16798463wix.0 for ; Sun, 22 Mar 2015 01:26:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=ndyLTROEAV+4WmU3h+ZAtOekG2qMfbNBnJEr3jswPn0=; b=VmScizCG35Nvf6+w7QCvQc5Z2vdJ5Z90y4RKrXacTi7xiUm5ZPGpphk0IKEeJdsfR4 TTAWFi5sM0jszbAkNlyrrDxIPNToyriMxmzDrUQnm5yRSWkWkGW1qw7dIC6VsOUC9Hkb T7YmwIJIJ4ctMZHU2qgKfjIF3Jqrgy19KaVb7cC0K9TPjen/d5e4Xx+MxG+F+qeIbpGJ 59q8mptV5pMb5+cLHMpTbNacucTXq5npowUh3sWXAsnt7H7TnZKgLY/+56EWTH0vSTAx VWgL21JiQFDCy446Y7ZEgGTJCqRsCwMbUxknFarDX/57vNnTsnQtQIkdjecN2OlwhgS6 Xv2g== X-Received: by 10.194.185.9 with SMTP id ey9mr177647118wjc.135.1427012817698; Sun, 22 Mar 2015 01:26:57 -0700 (PDT) Received: from donizetti.station (net-93-66-123-41.cust.vodafonedsl.it. [93.66.123.41]) by mx.google.com with ESMTPSA id ev7sm13893225wjb.47.2015.03.22.01.26.55 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 22 Mar 2015 01:26:56 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Sun, 22 Mar 2015 09:26:50 +0100 Message-Id: <1427012810-8400-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 2.3.3 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::22a Cc: afaerber@suse.de Subject: [Qemu-devel] [PATCH v3] rcu tests: fix compilation on 32-bit ppc X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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: Andreas Faerber Signed-off-by: Paolo Bonzini Reviewed-by: Fam Zheng Tested-by: Andreas Färber --- tests/rcutorture.c | 20 ++++++++++++++++---- tests/test-rcu-list.c | 50 ++++++++++++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/tests/rcutorture.c b/tests/rcutorture.c index 60a2ccf..d6b304d 100644 --- a/tests/rcutorture.c +++ b/tests/rcutorture.c @@ -82,6 +82,7 @@ static volatile int goflag = GOFLAG_INIT; #define RCU_READ_RUN 1000 #define NR_THREADS 100 +static QemuMutex counts_mutex; static QemuThread threads[NR_THREADS]; static struct rcu_reader_data *data[NR_THREADS]; static int n_threads; @@ -130,7 +131,9 @@ static void *rcu_read_perf_test(void *arg) } 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(); return NULL; @@ -151,7 +154,9 @@ static void *rcu_update_perf_test(void *arg) synchronize_rcu(); 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(); return NULL; @@ -241,6 +246,7 @@ static void *rcu_read_stress_test(void *arg) struct rcu_stress *p; int pc; long long n_reads_local = 0; + long long rcu_stress_local[RCU_STRESS_PIPE_LEN + 1] = { 0 }; volatile int garbage = 0; rcu_register_thread(); @@ -265,13 +271,18 @@ static void *rcu_read_stress_test(void *arg) if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) { pc = RCU_STRESS_PIPE_LEN; } - atomic_inc(&rcu_stress_count[pc]); + rcu_stress_local[pc]++; n_reads_local++; if ((++itercnt % 0x1000) == 0) { 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(); return NULL; @@ -419,6 +430,7 @@ int main(int argc, char *argv[]) int nreaders = 1; int duration = 1; + qemu_mutex_init(&counts_mutex); if (argc >= 2 && argv[1][0] == '-') { g_test_init(&argc, &argv, NULL); if (g_test_quick()) { diff --git a/tests/test-rcu-list.c b/tests/test-rcu-list.c index 46b5e26..4c5f62e 100644 --- a/tests/test-rcu-list.c +++ b/tests/test-rcu-list.c @@ -35,16 +35,15 @@ * Test variables. */ -long long n_reads = 0LL; -long long n_updates = 0LL; -long long n_reclaims = 0LL; -long long n_nodes_removed = 0LL; -long long n_nodes = 0LL; -int g_test_in_charge = 0; +static QemuMutex counts_mutex; +static long long n_reads = 0LL; +static long long n_updates = 0LL; +static long long n_reclaims = 0LL; +static long long n_nodes_removed = 0LL; +static long long n_nodes = 0LL; +static int g_test_in_charge = 0; -int nthreadsrunning; - -char argsbuf[64]; +static int nthreadsrunning; #define GOFLAG_INIT 0 #define GOFLAG_RUN 1 @@ -92,21 +91,21 @@ static void wait_all_threads(void) struct list_element { QLIST_ENTRY(list_element) entry; struct rcu_head rcu; - long long val; }; static void reclaim_list_el(struct rcu_head *prcu) { struct list_element *el = container_of(prcu, struct list_element, rcu); 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 void *rcu_q_reader(void *arg) { - long long j, n_reads_local = 0; + long long n_reads_local = 0; struct list_element *el; *(struct rcu_reader_data **)arg = &rcu_reader; @@ -118,8 +117,6 @@ static void *rcu_q_reader(void *arg) while (goflag == GOFLAG_RUN) { rcu_read_lock(); QLIST_FOREACH_RCU(el, &Q_list_head, entry) { - j = atomic_read(&el->val); - (void)j; n_reads_local++; if (goflag == GOFLAG_STOP) { break; @@ -129,7 +126,9 @@ static void *rcu_q_reader(void *arg) 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; } @@ -137,6 +136,7 @@ static void *rcu_q_reader(void *arg) static void *rcu_q_updater(void *arg) { int j, target_el; + long long n_nodes_local = 0; long long n_updates_local = 0; long long n_removed_local = 0; struct list_element *el, *prev_el; @@ -170,8 +170,7 @@ static void *rcu_q_updater(void *arg) j++; if (target_el == j) { prev_el = g_new(struct list_element, 1); - atomic_add(&n_nodes, 1); - prev_el->val = atomic_read(&n_nodes); + n_nodes += n_nodes_local; QLIST_INSERT_BEFORE_RCU(el, prev_el, entry); break; } @@ -181,8 +180,11 @@ static void *rcu_q_updater(void *arg) synchronize_rcu(); } synchronize_rcu(); - atomic_add(&n_updates, n_updates_local); - atomic_add(&n_nodes_removed, n_removed_local); + qemu_mutex_lock(&counts_mutex); + n_nodes += n_nodes_local; + n_updates += n_updates_local; + n_nodes_removed += n_removed_local; + qemu_mutex_unlock(&counts_mutex); return NULL; } @@ -194,10 +196,11 @@ static void rcu_qtest_init(void) srand(time(0)); for (i = 0; i < RCU_Q_LEN; i++) { new_el = g_new(struct list_element, 1); - new_el->val = i; 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) @@ -233,7 +236,9 @@ static void rcu_qtest(const char *test, int duration, int nreaders) call_rcu1(&prev_el->rcu, reclaim_list_el); 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(); while (n_nodes_removed > n_reclaims) { g_usleep(100); @@ -277,6 +282,7 @@ int main(int argc, char *argv[]) { int duration = 0, readers = 0; + qemu_mutex_init(&counts_mutex); if (argc >= 2) { if (argv[1][0] == '-') { g_test_init(&argc, &argv, NULL);