diff mbox

[v18,13/21] icount: improve counting for record/replay

Message ID 20150917162439.8676.38290.stgit@PASHA-ISP.def.inno
State New
Headers show

Commit Message

Pavel Dovgalyuk Sept. 17, 2015, 4:24 p.m. UTC
icount_warp_rt function is called by qemu_clock_warp and as
callback of icount_warp timer. This patch adds call to qemu_clock_warp
into main_loop_wait function, because icount warp may be missed
in record/replay mode, when CPU is sleeping.
This patch also disables of calling this function by timer, because
it is not needed after making modifications of main_loop_wait.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 cpus.c      |   11 ++++++++---
 main-loop.c |    3 +++
 2 files changed, 11 insertions(+), 3 deletions(-)

Comments

Paolo Bonzini Sept. 22, 2015, 1:15 p.m. UTC | #1
On 17/09/2015 18:24, Pavel Dovgalyuk wrote:
>  #endif
>  
> +    /* CPU thread can infinitely wait for event after
> +       missing the warp */
> +    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
>      qemu_clock_run_all_timers();

It is still not clear to me why the call in timerlist_rearm is not
sufficient.  Can you explain this (again probably)?

Paolo
Pavel Dovgalyuk Sept. 23, 2015, 7:22 a.m. UTC | #2
> From: Paolo Bonzini [mailto:pbonzini@redhat.com]
> On 17/09/2015 18:24, Pavel Dovgalyuk wrote:
> >  #endif
> >
> > +    /* CPU thread can infinitely wait for event after
> > +       missing the warp */
> > +    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
> >      qemu_clock_run_all_timers();
> 
> It is still not clear to me why the call in timerlist_rearm is not
> sufficient.  Can you explain this (again probably)?

Sometimes tcg thread halts in qemu_tcg_wait_io_event function, waiting
for any external event. Virtual clock does not run, because warp is not called.
warp call in main_loop_wait proceeds virtual clock and allows tcg thread to run further.

Pavel Dovgalyuk
diff mbox

Patch

diff --git a/cpus.c b/cpus.c
index 95b8469..46d6717 100644
--- a/cpus.c
+++ b/cpus.c
@@ -327,7 +327,7 @@  static int64_t qemu_icount_round(int64_t count)
     return (count + (1 << icount_time_shift) - 1) >> icount_time_shift;
 }
 
-static void icount_warp_rt(void *opaque)
+static void icount_warp_rt(void)
 {
     /* The icount_warp_timer is rescheduled soon after vm_clock_warp_start
      * changes from -1 to another value, so the race here is okay.
@@ -362,6 +362,11 @@  static void icount_warp_rt(void *opaque)
     }
 }
 
+static void icount_dummy_timer(void *opaque)
+{
+    (void)opaque;
+}
+
 void qtest_clock_warp(int64_t dest)
 {
     int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -406,7 +411,7 @@  void qemu_clock_warp(QEMUClockType type)
          * the CPU starts running, in case the CPU is woken by an event other
          * than the earliest QEMU_CLOCK_VIRTUAL timer.
          */
-        icount_warp_rt(NULL);
+        icount_warp_rt();
         timer_del(icount_warp_timer);
     }
     if (!all_cpu_threads_idle()) {
@@ -529,7 +534,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,
-                                         icount_warp_rt, NULL);
+                                         icount_dummy_timer, NULL);
     }
 
     icount_align_option = qemu_opt_get_bool(opts, "align", false);
diff --git a/main-loop.c b/main-loop.c
index db600a3..df28670 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -506,6 +506,9 @@  int main_loop_wait(int nonblocking)
     slirp_pollfds_poll(gpollfds, (ret < 0));
 #endif
 
+    /* CPU thread can infinitely wait for event after
+       missing the warp */
+    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
     qemu_clock_run_all_timers();
 
     return ret;