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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).