[Qemu-devel] [PATCH] migration: Do not re-read the clock on pre_save in case of paused guest

Maxiwell S. Garcia posted 1 patch 4 years, 7 months ago
Test docker-clang@ubuntu passed
Test FreeBSD passed
Test checkpatch passed
Test docker-mingw@fedora passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20190829210711.6570-1-maxiwell@linux.ibm.com
Maintainers: Richard Henderson <rth@twiddle.net>, "Michael S. Tsirkin" <mst@redhat.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Eduardo Habkost <ehabkost@redhat.com>
hw/i386/kvm/clock.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
[Qemu-devel] [PATCH] migration: Do not re-read the clock on pre_save in case of paused guest
Posted by Maxiwell S. Garcia 4 years, 7 months ago
The clock move makes the guest knows about the paused time between the
'stop' and 'migrate' commands. This is an issue in an already-paused
VM because some side effects, like process stalls, could happen
after migration.

So, this patch checks the runstate of guest in the pre_save handler and
do not re-reads the clock in case of paused state (cold migration).

Signed-off-by: Maxiwell S. Garcia <maxiwell@linux.ibm.com>
---
 hw/i386/kvm/clock.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 80c133a724..2c59b6894b 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -41,6 +41,9 @@ typedef struct KVMClockState {
     uint64_t clock;
     bool clock_valid;
 
+    /* whether the 'clock' value was obtained in the 'paused' state */
+    bool runstate_paused;
+
     /* whether machine type supports reliable KVM_GET_CLOCK */
     bool mach_use_reliable_get_clock;
 
@@ -202,6 +205,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
             return;
         }
 
+        s->runstate_paused = runstate_check(RUN_STATE_PAUSED);
+
         kvm_synchronize_all_tsc();
 
         kvm_update_clock(s);
@@ -260,9 +265,9 @@ static int kvmclock_pre_load(void *opaque)
 }
 
 /*
- * When migrating, read the clock just before migration,
- * so that the guest clock counts during the events
- * between:
+ * When migrating a running guest, read the clock just
+ * before migration, so that the guest clock counts
+ * during the events between:
  *
  *  * vm_stop()
  *  *
@@ -277,7 +282,9 @@ static int kvmclock_pre_save(void *opaque)
 {
     KVMClockState *s = opaque;
 
-    kvm_update_clock(s);
+    if (!s->runstate_paused) {
+        kvm_update_clock(s);
+    }
 
     return 0;
 }
-- 
2.20.1


Re: [Qemu-devel] [PATCH] migration: Do not re-read the clock on pre_save in case of paused guest
Posted by Eduardo Habkost 4 years, 7 months ago
CCing Marcelo, who wrote kvm_update_clock() and
kvmclock_pre_save().

On Thu, Aug 29, 2019 at 06:07:11PM -0300, Maxiwell S. Garcia wrote:
> The clock move makes the guest knows about the paused time between the
> 'stop' and 'migrate' commands. This is an issue in an already-paused
> VM because some side effects, like process stalls, could happen
> after migration.
> 
> So, this patch checks the runstate of guest in the pre_save handler and
> do not re-reads the clock in case of paused state (cold migration).
> 
> Signed-off-by: Maxiwell S. Garcia <maxiwell@linux.ibm.com>
> ---
>  hw/i386/kvm/clock.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
> index 80c133a724..2c59b6894b 100644
> --- a/hw/i386/kvm/clock.c
> +++ b/hw/i386/kvm/clock.c
> @@ -41,6 +41,9 @@ typedef struct KVMClockState {
>      uint64_t clock;
>      bool clock_valid;
>  
> +    /* whether the 'clock' value was obtained in the 'paused' state */
> +    bool runstate_paused;
> +
>      /* whether machine type supports reliable KVM_GET_CLOCK */
>      bool mach_use_reliable_get_clock;
>  
> @@ -202,6 +205,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
>              return;
>          }
>  
> +        s->runstate_paused = runstate_check(RUN_STATE_PAUSED);
> +
>          kvm_synchronize_all_tsc();
>  
>          kvm_update_clock(s);
> @@ -260,9 +265,9 @@ static int kvmclock_pre_load(void *opaque)
>  }
>  
>  /*
> - * When migrating, read the clock just before migration,
> - * so that the guest clock counts during the events
> - * between:
> + * When migrating a running guest, read the clock just
> + * before migration, so that the guest clock counts
> + * during the events between:
>   *
>   *  * vm_stop()
>   *  *
> @@ -277,7 +282,9 @@ static int kvmclock_pre_save(void *opaque)
>  {
>      KVMClockState *s = opaque;
>  
> -    kvm_update_clock(s);
> +    if (!s->runstate_paused) {
> +        kvm_update_clock(s);
> +    }
>  
>      return 0;
>  }
> -- 
> 2.20.1
> 

-- 
Eduardo

Re: [Qemu-devel] [PATCH] migration: Do not re-read the clock on pre_save in case of paused guest
Posted by Marcelo Tosatti 4 years, 7 months ago
Looks good.

Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>

On Thu, Aug 29, 2019 at 06:18:42PM -0300, Eduardo Habkost wrote:
> CCing Marcelo, who wrote kvm_update_clock() and
> kvmclock_pre_save().
> 
> On Thu, Aug 29, 2019 at 06:07:11PM -0300, Maxiwell S. Garcia wrote:
> > The clock move makes the guest knows about the paused time between the
> > 'stop' and 'migrate' commands. This is an issue in an already-paused
> > VM because some side effects, like process stalls, could happen
> > after migration.
> > 
> > So, this patch checks the runstate of guest in the pre_save handler and
> > do not re-reads the clock in case of paused state (cold migration).
> > 
> > Signed-off-by: Maxiwell S. Garcia <maxiwell@linux.ibm.com>
> > ---
> >  hw/i386/kvm/clock.c | 15 +++++++++++----
> >  1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
> > index 80c133a724..2c59b6894b 100644
> > --- a/hw/i386/kvm/clock.c
> > +++ b/hw/i386/kvm/clock.c
> > @@ -41,6 +41,9 @@ typedef struct KVMClockState {
> >      uint64_t clock;
> >      bool clock_valid;
> >  
> > +    /* whether the 'clock' value was obtained in the 'paused' state */
> > +    bool runstate_paused;
> > +
> >      /* whether machine type supports reliable KVM_GET_CLOCK */
> >      bool mach_use_reliable_get_clock;
> >  
> > @@ -202,6 +205,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
> >              return;
> >          }
> >  
> > +        s->runstate_paused = runstate_check(RUN_STATE_PAUSED);
> > +
> >          kvm_synchronize_all_tsc();
> >  
> >          kvm_update_clock(s);
> > @@ -260,9 +265,9 @@ static int kvmclock_pre_load(void *opaque)
> >  }
> >  
> >  /*
> > - * When migrating, read the clock just before migration,
> > - * so that the guest clock counts during the events
> > - * between:
> > + * When migrating a running guest, read the clock just
> > + * before migration, so that the guest clock counts
> > + * during the events between:
> >   *
> >   *  * vm_stop()
> >   *  *
> > @@ -277,7 +282,9 @@ static int kvmclock_pre_save(void *opaque)
> >  {
> >      KVMClockState *s = opaque;
> >  
> > -    kvm_update_clock(s);
> > +    if (!s->runstate_paused) {
> > +        kvm_update_clock(s);
> > +    }
> >  
> >      return 0;
> >  }
> > -- 
> > 2.20.1
> > 
> 
> -- 
> Eduardo