From: Ilya Leoshkevich <iii@linux.ibm.com>
To: "Richard Henderson" <richard.henderson@linaro.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>
Cc: qemu-devel@nongnu.org, Ilya Leoshkevich <iii@linux.ibm.com>
Subject: [PATCH 10/18] cpu: Use BQL in qemu-user
Date: Mon, 23 Sep 2024 18:13:05 +0200 [thread overview]
Message-ID: <20240923162208.90745-11-iii@linux.ibm.com> (raw)
In-Reply-To: <20240923162208.90745-1-iii@linux.ibm.com>
Currently BQL is stubbed out in qemu-user. However, enabling the
ability to pause and resume CPUs requires BQL, so introduce it.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
accel/tcg/user-exec.c | 2 ++
bsd-user/freebsd/os-syscall.c | 6 ++++
bsd-user/main.c | 2 ++
cpu-common.c | 45 ++++++++++++++++++++++++++++++
gdbstub/user.c | 5 ++++
linux-user/main.c | 3 ++
linux-user/syscall.c | 6 ++++
system/cpus.c | 52 ++---------------------------------
8 files changed, 72 insertions(+), 49 deletions(-)
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index ca3e8e988ee..d56882c87f3 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -1293,9 +1293,11 @@ int cpu_exec_user(CPUState *cs)
{
int trapnr;
+ bql_unlock();
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
cpu_exec_end(cs);
+ bql_lock();
process_queued_cpu_work(cs);
return trapnr;
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index ca2f6fdb66e..c2849d43223 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -32,6 +32,7 @@
#include "qemu.h"
#include "signal-common.h"
#include "user/syscall-trace.h"
+#include "qemu/main-loop.h"
/* BSD independent syscall shims */
#include "bsd-file.h"
@@ -935,16 +936,21 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
{
abi_long ret;
+ bql_unlock();
+
if (do_strace) {
print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
}
ret = freebsd_syscall(cpu_env, num, arg1, arg2, arg3, arg4, arg5, arg6,
arg7, arg8);
+
if (do_strace) {
print_freebsd_syscall_ret(num, ret);
}
+ bql_lock();
+
return ret;
}
diff --git a/bsd-user/main.c b/bsd-user/main.c
index cc980e6f401..ba5b54c228d 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -48,6 +48,7 @@
#include "qemu/guest-random.h"
#include "gdbstub/user.h"
#include "exec/page-vary.h"
+#include "qemu/main-loop.h"
#include "host-os.h"
#include "target_arch_cpu.h"
@@ -616,6 +617,7 @@ int main(int argc, char **argv)
target_cpu_init(env, regs);
+ bql_lock();
if (gdbstub) {
gdbserver_start(gdbstub);
gdb_handlesig(cpu, 0, NULL, NULL, 0);
diff --git a/cpu-common.c b/cpu-common.c
index 6b262233a3b..cb7c10a3915 100644
--- a/cpu-common.c
+++ b/cpu-common.c
@@ -452,3 +452,48 @@ void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
}
}
}
+
+/* The Big QEMU Lock (BQL) */
+static QemuMutex bql = QEMU_MUTEX_INITIALIZER;
+
+QEMU_DEFINE_STATIC_CO_TLS(bool, bql_locked)
+
+bool bql_locked(void)
+{
+ return get_bql_locked();
+}
+
+/*
+ * The BQL is taken from so many places that it is worth profiling the
+ * callers directly, instead of funneling them all through a single function.
+ */
+void bql_lock_impl(const char *file, int line)
+{
+ QemuMutexLockFunc bql_lock_fn = qatomic_read(&bql_mutex_lock_func);
+
+ g_assert(!bql_locked());
+ bql_lock_fn(&bql, file, line);
+ set_bql_locked(true);
+}
+
+void bql_unlock(void)
+{
+ g_assert(bql_locked());
+ set_bql_locked(false);
+ qemu_mutex_unlock(&bql);
+}
+
+void qemu_cond_wait_bql(QemuCond *cond)
+{
+ qemu_cond_wait(cond, &bql);
+}
+
+void qemu_cond_timedwait_bql(QemuCond *cond, int ms)
+{
+ qemu_cond_timedwait(cond, &bql, ms);
+}
+
+void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
+{
+ do_run_on_cpu(cpu, func, data, &bql);
+}
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 77ba227fc3b..82007b09db6 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/cutils.h"
+#include "qemu/main-loop.h"
#include "qemu/sockets.h"
#include "exec/hwaddr.h"
#include "exec/tb-flush.h"
@@ -169,6 +170,8 @@ void gdb_exit(int code)
{
char buf[4];
+ BQL_LOCK_GUARD();
+
if (!gdbserver_state.init) {
return;
}
@@ -464,6 +467,8 @@ void gdbserver_fork_end(CPUState *cpu, pid_t pid)
char b;
int fd;
+ BQL_LOCK_GUARD();
+
if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
return;
}
diff --git a/linux-user/main.c b/linux-user/main.c
index 8143a0d4b02..016f60bf3dc 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -57,6 +57,7 @@
#include "user-mmap.h"
#include "tcg/perf.h"
#include "exec/page-vary.h"
+#include "qemu/main-loop.h"
#ifdef CONFIG_SEMIHOSTING
#include "semihosting/semihost.h"
@@ -1011,6 +1012,8 @@ int main(int argc, char **argv, char **envp)
target_cpu_copy_regs(env, regs);
+ bql_lock();
+
if (gdbstub) {
if (gdbserver_start(gdbstub) < 0) {
fprintf(stderr, "qemu: could not open gdbserver on %s\n",
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b693aeff5bb..ff34ae11340 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -144,6 +144,7 @@
#include "qapi/error.h"
#include "fd-trans.h"
#include "cpu_loop-common.h"
+#include "qemu/main-loop.h"
#ifndef CLONE_IO
#define CLONE_IO 0x80000000 /* Clone io context */
@@ -6529,6 +6530,7 @@ static void *clone_func(void *arg)
/* Wait until the parent has finished initializing the tls state. */
pthread_mutex_lock(&clone_lock);
pthread_mutex_unlock(&clone_lock);
+ bql_lock();
cpu_loop(env);
/* never exits */
return NULL;
@@ -13772,6 +13774,8 @@ abi_long do_syscall(CPUArchState *cpu_env, int num, abi_long arg1,
record_syscall_start(cpu, num, arg1,
arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+ bql_unlock();
+
if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
print_syscall(cpu_env, num, arg1, arg2, arg3, arg4, arg5, arg6);
}
@@ -13784,6 +13788,8 @@ abi_long do_syscall(CPUArchState *cpu_env, int num, abi_long arg1,
arg3, arg4, arg5, arg6);
}
+ bql_lock();
+
record_syscall_return(cpu, num, ret);
return ret;
}
diff --git a/system/cpus.c b/system/cpus.c
index 1c818ff6828..fe84b822798 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -65,9 +65,6 @@
#endif /* CONFIG_LINUX */
-/* The Big QEMU Lock (BQL) */
-static QemuMutex bql;
-
/*
* The chosen accelerator is supposed to register this.
*/
@@ -420,16 +417,10 @@ void qemu_init_cpu_loop(void)
qemu_init_sigbus();
qemu_cond_init(&qemu_cpu_cond);
qemu_cond_init(&qemu_pause_cond);
- qemu_mutex_init(&bql);
qemu_thread_get_self(&io_thread);
}
-void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
-{
- do_run_on_cpu(cpu, func, data, &bql);
-}
-
static void qemu_cpu_stop(CPUState *cpu, bool exit)
{
g_assert(qemu_cpu_is_self(cpu));
@@ -459,7 +450,7 @@ void qemu_wait_io_event(CPUState *cpu)
slept = true;
qemu_plugin_vcpu_idle_cb(cpu);
}
- qemu_cond_wait(cpu->halt_cond, &bql);
+ qemu_cond_wait_bql(cpu->halt_cond);
}
if (slept) {
qemu_plugin_vcpu_resume_cb(cpu);
@@ -512,48 +503,11 @@ bool qemu_in_vcpu_thread(void)
return current_cpu && qemu_cpu_is_self(current_cpu);
}
-QEMU_DEFINE_STATIC_CO_TLS(bool, bql_locked)
-
-bool bql_locked(void)
-{
- return get_bql_locked();
-}
-
bool qemu_in_main_thread(void)
{
return bql_locked();
}
-/*
- * The BQL is taken from so many places that it is worth profiling the
- * callers directly, instead of funneling them all through a single function.
- */
-void bql_lock_impl(const char *file, int line)
-{
- QemuMutexLockFunc bql_lock_fn = qatomic_read(&bql_mutex_lock_func);
-
- g_assert(!bql_locked());
- bql_lock_fn(&bql, file, line);
- set_bql_locked(true);
-}
-
-void bql_unlock(void)
-{
- g_assert(bql_locked());
- set_bql_locked(false);
- qemu_mutex_unlock(&bql);
-}
-
-void qemu_cond_wait_bql(QemuCond *cond)
-{
- qemu_cond_wait(cond, &bql);
-}
-
-void qemu_cond_timedwait_bql(QemuCond *cond, int ms)
-{
- qemu_cond_timedwait(cond, &bql, ms);
-}
-
/* signal CPU creation */
void cpu_thread_signal_created(CPUState *cpu)
{
@@ -613,7 +567,7 @@ void pause_all_vcpus(void)
replay_mutex_unlock();
while (!all_vcpus_paused()) {
- qemu_cond_wait(&qemu_pause_cond, &bql);
+ qemu_cond_wait_bql(&qemu_pause_cond);
CPU_FOREACH(cpu) {
qemu_cpu_kick(cpu);
}
@@ -684,7 +638,7 @@ void qemu_init_vcpu(CPUState *cpu)
cpus_accel->create_vcpu_thread(cpu);
while (!cpu->created) {
- qemu_cond_wait(&qemu_cpu_cond, &bql);
+ qemu_cond_wait_bql(&qemu_cpu_cond);
}
}
--
2.46.0
next prev parent reply other threads:[~2024-09-23 16:30 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-23 16:12 [PATCH 00/18] Stop all qemu-cpu threads on a breakpoint Ilya Leoshkevich
2024-09-23 16:12 ` [PATCH 01/18] gdbstub: Make gdb_get_char() static Ilya Leoshkevich
2024-10-05 19:20 ` Richard Henderson
2024-09-23 16:12 ` [PATCH 02/18] gdbstub: Move phy_memory_mode to GDBSystemState Ilya Leoshkevich
2024-10-05 19:21 ` Richard Henderson
2024-09-23 16:12 ` [PATCH 03/18] gdbstub: Move gdb_syscall_mode to GDBSyscallState Ilya Leoshkevich
2024-10-05 19:22 ` Richard Henderson
2024-09-23 16:12 ` [PATCH 04/18] gdbstub: Factor out gdb_try_stop() Ilya Leoshkevich
2024-10-05 19:26 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 05/18] accel/tcg: Factor out cpu_exec_user() Ilya Leoshkevich
2024-10-05 19:29 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 06/18] qemu-thread: Introduce QEMU_MUTEX_INITIALIZER Ilya Leoshkevich
2024-10-05 19:30 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 07/18] qemu-thread: Introduce QEMU_COND_INITIALIZER Ilya Leoshkevich
2024-10-05 19:30 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 08/18] replay: Add replay_mutex_{lock, unlock}() stubs for qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 09/18] qemu-timer: Provide qemu_clock_enable() stub " Ilya Leoshkevich
2024-09-23 16:13 ` Ilya Leoshkevich [this message]
2024-09-23 16:13 ` [PATCH 11/18] accel/tcg: Unify user implementations of qemu_cpu_kick() Ilya Leoshkevich
2024-10-05 19:31 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 12/18] cpu: Track CPUs executing syscalls Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 13/18] cpu: Implement cpu_thread_is_idle() for qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 14/18] cpu: Introduce cpu_is_paused() Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 15/18] cpu: Set current_cpu early in qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 16/18] cpu: Allow pausing and resuming CPUs " Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 17/18] gdbstub: Pause all CPUs before sending stop replies Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 18/18] tests/tcg: Stress test thread breakpoints Ilya Leoshkevich
2024-09-23 16:37 ` [PATCH 00/18] Stop all qemu-cpu threads on a breakpoint Ilya Leoshkevich
2024-09-24 11:46 ` Richard Henderson
2024-09-25 7:43 ` Ilya Leoshkevich
2024-10-05 19:51 ` Richard Henderson
2024-10-05 20:26 ` Ilya Leoshkevich
2024-10-05 20:35 ` Ilya Leoshkevich
2024-10-08 18:17 ` Richard Henderson
2024-10-09 22:01 ` Ilya Leoshkevich
2025-01-08 15:56 ` Alex Bennée
2025-01-08 16:20 ` Ilya Leoshkevich
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=20240923162208.90745-11-iii@linux.ibm.com \
--to=iii@linux.ibm.com \
--cc=alex.bennee@linaro.org \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/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.