From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>,
Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Subject: [Qemu-devel] [PULL 37/52] icount: fixed saving/restoring of icount warp timers
Date: Fri, 12 Jan 2018 12:31:01 +0100 [thread overview]
Message-ID: <1515756676-3860-38-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1515756676-3860-1-git-send-email-pbonzini@redhat.com>
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
This patch adds saving and restoring of the icount warp
timers in the vmstate.
It is needed because there timers affect the virtual clock value.
Therefore determinism of the execution in icount record/replay mode
depends on determinism of the timers.
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
---
cpus.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 66 insertions(+), 19 deletions(-)
diff --git a/cpus.c b/cpus.c
index e8139de..f992537 100644
--- a/cpus.c
+++ b/cpus.c
@@ -120,16 +120,11 @@ static bool all_cpu_threads_idle(void)
/* Protected by TimersState seqlock */
static bool icount_sleep = true;
-static int64_t vm_clock_warp_start = -1;
/* Conversion factor from emulated instructions to virtual clock ticks. */
static int icount_time_shift;
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
#define MAX_ICOUNT_SHIFT 10
-static QEMUTimer *icount_rt_timer;
-static QEMUTimer *icount_vm_timer;
-static QEMUTimer *icount_warp_timer;
-
typedef struct TimersState {
/* Protected by BQL. */
int64_t cpu_ticks_prev;
@@ -147,6 +142,11 @@ typedef struct TimersState {
int64_t qemu_icount_bias;
/* Only written by TCG thread */
int64_t qemu_icount;
+ /* for adjusting icount */
+ int64_t vm_clock_warp_start;
+ QEMUTimer *icount_rt_timer;
+ QEMUTimer *icount_vm_timer;
+ QEMUTimer *icount_warp_timer;
} TimersState;
static TimersState timers_state;
@@ -432,14 +432,14 @@ static void icount_adjust(void)
static void icount_adjust_rt(void *opaque)
{
- timer_mod(icount_rt_timer,
+ timer_mod(timers_state.icount_rt_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
icount_adjust();
}
static void icount_adjust_vm(void *opaque)
{
- timer_mod(icount_vm_timer,
+ timer_mod(timers_state.icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
icount_adjust();
@@ -460,7 +460,7 @@ static void icount_warp_rt(void)
*/
do {
seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
- warp_start = vm_clock_warp_start;
+ warp_start = timers_state.vm_clock_warp_start;
} while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
if (warp_start == -1) {
@@ -473,7 +473,7 @@ static void icount_warp_rt(void)
cpu_get_clock_locked());
int64_t warp_delta;
- warp_delta = clock - vm_clock_warp_start;
+ warp_delta = clock - timers_state.vm_clock_warp_start;
if (use_icount == 2) {
/*
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
@@ -485,7 +485,7 @@ static void icount_warp_rt(void)
}
timers_state.qemu_icount_bias += warp_delta;
}
- vm_clock_warp_start = -1;
+ timers_state.vm_clock_warp_start = -1;
seqlock_write_end(&timers_state.vm_clock_seqlock);
if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
@@ -594,11 +594,13 @@ void qemu_start_warp_timer(void)
* every 100ms.
*/
seqlock_write_begin(&timers_state.vm_clock_seqlock);
- if (vm_clock_warp_start == -1 || vm_clock_warp_start > clock) {
- vm_clock_warp_start = clock;
+ if (timers_state.vm_clock_warp_start == -1
+ || timers_state.vm_clock_warp_start > clock) {
+ timers_state.vm_clock_warp_start = clock;
}
seqlock_write_end(&timers_state.vm_clock_seqlock);
- timer_mod_anticipate(icount_warp_timer, clock + deadline);
+ timer_mod_anticipate(timers_state.icount_warp_timer,
+ clock + deadline);
}
} else if (deadline == 0) {
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
@@ -623,7 +625,7 @@ static void qemu_account_warp_timer(void)
return;
}
- timer_del(icount_warp_timer);
+ timer_del(timers_state.icount_warp_timer);
icount_warp_rt();
}
@@ -632,6 +634,45 @@ static bool icount_state_needed(void *opaque)
return use_icount;
}
+static bool warp_timer_state_needed(void *opaque)
+{
+ TimersState *s = opaque;
+ return s->icount_warp_timer != NULL;
+}
+
+static bool adjust_timers_state_needed(void *opaque)
+{
+ TimersState *s = opaque;
+ return s->icount_rt_timer != NULL;
+}
+
+/*
+ * Subsection for warp timer migration is optional, because may not be created
+ */
+static const VMStateDescription icount_vmstate_warp_timer = {
+ .name = "timer/icount/warp_timer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = warp_timer_state_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT64(vm_clock_warp_start, TimersState),
+ VMSTATE_TIMER_PTR(icount_warp_timer, TimersState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription icount_vmstate_adjust_timers = {
+ .name = "timer/icount/timers",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = adjust_timers_state_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_TIMER_PTR(icount_rt_timer, TimersState),
+ VMSTATE_TIMER_PTR(icount_vm_timer, TimersState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
/*
* This is a subsection for icount migration.
*/
@@ -644,6 +685,11 @@ static const VMStateDescription icount_vmstate_timers = {
VMSTATE_INT64(qemu_icount_bias, TimersState),
VMSTATE_INT64(qemu_icount, TimersState),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription*[]) {
+ &icount_vmstate_warp_timer,
+ &icount_vmstate_adjust_timers,
+ NULL
}
};
@@ -754,7 +800,7 @@ void configure_icount(QemuOpts *opts, Error **errp)
icount_sleep = qemu_opt_get_bool(opts, "sleep", true);
if (icount_sleep) {
- icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
+ timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
icount_timer_cb, NULL);
}
@@ -788,13 +834,14 @@ void configure_icount(QemuOpts *opts, Error **errp)
the virtual time trigger catches emulated time passing too fast.
Realtime triggers occur even when idle, so use them less frequently
than VM triggers. */
- icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
+ timers_state.vm_clock_warp_start = -1;
+ timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
icount_adjust_rt, NULL);
- timer_mod(icount_rt_timer,
+ timer_mod(timers_state.icount_rt_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
- icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
icount_adjust_vm, NULL);
- timer_mod(icount_vm_timer,
+ timer_mod(timers_state.icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
}
--
1.8.3.1
next prev parent reply other threads:[~2018-01-12 11:32 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-12 11:30 [Qemu-devel] [PULL 00/52] Misc patches for 2017-01-12 Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 01/52] scsi-generic: Add share-rw option Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 02/52] scsi: fix scsi_convert_sense crash when in_buf == NULL && in_len == 0 Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 03/52] pc: fail memory hot-plug/unplug with -no-acpi and Q35 machine type Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 04/52] hpet: recover timer offset correctly Paolo Bonzini
2018-01-12 11:47 ` Pavel Dovgalyuk
2018-01-12 12:08 ` Paolo Bonzini
2018-01-12 12:18 ` Pavel Dovgalyuk
2018-01-12 12:21 ` Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 05/52] i386/cpu/kvm: look at PMU's CPUID before setting MSRs Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 06/52] chardev: use backend chr context when watch for fe Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 07/52] chardev: let g_idle_add() be with chardev gcontext Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 08/52] chardev: introduce qemu_chr_timeout_add_ms() Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 09/52] build-sys: fix qemu-ga -pthread linking Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 10/52] build-sys: silence make by default or V=0 Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 11/52] build-sys: add a rule to print a variable Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 12/52] build-sys: compile with -Og or -O1 when --enable-debug Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 13/52] tests/docker: add some sanitizers to fedora dockerfile Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 14/52] tests/docker: add test-debug Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 15/52] build-sys: add some sanitizers when --enable-debug if possible Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 16/52] tests: fix check-qobject leak Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 17/52] vl: fix direct firmware directories leak Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 18/52] readline: add a free function Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 19/52] tests: fix migration-test leak Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 20/52] crypto: fix stack-buffer-overflow error Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 21/52] qemu-config: fix leak in query-command-line-options Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 22/52] tests: fix qmp-test leak Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 23/52] ucontext: annotate coroutine stack for ASAN Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 24/52] tests: fix coroutine leak in /basic/entered Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 25/52] mips: fix potential fopen(NULL,...) Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 26/52] disas/s390: fix global-buffer-overflow Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 27/52] scsi-disk: release AioContext in unaligned WRITE SAME case Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 28/52] tests/boot-serial-test: Add tests for microblaze boards Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 29/52] tests/boot-serial-test: Add a test for the moxiesim machine Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 30/52] tests/boot-serial-test: Add support for the raspi2 machine Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 31/52] target/i386: move hflags update code to a function Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 32/52] target/i386: hax: change to use x86_update_hflags Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 33/52] target/i386: hax: Move x86_update_hflags Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 34/52] target-i386: update hflags on Hypervisor.framework Paolo Bonzini
2018-01-12 11:30 ` [Qemu-devel] [PULL 35/52] scripts/qemu-gdb: add simple tcg lock status helper Paolo Bonzini
2018-01-12 12:37 ` Alex Bennée
2018-01-12 11:31 ` [Qemu-devel] [PULL 36/52] scripts/qemu-gdb/timers.py: new helper to dump timer state Paolo Bonzini
2018-01-12 11:31 ` Paolo Bonzini [this message]
2018-01-12 11:31 ` [Qemu-devel] [PULL 38/52] cpus: unify qemu_*_wait_io_event Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 39/52] irq: fix memory leak Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 40/52] net: Drop unusual use of do { } while (0); Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 41/52] mips: Tweak location of ';' in macros Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 42/52] chardev: Use goto/label instead of do/break/while(0) Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 43/52] chardev: Clean up previous patch indentation Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 44/52] tests: Avoid 'do/while(false); ' in vhost-user-bridge Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 45/52] maint: Fix macros with broken 'do/while(0); ' usage Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 46/52] checkpatch: Enforce proper do/while (0) style Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 47/52] find_ram_offset: Add comments and tracing Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 48/52] find_ram_offset: Align ram_addr_t allocation on long boundaries Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 49/52] block/iscsi: fix initialization of iTask in iscsi_co_get_block_status Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 50/52] cpu: flush TB cache when loading VMState Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 51/52] util/qemu-thread-*: add qemu_lock, locked and unlock trace events Paolo Bonzini
2018-01-12 11:31 ` [Qemu-devel] [PULL 52/52] scripts/analyse-locks-simpletrace.py: script to analyse lock times Paolo Bonzini
2018-01-12 18:38 ` Eric Blake
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=1515756676-3860-38-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=Pavel.Dovgaluk@ispras.ru \
--cc=qemu-devel@nongnu.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).