[RFC,v2,09/26] replay: save prior value of the host clock

Message ID 20171114081722.27640.32191.stgit@pasha-VirtualBox
State New
Headers show
Series
  • replay additions
Related show

Commit Message

Pavel Dovgalyuk Nov. 14, 2017, 8:17 a.m.
This patch adds saving/restoring of the host clock field 'last'.
It is used in host clock calculation and therefore clock may
become incorrect when using restored vmstate.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>

---
 include/qemu/timer.h     |   14 ++++++++++++++
 replay/replay-internal.h |    2 ++
 replay/replay-snapshot.c |    3 +++
 util/qemu-timer.c        |   12 ++++++++++++
 4 files changed, 31 insertions(+)

Comments

Paolo Bonzini Nov. 14, 2017, 1:35 p.m. | #1
On 14/11/2017 09:17, Pavel Dovgalyuk wrote:
> This patch adds saving/restoring of the host clock field 'last'.
> It is used in host clock calculation and therefore clock may
> become incorrect when using restored vmstate.
> 
> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
> 
> ---
>  include/qemu/timer.h     |   14 ++++++++++++++
>  replay/replay-internal.h |    2 ++
>  replay/replay-snapshot.c |    3 +++
>  util/qemu-timer.c        |   12 ++++++++++++
>  4 files changed, 31 insertions(+)
> 
> diff --git a/include/qemu/timer.h b/include/qemu/timer.h
> index 1b518bc..a610a17 100644
> --- a/include/qemu/timer.h
> +++ b/include/qemu/timer.h
> @@ -251,6 +251,20 @@ bool qemu_clock_run_timers(QEMUClockType type);
>   */
>  bool qemu_clock_run_all_timers(void);
>  
> +/**
> + * qemu_clock_get_last:
> + *
> + * Returns last clock query time.
> + */
> +uint64_t qemu_clock_get_last(QEMUClockType type);
> +/**
> + * qemu_clock_set_last:
> + *
> + * Sets last clock query time.
> + */
> +void qemu_clock_set_last(QEMUClockType type, uint64_t last);
> +
> +
>  /*
>   * QEMUTimerList
>   */
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index 3ebb199..be96d7e 100644
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -78,6 +78,8 @@ typedef struct ReplayState {
>          This counter is global, because requests from different
>          block devices should not get overlapping ids. */
>      uint64_t block_request_id;
> +    /*! Prior value of the host clock */
> +    uint64_t host_clock_last;
>  } ReplayState;
>  extern ReplayState replay_state;
>  
> diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c
> index 7075986..e0b2204 100644
> --- a/replay/replay-snapshot.c
> +++ b/replay/replay-snapshot.c
> @@ -25,6 +25,7 @@ static int replay_pre_save(void *opaque)
>  {
>      ReplayState *state = opaque;
>      state->file_offset = ftell(replay_file);
> +    state->host_clock_last = qemu_clock_get_last(QEMU_CLOCK_HOST);
>  
>      return 0;
>  }
> @@ -33,6 +34,7 @@ static int replay_post_load(void *opaque, int version_id)
>  {
>      ReplayState *state = opaque;
>      fseek(replay_file, state->file_offset, SEEK_SET);
> +    qemu_clock_set_last(QEMU_CLOCK_HOST, state->host_clock_last);
>      /* If this was a vmstate, saved in recording mode,
>         we need to initialize replay data fields. */
>      replay_fetch_data_kind();
> @@ -54,6 +56,7 @@ static const VMStateDescription vmstate_replay = {
>          VMSTATE_UINT32(has_unread_data, ReplayState),
>          VMSTATE_UINT64(file_offset, ReplayState),
>          VMSTATE_UINT64(block_request_id, ReplayState),
> +        VMSTATE_UINT64(host_clock_last, ReplayState),
>          VMSTATE_END_OF_LIST()
>      },
>  };
> diff --git a/util/qemu-timer.c b/util/qemu-timer.c
> index 82d5650..2ed1bf2 100644
> --- a/util/qemu-timer.c
> +++ b/util/qemu-timer.c
> @@ -622,6 +622,18 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
>      }
>  }
>  
> +uint64_t qemu_clock_get_last(QEMUClockType type)
> +{
> +    QEMUClock *clock = qemu_clock_ptr(type);
> +    return clock->last;
> +}
> +
> +void qemu_clock_set_last(QEMUClockType type, uint64_t last)
> +{
> +    QEMUClock *clock = qemu_clock_ptr(type);
> +    clock->last = last;
> +}
> +
>  void qemu_clock_register_reset_notifier(QEMUClockType type,
>                                          Notifier *notifier)
>  {
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

Patch

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 1b518bc..a610a17 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -251,6 +251,20 @@  bool qemu_clock_run_timers(QEMUClockType type);
  */
 bool qemu_clock_run_all_timers(void);
 
+/**
+ * qemu_clock_get_last:
+ *
+ * Returns last clock query time.
+ */
+uint64_t qemu_clock_get_last(QEMUClockType type);
+/**
+ * qemu_clock_set_last:
+ *
+ * Sets last clock query time.
+ */
+void qemu_clock_set_last(QEMUClockType type, uint64_t last);
+
+
 /*
  * QEMUTimerList
  */
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 3ebb199..be96d7e 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -78,6 +78,8 @@  typedef struct ReplayState {
         This counter is global, because requests from different
         block devices should not get overlapping ids. */
     uint64_t block_request_id;
+    /*! Prior value of the host clock */
+    uint64_t host_clock_last;
 } ReplayState;
 extern ReplayState replay_state;
 
diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c
index 7075986..e0b2204 100644
--- a/replay/replay-snapshot.c
+++ b/replay/replay-snapshot.c
@@ -25,6 +25,7 @@  static int replay_pre_save(void *opaque)
 {
     ReplayState *state = opaque;
     state->file_offset = ftell(replay_file);
+    state->host_clock_last = qemu_clock_get_last(QEMU_CLOCK_HOST);
 
     return 0;
 }
@@ -33,6 +34,7 @@  static int replay_post_load(void *opaque, int version_id)
 {
     ReplayState *state = opaque;
     fseek(replay_file, state->file_offset, SEEK_SET);
+    qemu_clock_set_last(QEMU_CLOCK_HOST, state->host_clock_last);
     /* If this was a vmstate, saved in recording mode,
        we need to initialize replay data fields. */
     replay_fetch_data_kind();
@@ -54,6 +56,7 @@  static const VMStateDescription vmstate_replay = {
         VMSTATE_UINT32(has_unread_data, ReplayState),
         VMSTATE_UINT64(file_offset, ReplayState),
         VMSTATE_UINT64(block_request_id, ReplayState),
+        VMSTATE_UINT64(host_clock_last, ReplayState),
         VMSTATE_END_OF_LIST()
     },
 };
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
index 82d5650..2ed1bf2 100644
--- a/util/qemu-timer.c
+++ b/util/qemu-timer.c
@@ -622,6 +622,18 @@  int64_t qemu_clock_get_ns(QEMUClockType type)
     }
 }
 
+uint64_t qemu_clock_get_last(QEMUClockType type)
+{
+    QEMUClock *clock = qemu_clock_ptr(type);
+    return clock->last;
+}
+
+void qemu_clock_set_last(QEMUClockType type, uint64_t last)
+{
+    QEMUClock *clock = qemu_clock_ptr(type);
+    clock->last = last;
+}
+
 void qemu_clock_register_reset_notifier(QEMUClockType type,
                                         Notifier *notifier)
 {