From: "Emilio G. Cota" <cota@braap.org>
To: Richard Henderson <rth@twiddle.net>
Cc: alex.bennee@linaro.org, mttcg@greensocs.com,
qemu-devel@nongnu.org, fred.konrad@greensocs.com,
a.rigo@virtualopensystems.com, bobby.prani@gmail.com,
nikunj@linux.vnet.ibm.com, mark.burton@greensocs.com,
pbonzini@redhat.com, jan.kiszka@siemens.com,
serge.fdrv@gmail.com, peter.maydell@linaro.org,
claudio.fontana@huawei.com, dgilbert@redhat.com,
crosthwaite.peter@gmail.com
Subject: [Qemu-devel] [PATCH 1/8] cpu list: convert to RCU QLIST
Date: Wed, 24 Aug 2016 18:17:56 -0400 [thread overview]
Message-ID: <1472077083-15022-1-git-send-email-cota@braap.org> (raw)
In-Reply-To: <20160824211240.GA26546@flamenco>
This avoids the chance of reading a corrupted list of CPUs in usermode.
Note: this breaks hw/ppc/spapr due to the removal of CPU_FOREACH_REVERSE.
Signed-off-by: Emilio G. Cota <cota@braap.org>
---
cpus.c | 2 +-
exec.c | 18 +++++++++++++++---
include/qom/cpu.h | 16 +++++++---------
linux-user/main.c | 2 +-
linux-user/syscall.c | 2 +-
5 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/cpus.c b/cpus.c
index a01bbbd..bc573be 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1177,7 +1177,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
}
}
- qemu_tcg_wait_io_event(QTAILQ_FIRST(&cpus));
+ qemu_tcg_wait_io_event(first_cpu);
CPU_FOREACH(cpu) {
if (cpu->unplug && !cpu_can_run(cpu)) {
remove_cpu = cpu;
diff --git a/exec.c b/exec.c
index 806e2fe..70dd869 100644
--- a/exec.c
+++ b/exec.c
@@ -93,7 +93,7 @@ static MemoryRegion io_mem_unassigned;
#endif
-struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
+struct CPUTailQ cpus = QLIST_HEAD_INITIALIZER(cpus);
/* current CPU in the current thread. It is only valid inside
cpu_exec() */
__thread CPUState *current_cpu;
@@ -651,7 +651,7 @@ void cpu_exec_exit(CPUState *cpu)
return;
}
- QTAILQ_REMOVE(&cpus, cpu, node);
+ QLIST_REMOVE_RCU(cpu, node);
cpu_release_index(cpu);
cpu->cpu_index = -1;
#if defined(CONFIG_USER_ONLY)
@@ -703,7 +703,19 @@ void cpu_exec_init(CPUState *cpu, Error **errp)
#endif
return;
}
- QTAILQ_INSERT_TAIL(&cpus, cpu, node);
+ /* poor man's QLIST_INSERT_TAIL_RCU */
+ if (QLIST_EMPTY_RCU(&cpus)) {
+ QLIST_INSERT_HEAD_RCU(&cpus, cpu, node);
+ } else {
+ CPUState *some_cpu;
+
+ CPU_FOREACH(some_cpu) {
+ if (QLIST_NEXT_RCU(some_cpu, node) == NULL) {
+ QLIST_INSERT_AFTER_RCU(some_cpu, cpu, node);
+ break;
+ }
+ }
+ }
#if defined(CONFIG_USER_ONLY)
(void) cc;
cpu_list_unlock();
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 32f3af3..eba48ed 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -24,7 +24,7 @@
#include "disas/bfd.h"
#include "exec/hwaddr.h"
#include "exec/memattrs.h"
-#include "qemu/queue.h"
+#include "qemu/rcu_queue.h"
#include "qemu/thread.h"
typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
@@ -319,7 +319,7 @@ struct CPUState {
struct GDBRegisterState *gdb_regs;
int gdb_num_regs;
int gdb_num_g_regs;
- QTAILQ_ENTRY(CPUState) node;
+ QLIST_ENTRY(CPUState) node;
/* ice debug support */
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;
@@ -362,15 +362,13 @@ struct CPUState {
uint32_t tcg_exit_req;
};
-QTAILQ_HEAD(CPUTailQ, CPUState);
+QLIST_HEAD(CPUTailQ, CPUState);
extern struct CPUTailQ cpus;
-#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
-#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
+#define CPU_NEXT(cpu) QLIST_NEXT_RCU(cpu, node)
+#define CPU_FOREACH(cpu) QLIST_FOREACH_RCU(cpu, &cpus, node)
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
- QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
-#define CPU_FOREACH_REVERSE(cpu) \
- QTAILQ_FOREACH_REVERSE(cpu, &cpus, CPUTailQ, node)
-#define first_cpu QTAILQ_FIRST(&cpus)
+ QLIST_FOREACH_SAFE_RCU(cpu, &cpus, node, next_cpu)
+#define first_cpu QLIST_FIRST_RCU(&cpus)
extern __thread CPUState *current_cpu;
diff --git a/linux-user/main.c b/linux-user/main.c
index f2f7422..9880505 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -131,7 +131,7 @@ void fork_end(int child)
Discard information about the parent threads. */
CPU_FOREACH_SAFE(cpu, next_cpu) {
if (cpu != thread_cpu) {
- QTAILQ_REMOVE(&cpus, cpu, node);
+ QLIST_REMOVE_RCU(cpu, node);
}
}
pending_cpus = 0;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1c17b74..2911319 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6710,7 +6710,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
cpu_list_lock();
/* Remove the CPU from the list. */
- QTAILQ_REMOVE(&cpus, cpu, node);
+ QLIST_REMOVE_RCU(cpu, node);
cpu_list_unlock();
ts = cpu->opaque;
if (ts->child_tidptr) {
--
2.5.0
next prev parent reply other threads:[~2016-08-24 22:18 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-15 10:46 [Qemu-devel] MTTCG status updates, benchmark results and KVM forum plans Alex Bennée
2016-08-15 11:00 ` Peter Maydell
2016-08-15 11:16 ` Alex Bennée
2016-08-15 15:46 ` Emilio G. Cota
2016-08-15 15:49 ` [Qemu-devel] [PATCH] aarch64: use TSX for ldrex/strex Emilio G. Cota
2016-08-17 17:22 ` Richard Henderson
2016-08-17 17:58 ` Emilio G. Cota
2016-08-17 18:18 ` Emilio G. Cota
2016-08-17 18:41 ` Richard Henderson
2016-08-18 15:38 ` Richard Henderson
2016-08-24 21:12 ` Emilio G. Cota
2016-08-24 22:17 ` Emilio G. Cota [this message]
2016-08-24 22:17 ` [Qemu-devel] [PATCH 2/8] cpu-exec: remove tb_lock from hot path Emilio G. Cota
2016-08-24 22:17 ` [Qemu-devel] [PATCH 3/8] rcu: add rcu_read_lock_held() Emilio G. Cota
2016-08-24 22:17 ` [Qemu-devel] [PATCH 4/8] target-arm: helper fixup for paired atomics Emilio G. Cota
2016-08-24 22:18 ` [Qemu-devel] [PATCH 5/8] linux-user: add stop-the-world to be called from CPU loop Emilio G. Cota
2016-08-24 22:18 ` [Qemu-devel] [PATCH 6/8] htm: add header to abstract Hardware Transactional Memory intrinsics Emilio G. Cota
2016-08-24 22:18 ` [Qemu-devel] [PATCH 7/8] htm: add powerpc64 intrinsics Emilio G. Cota
2016-08-24 22:18 ` [Qemu-devel] [PATCH 8/8] target-arm/a64: use HTM with stop-the-world fall-back path Emilio G. Cota
2016-08-16 11:16 ` [Qemu-devel] MTTCG status updates, benchmark results and KVM forum plans Alex Bennée
2016-08-16 21:51 ` Emilio G. Cota
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1472077083-15022-1-git-send-email-cota@braap.org \
--to=cota@braap.org \
--cc=a.rigo@virtualopensystems.com \
--cc=alex.bennee@linaro.org \
--cc=bobby.prani@gmail.com \
--cc=claudio.fontana@huawei.com \
--cc=crosthwaite.peter@gmail.com \
--cc=dgilbert@redhat.com \
--cc=fred.konrad@greensocs.com \
--cc=jan.kiszka@siemens.com \
--cc=mark.burton@greensocs.com \
--cc=mttcg@greensocs.com \
--cc=nikunj@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
--cc=serge.fdrv@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.