From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, peter.maydell@linaro.org,
boost.lists@gmail.com, quintela@redhat.com, jasowang@redhat.com,
mst@redhat.com, zuban32s@gmail.com,
maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru,
kraxel@redhat.com, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com,
alex.bennee@linaro.org
Subject: [Qemu-devel] [RFC PATCH v2 12/26] cpus: push BQL lock to qemu_*_wait_io_event
Date: Tue, 14 Nov 2017 11:17:39 +0300 [thread overview]
Message-ID: <20171114081739.27640.85769.stgit@pasha-VirtualBox> (raw)
In-Reply-To: <20171114081630.27640.53933.stgit@pasha-VirtualBox>
From: Alex Bennée <alex.bennee@linaro.org>
We only really need to grab the lock for initial setup (so we don't
race with the thread-spawning thread). After that we can drop the lock
for the whole main loop and only grab it for waiting for IO events.
There is a slight wrinkle for the round-robin TCG thread as we also
expire timers which needs to be done under BQL as they are in the
main-loop.
This is stage one of reducing the lock impact as we can drop the
requirement of implicit BQL for async work and only grab the lock when
we need to sleep on the cpu->halt_cond.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
accel/kvm/kvm-all.c | 4 ----
cpus.c | 27 ++++++++++++++++++++-------
target/i386/hax-all.c | 2 --
3 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f290f48..8d1d2c4 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1857,9 +1857,7 @@ int kvm_cpu_exec(CPUState *cpu)
return EXCP_HLT;
}
- qemu_mutex_unlock_iothread();
cpu_exec_start(cpu);
-
do {
MemTxAttrs attrs;
@@ -1989,8 +1987,6 @@ int kvm_cpu_exec(CPUState *cpu)
} while (ret == 0);
cpu_exec_end(cpu);
- qemu_mutex_lock_iothread();
-
if (ret < 0) {
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
diff --git a/cpus.c b/cpus.c
index 7a3abea..3aeba5d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1127,6 +1127,8 @@ static bool qemu_tcg_should_sleep(CPUState *cpu)
static void qemu_tcg_wait_io_event(CPUState *cpu)
{
+ qemu_mutex_lock_iothread();
+
while (qemu_tcg_should_sleep(cpu)) {
stop_tcg_kick_timer();
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
@@ -1135,15 +1137,21 @@ static void qemu_tcg_wait_io_event(CPUState *cpu)
start_tcg_kick_timer();
qemu_wait_io_event_common(cpu);
+
+ qemu_mutex_unlock_iothread();
}
static void qemu_kvm_wait_io_event(CPUState *cpu)
{
+ qemu_mutex_lock_iothread();
+
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
qemu_wait_io_event_common(cpu);
+
+ qemu_mutex_unlock_iothread();
}
static void *qemu_kvm_cpu_thread_fn(void *arg)
@@ -1169,6 +1177,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
+ qemu_mutex_unlock_iothread();
+
qemu_cond_signal(&qemu_cpu_cond);
do {
@@ -1211,10 +1221,10 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
+ qemu_mutex_unlock_iothread();
qemu_cond_signal(&qemu_cpu_cond);
while (1) {
- qemu_mutex_unlock_iothread();
do {
int sig;
r = sigwait(&waitset, &sig);
@@ -1225,6 +1235,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
}
qemu_mutex_lock_iothread();
qemu_wait_io_event_common(cpu);
+ qemu_mutex_unlock_iothread();
}
return NULL;
@@ -1313,11 +1324,9 @@ static int tcg_cpu_exec(CPUState *cpu)
#ifdef CONFIG_PROFILER
ti = profile_getclock();
#endif
- qemu_mutex_unlock_iothread();
cpu_exec_start(cpu);
ret = cpu_exec(cpu);
cpu_exec_end(cpu);
- qemu_mutex_lock_iothread();
#ifdef CONFIG_PROFILER
tcg_time += profile_getclock() - ti;
#endif
@@ -1377,6 +1386,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
qemu_wait_io_event_common(cpu);
}
}
+ qemu_mutex_unlock_iothread();
start_tcg_kick_timer();
@@ -1386,6 +1396,9 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
cpu->exit_request = 1;
while (1) {
+
+ qemu_mutex_lock_iothread();
+
/* Account partial waits to QEMU_CLOCK_VIRTUAL. */
qemu_account_warp_timer();
@@ -1394,6 +1407,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
*/
handle_icount_deadline();
+ qemu_mutex_unlock_iothread();
+
if (!cpu) {
cpu = first_cpu;
}
@@ -1419,9 +1434,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
cpu_handle_guest_debug(cpu);
break;
} else if (r == EXCP_ATOMIC) {
- qemu_mutex_unlock_iothread();
cpu_exec_step_atomic(cpu);
- qemu_mutex_lock_iothread();
break;
}
} else if (cpu->stop) {
@@ -1462,6 +1475,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
current_cpu = cpu;
hax_init_vcpu(cpu);
+ qemu_mutex_unlock_iothread();
qemu_cond_signal(&qemu_cpu_cond);
while (1) {
@@ -1512,6 +1526,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
cpu->created = true;
cpu->can_do_io = 1;
current_cpu = cpu;
+ qemu_mutex_unlock_iothread();
qemu_cond_signal(&qemu_cpu_cond);
/* process any pending work */
@@ -1536,9 +1551,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
g_assert(cpu->halted);
break;
case EXCP_ATOMIC:
- qemu_mutex_unlock_iothread();
cpu_exec_step_atomic(cpu);
- qemu_mutex_lock_iothread();
default:
/* Ignore everything else? */
break;
diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c
index 3ce6950..9fd60d9 100644
--- a/target/i386/hax-all.c
+++ b/target/i386/hax-all.c
@@ -513,11 +513,9 @@ static int hax_vcpu_hax_exec(CPUArchState *env)
hax_vcpu_interrupt(env);
- qemu_mutex_unlock_iothread();
cpu_exec_start(cpu);
hax_ret = hax_vcpu_run(vcpu);
cpu_exec_end(cpu);
- qemu_mutex_lock_iothread();
/* Simply continue the vcpu_run if system call interrupted */
if (hax_ret == -EINTR || hax_ret == -EAGAIN) {
next prev parent reply other threads:[~2017-11-14 8:17 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-14 8:16 [Qemu-devel] [RFC PATCH v2 00/26] replay additions Pavel Dovgalyuk
2017-11-14 8:16 ` [Qemu-devel] [RFC PATCH v2 01/26] block: implement bdrv_snapshot_goto for blkreplay Pavel Dovgalyuk
2017-11-14 8:16 ` [Qemu-devel] [RFC PATCH v2 02/26] blkreplay: create temporary overlay for underlaying devices Pavel Dovgalyuk
2017-11-14 8:16 ` [Qemu-devel] [RFC PATCH v2 03/26] replay: disable default snapshot for record/replay Pavel Dovgalyuk
2017-11-14 8:16 ` [Qemu-devel] [RFC PATCH v2 04/26] replay: fix processing async events Pavel Dovgalyuk
2017-11-14 13:34 ` Paolo Bonzini
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 05/26] replay: fixed replay_enable_events Pavel Dovgalyuk
2017-11-14 13:34 ` Paolo Bonzini
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 06/26] replay: fix save/load vm for non-empty queue Pavel Dovgalyuk
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 07/26] replay: added replay log format description Pavel Dovgalyuk
2017-11-14 13:34 ` Paolo Bonzini
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 08/26] replay: make safe vmstop at record/replay Pavel Dovgalyuk
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 09/26] replay: save prior value of the host clock Pavel Dovgalyuk
2017-11-14 13:35 ` Paolo Bonzini
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 10/26] icount: fixed saving/restoring of icount warp timers Pavel Dovgalyuk
2017-11-14 13:35 ` Paolo Bonzini
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 11/26] target/arm/arm-powertctl: drop BQL assertions Pavel Dovgalyuk
2017-11-14 8:17 ` Pavel Dovgalyuk [this message]
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 13/26] cpus: only take BQL for sleeping threads Pavel Dovgalyuk
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 14/26] replay/replay.c: bump REPLAY_VERSION again Pavel Dovgalyuk
2017-11-14 13:35 ` Paolo Bonzini
2017-11-14 8:17 ` [Qemu-devel] [RFC PATCH v2 15/26] replay/replay-internal.c: track holding of replay_lock Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 16/26] replay: make locking visible outside replay code Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 17/26] replay: push replay_mutex_lock up the call tree Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 18/26] cpu-exec: don't overwrite exception_index Pavel Dovgalyuk
2017-11-14 13:37 ` Paolo Bonzini
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before calling cpu_exec_nocache Pavel Dovgalyuk
2017-11-14 13:38 ` Paolo Bonzini
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 20/26] replay: don't destroy mutex at exit Pavel Dovgalyuk
2017-11-14 13:36 ` Paolo Bonzini
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 21/26] replay: check return values of fwrite Pavel Dovgalyuk
2017-11-14 13:37 ` Paolo Bonzini
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 22/26] scripts/qemu-gdb: add simple tcg lock status helper Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 23/26] util/qemu-thread-*: add qemu_lock, locked and unlock trace events Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 24/26] scripts/analyse-locks-simpletrace.py: script to analyse lock times Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 25/26] scripts/replay-dump.py: replay log dumper Pavel Dovgalyuk
2017-11-14 8:18 ` [Qemu-devel] [RFC PATCH v2 26/26] scripts/qemu-gdb/timers.py: new helper to dump timer state Pavel Dovgalyuk
2017-11-14 8:58 ` [Qemu-devel] [RFC PATCH v2 00/26] replay additions no-reply
2017-11-14 9:03 ` no-reply
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=20171114081739.27640.85769.stgit@pasha-VirtualBox \
--to=pavel.dovgaluk@ispras.ru \
--cc=alex.bennee@linaro.org \
--cc=boost.lists@gmail.com \
--cc=dovgaluk@ispras.ru \
--cc=jasowang@redhat.com \
--cc=kraxel@redhat.com \
--cc=kwolf@redhat.com \
--cc=maria.klimushenkova@ispras.ru \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=zuban32s@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 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).