[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 38/79] replay: wake up vCPU when replaying
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 38/79] replay: wake up vCPU when replaying |
Date: |
Sun, 30 Sep 2018 10:12:36 +0200 |
From: Pavel Dovgalyuk <address@hidden>
In record/replay icount mode vCPU thread and iothread synchronize
the execution using the checkpoints.
vCPU thread processes the virtual timers and iothread processes all others.
When iothread wants to wake up sleeping vCPU thread, it sends dummy queued
work. Therefore it could be the following sequence of the events in
record mode:
- IO: sending dummy work
- IO: processing timers
- CPU: wakeup
- CPU: clearing dummy work
- CPU: processing virtual timers
But due to the races in replay mode the sequence may change:
- IO: sending dummy work
- CPU: wakeup
- CPU: clearing dummy work
- CPU: sleeping again because nothing to do
- IO: Processing timers
- CPU: zzzz
In this case vCPU will not wake up, because dummy work is not to be set up
again.
This patch tries to wake up the vCPU when it sleeps and the icount warp
checkpoint isn't met. It means that vCPU has something to do, because
there are no other reasons of non-matching warp checkpoint.
Signed-off-by: Pavel Dovgalyuk <address@hidden>
--
v5: improve checking that vCPU is still sleeping
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
cpus.c | 31 +++++++++++++++++++++----------
include/sysemu/replay.h | 3 +++
replay/replay.c | 12 ++++++++++++
3 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/cpus.c b/cpus.c
index d8b3b46..68f08f5 100644
--- a/cpus.c
+++ b/cpus.c
@@ -583,18 +583,29 @@ void qemu_start_warp_timer(void)
return;
}
- /* warp clock deterministically in record/replay mode */
- if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) {
- return;
- }
+ if (replay_mode != REPLAY_MODE_PLAY) {
+ if (!all_cpu_threads_idle()) {
+ return;
+ }
- if (!all_cpu_threads_idle()) {
- return;
- }
+ if (qtest_enabled()) {
+ /* When testing, qtest commands advance icount. */
+ return;
+ }
- if (qtest_enabled()) {
- /* When testing, qtest commands advance icount. */
- return;
+ replay_checkpoint(CHECKPOINT_CLOCK_WARP_START);
+ } else {
+ /* warp clock deterministically in record/replay mode */
+ if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) {
+ /* vCPU is sleeping and warp can't be started.
+ It is probably a race condition: notification sent
+ to vCPU was processed in advance and vCPU went to sleep.
+ Therefore we have to wake it up for doing someting. */
+ if (replay_has_checkpoint()) {
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ }
+ return;
+ }
}
/* We want to use the earliest deadline from ALL vm_clocks */
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 3ced6bc..7f7a594 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -120,6 +120,9 @@ void replay_shutdown_request(ShutdownCause cause);
Returns 0 in PLAY mode if checkpoint was not found.
Returns 1 in all other cases. */
bool replay_checkpoint(ReplayCheckpoint checkpoint);
+/*! Used to determine that checkpoint is pending.
+ Does not proceed to the next event in the log. */
+bool replay_has_checkpoint(void);
/* Asynchronous events queue */
diff --git a/replay/replay.c b/replay/replay.c
index 8228261..379b51a 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -224,6 +224,18 @@ out:
return res;
}
+bool replay_has_checkpoint(void)
+{
+ bool res = false;
+ if (replay_mode == REPLAY_MODE_PLAY) {
+ g_assert(replay_mutex_locked());
+ replay_account_executed_instructions();
+ res = EVENT_CHECKPOINT <= replay_state.data_kind
+ && replay_state.data_kind <= EVENT_CHECKPOINT_LAST;
+ }
+ return res;
+}
+
static void replay_enable(const char *fname, int mode)
{
const char *fmode = NULL;
--
1.8.3.1
- [Qemu-devel] [PULL 25/79] target/i386: move cpu_cc_srcT to DisasContext, (continued)
- [Qemu-devel] [PULL 25/79] target/i386: move cpu_cc_srcT to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 28/79] target/i386: move cpu_T1 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 34/79] target/i386: move cpu_tmp3_i32 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 26/79] target/i386: move cpu_A0 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 31/79] target/i386: move cpu_ptr0 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 30/79] target/i386: move cpu_tmp4 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 29/79] target/i386: move cpu_tmp0 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 32/79] target/i386: move cpu_ptr1 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 35/79] target/i386: move cpu_tmp1_i64 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 33/79] target/i386: move cpu_tmp2_i32 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 38/79] replay: wake up vCPU when replaying,
Paolo Bonzini <=
- [Qemu-devel] [PULL 42/79] timer: introduce new virtual clock, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 37/79] configure: enable mttcg for i386 and x86_64, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 39/79] replay: flush events when exiting, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 40/79] translator: fix breakpoint processing, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 27/79] target/i386: move cpu_T0 to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 41/79] replay: allow loading any snapshots before recording, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 43/79] slirp: fix ipv6 timers, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 36/79] target/i386: move x86_64_hregs to DisasContext, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 45/79] fw_cfg_mem: add read memory region callback, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 44/79] ui: fix virtual timers, Paolo Bonzini, 2018/09/30