diff mbox

[RFC,v4,17/25] cpus: make icount warp deterministic in replay mode

Message ID 20141107103304.6136.29222.stgit@PASHA-ISP
State New
Headers show

Commit Message

Pavel Dovgalyuk Nov. 7, 2014, 10:33 a.m. UTC
This patch adds saving and replaying warping parameters in record and replay
modes. These parameters affect on virtual clock values and therefore should
be deterministic.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 cpus.c |   24 +++++++++++++++++-------
 1 files changed, 17 insertions(+), 7 deletions(-)

Comments

Paolo Bonzini Nov. 7, 2014, 11:24 a.m. UTC | #1
On 07/11/2014 11:33, Pavel Dovgalyuk wrote:
> This patch adds saving and replaying warping parameters in record and replay
> modes. These parameters affect on virtual clock values and therefore should
> be deterministic.

Why are QEMU_CLOCK_REALTIME timers not recorded/replayed like
QEMU_CLOCK_HOST is?

Paolo

> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
> ---
>  cpus.c |   24 +++++++++++++++++-------
>  1 files changed, 17 insertions(+), 7 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index b41baf6..dac222b 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -370,7 +370,9 @@ static void icount_warp_rt(void *opaque)
>  
>      seqlock_write_lock(&timers_state.vm_clock_seqlock);
>      if (runstate_is_running()) {
> -        int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +        int64_t clock = qemu_clock_get_ns(replay_mode == REPLAY_MODE_NONE
> +                                          ? QEMU_CLOCK_REALTIME
> +                                          : QEMU_CLOCK_HOST);
>          int64_t warp_delta;
>  
>          warp_delta = clock - vm_clock_warp_start;
> @@ -444,7 +446,9 @@ void qemu_clock_warp(QEMUClockType type)
>      }
>  
>      /* We want to use the earliest deadline from ALL vm_clocks */
> -    clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +    clock = qemu_clock_get_ns(replay_mode == REPLAY_MODE_NONE
> +                              ? QEMU_CLOCK_REALTIME
> +                              : QEMU_CLOCK_HOST);
>      deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
>      if (deadline < 0) {
>          return;
> @@ -537,8 +541,10 @@ void configure_icount(QemuOpts *opts, Error **errp)
>          return;
>      }
>      icount_align_option = qemu_opt_get_bool(opts, "align", false);
> -    icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
> -                                          icount_warp_rt, NULL);
> +    icount_warp_timer = timer_new_ns(replay_mode == REPLAY_MODE_NONE
> +                                     ? QEMU_CLOCK_REALTIME
> +                                     : QEMU_CLOCK_HOST,
> +                                     icount_warp_rt, NULL);
>      if (strcmp(option, "auto") != 0) {
>          errno = 0;
>          icount_time_shift = strtol(option, &rem_str, 0);
> @@ -562,10 +568,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_REALTIME,
> -                                        icount_adjust_rt, NULL);
> +    icount_rt_timer = timer_new_ms(replay_mode == REPLAY_MODE_NONE
> +                                   ? QEMU_CLOCK_REALTIME
> +                                   : QEMU_CLOCK_HOST,
> +                                   icount_adjust_rt, NULL);
>      timer_mod(icount_rt_timer,
> -                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
> +                   qemu_clock_get_ms(replay_mode == REPLAY_MODE_NONE
> +                                     ? QEMU_CLOCK_REALTIME
> +                                     : QEMU_CLOCK_HOST) + 1000);
>      icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>                                          icount_adjust_vm, NULL);
>      timer_mod(icount_vm_timer,
>
Pavel Dovgalyuk Nov. 7, 2014, 11:45 a.m. UTC | #2
> From: Paolo Bonzini [mailto:pbonzini@redhat.com]
> On 07/11/2014 11:33, Pavel Dovgalyuk wrote:
> > This patch adds saving and replaying warping parameters in record and replay
> > modes. These parameters affect on virtual clock values and therefore should
> > be deterministic.
> 
> Why are QEMU_CLOCK_REALTIME timers not recorded/replayed like
> QEMU_CLOCK_HOST is?

We cannot record all QEMU_CLOCK_REALTIME timers, because they are simulator-related timers,
not the VM-related ones. If we'll record them then we'll have to replay simulator
execution. And we want just to replay VM allowing different realtime events to be
non-replayable (like screen refresh, monitor events handling, and so on).

Pavel Dovgalyuk
> 
> > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
> > ---
> >  cpus.c |   24 +++++++++++++++++-------
> >  1 files changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/cpus.c b/cpus.c
> > index b41baf6..dac222b 100644
> > --- a/cpus.c
> > +++ b/cpus.c
> > @@ -370,7 +370,9 @@ static void icount_warp_rt(void *opaque)
> >
> >      seqlock_write_lock(&timers_state.vm_clock_seqlock);
> >      if (runstate_is_running()) {
> > -        int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> > +        int64_t clock = qemu_clock_get_ns(replay_mode == REPLAY_MODE_NONE
> > +                                          ? QEMU_CLOCK_REALTIME
> > +                                          : QEMU_CLOCK_HOST);
> >          int64_t warp_delta;
> >
> >          warp_delta = clock - vm_clock_warp_start;
> > @@ -444,7 +446,9 @@ void qemu_clock_warp(QEMUClockType type)
> >      }
> >
> >      /* We want to use the earliest deadline from ALL vm_clocks */
> > -    clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> > +    clock = qemu_clock_get_ns(replay_mode == REPLAY_MODE_NONE
> > +                              ? QEMU_CLOCK_REALTIME
> > +                              : QEMU_CLOCK_HOST);
> >      deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
> >      if (deadline < 0) {
> >          return;
> > @@ -537,8 +541,10 @@ void configure_icount(QemuOpts *opts, Error **errp)
> >          return;
> >      }
> >      icount_align_option = qemu_opt_get_bool(opts, "align", false);
> > -    icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
> > -                                          icount_warp_rt, NULL);
> > +    icount_warp_timer = timer_new_ns(replay_mode == REPLAY_MODE_NONE
> > +                                     ? QEMU_CLOCK_REALTIME
> > +                                     : QEMU_CLOCK_HOST,
> > +                                     icount_warp_rt, NULL);
> >      if (strcmp(option, "auto") != 0) {
> >          errno = 0;
> >          icount_time_shift = strtol(option, &rem_str, 0);
> > @@ -562,10 +568,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_REALTIME,
> > -                                        icount_adjust_rt, NULL);
> > +    icount_rt_timer = timer_new_ms(replay_mode == REPLAY_MODE_NONE
> > +                                   ? QEMU_CLOCK_REALTIME
> > +                                   : QEMU_CLOCK_HOST,
> > +                                   icount_adjust_rt, NULL);
> >      timer_mod(icount_rt_timer,
> > -                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
> > +                   qemu_clock_get_ms(replay_mode == REPLAY_MODE_NONE
> > +                                     ? QEMU_CLOCK_REALTIME
> > +                                     : QEMU_CLOCK_HOST) + 1000);
> >      icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> >                                          icount_adjust_vm, NULL);
> >      timer_mod(icount_vm_timer,
> >
Paolo Bonzini Nov. 7, 2014, noon UTC | #3
On 07/11/2014 12:45, Pavel Dovgaluk wrote:
>> From: Paolo Bonzini [mailto:pbonzini@redhat.com]
>> On 07/11/2014 11:33, Pavel Dovgalyuk wrote:
>>> This patch adds saving and replaying warping parameters in record and replay
>>> modes. These parameters affect on virtual clock values and therefore should
>>> be deterministic.
>>
>> Why are QEMU_CLOCK_REALTIME timers not recorded/replayed like
>> QEMU_CLOCK_HOST is?
> 
> We cannot record all QEMU_CLOCK_REALTIME timers, because they are simulator-related timers,
> not the VM-related ones. If we'll record them then we'll have to replay simulator
> execution. And we want just to replay VM allowing different realtime events to be
> non-replayable (like screen refresh, monitor events handling, and so on).

Hmm... I think you want the icount_rt timer to use what
QEMU_CLOCK_VIRTUAL does in !use_icount mode.  Maybe you can add a fourth
clock, QEMU_CLOCK_VIRTUAL_RT and use this one independent of the replay
mode.  This clock can then be traced like QEMU_CLOCK_HOST.

The problem is that QEMU_CLOCK_HOST can move backwards or forwards,
sometimes by as much as 1 hour, so it's not the best match for this case.

Paolo
diff mbox

Patch

diff --git a/cpus.c b/cpus.c
index b41baf6..dac222b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -370,7 +370,9 @@  static void icount_warp_rt(void *opaque)
 
     seqlock_write_lock(&timers_state.vm_clock_seqlock);
     if (runstate_is_running()) {
-        int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+        int64_t clock = qemu_clock_get_ns(replay_mode == REPLAY_MODE_NONE
+                                          ? QEMU_CLOCK_REALTIME
+                                          : QEMU_CLOCK_HOST);
         int64_t warp_delta;
 
         warp_delta = clock - vm_clock_warp_start;
@@ -444,7 +446,9 @@  void qemu_clock_warp(QEMUClockType type)
     }
 
     /* We want to use the earliest deadline from ALL vm_clocks */
-    clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+    clock = qemu_clock_get_ns(replay_mode == REPLAY_MODE_NONE
+                              ? QEMU_CLOCK_REALTIME
+                              : QEMU_CLOCK_HOST);
     deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
     if (deadline < 0) {
         return;
@@ -537,8 +541,10 @@  void configure_icount(QemuOpts *opts, Error **errp)
         return;
     }
     icount_align_option = qemu_opt_get_bool(opts, "align", false);
-    icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
-                                          icount_warp_rt, NULL);
+    icount_warp_timer = timer_new_ns(replay_mode == REPLAY_MODE_NONE
+                                     ? QEMU_CLOCK_REALTIME
+                                     : QEMU_CLOCK_HOST,
+                                     icount_warp_rt, NULL);
     if (strcmp(option, "auto") != 0) {
         errno = 0;
         icount_time_shift = strtol(option, &rem_str, 0);
@@ -562,10 +568,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_REALTIME,
-                                        icount_adjust_rt, NULL);
+    icount_rt_timer = timer_new_ms(replay_mode == REPLAY_MODE_NONE
+                                   ? QEMU_CLOCK_REALTIME
+                                   : QEMU_CLOCK_HOST,
+                                   icount_adjust_rt, NULL);
     timer_mod(icount_rt_timer,
-                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
+                   qemu_clock_get_ms(replay_mode == REPLAY_MODE_NONE
+                                     ? QEMU_CLOCK_REALTIME
+                                     : QEMU_CLOCK_HOST) + 1000);
     icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                         icount_adjust_vm, NULL);
     timer_mod(icount_vm_timer,