diff mbox series

[v2,3/4] virtio-gpu: add x-vmstate-version

Message ID 20240513071905.499143-4-marcandre.lureau@redhat.com
State New
Headers show
Series Fix "virtio-gpu: fix scanout migration post-load" | expand

Commit Message

Marc-André Lureau May 13, 2024, 7:19 a.m. UTC
From: Marc-André Lureau <marcandre.lureau@redhat.com>

Machine <= 8.2 use v1.

Following patch will adjust to v2 for other machines to fix migration.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
---
 include/hw/virtio/virtio-gpu.h | 1 +
 hw/core/machine.c              | 1 +
 hw/display/virtio-gpu.c        | 6 ++++--
 3 files changed, 6 insertions(+), 2 deletions(-)

Comments

Peter Xu May 14, 2024, 4:29 a.m. UTC | #1
Hey, Marc-Andre,

On Mon, May 13, 2024 at 11:19:04AM +0400, marcandre.lureau@redhat.com wrote:
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index ae831b6b3e..7f9fb5eacc 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -1234,7 +1234,8 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
>      }
>      qemu_put_be32(f, 0); /* end of list */
>  
> -    return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
> +    return vmstate_save_state_v(f, &vmstate_virtio_gpu_scanouts, g,
> +                                NULL, g->vmstate_version, NULL);
>  }
>  
>  static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
> @@ -1339,7 +1340,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>      }
>  
>      /* load & apply scanout state */
> -    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
> +    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, g->vmstate_version);

[sorry for a late response; attending a conf, and will reply to the v1
 thread later for the other discussions..]

These two changes shouldn't be needed if we go with the .field_exists()
approach, am I right?  IIUC in that case we can keep the version 1 here and
don't boost anything, because we relied on the machine versions.

IIUC this might be the reason why we found 9.0 mahines are broken on
migration.  E.g, IIUC my original patch should work for 9.0<->9.0 too.

Thanks,

>  
>      return 0;
>  }
> @@ -1659,6 +1660,7 @@ static Property virtio_gpu_properties[] = {
>      DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
>                      VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
>      DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
> +    DEFINE_PROP_UINT8("x-vmstate-version", VirtIOGPU, vmstate_version, 1),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> -- 
> 2.41.0.28.gd7d8841f67
>
Marc-André Lureau May 14, 2024, 7:25 a.m. UTC | #2
Hi

On Tue, May 14, 2024 at 8:35 AM Peter Xu <peterx@redhat.com> wrote:
>
> Hey, Marc-Andre,
>
> On Mon, May 13, 2024 at 11:19:04AM +0400, marcandre.lureau@redhat.com wrote:
> > diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> > index ae831b6b3e..7f9fb5eacc 100644
> > --- a/hw/display/virtio-gpu.c
> > +++ b/hw/display/virtio-gpu.c
> > @@ -1234,7 +1234,8 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
> >      }
> >      qemu_put_be32(f, 0); /* end of list */
> >
> > -    return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
> > +    return vmstate_save_state_v(f, &vmstate_virtio_gpu_scanouts, g,
> > +                                NULL, g->vmstate_version, NULL);
> >  }
> >
> >  static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
> > @@ -1339,7 +1340,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
> >      }
> >
> >      /* load & apply scanout state */
> > -    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
> > +    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, g->vmstate_version);
>
> [sorry for a late response; attending a conf, and will reply to the v1
>  thread later for the other discussions..]
>
> These two changes shouldn't be needed if we go with the .field_exists()
> approach, am I right?  IIUC in that case we can keep the version 1 here and
> don't boost anything, because we relied on the machine versions.
>
> IIUC this might be the reason why we found 9.0 mahines are broken on
> migration.  E.g, IIUC my original patch should work for 9.0<->9.0 too.
>

Indeed, but for consistency, shouldn't it use the x-vmstate-version
value for the top-level VMSD save/load ?

Otherwise, it feels a bit odd that this x-vmstate-version is only used
for the nested "virtio-gpu-one-scanout" version.

Or perhaps we should rename it to x-scanout-vmstate-version ? wdyt


> Thanks,
>
> >
> >      return 0;
> >  }
> > @@ -1659,6 +1660,7 @@ static Property virtio_gpu_properties[] = {
> >      DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
> >                      VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
> >      DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
> > +    DEFINE_PROP_UINT8("x-vmstate-version", VirtIOGPU, vmstate_version, 1),
> >      DEFINE_PROP_END_OF_LIST(),
> >  };
> >
> > --
> > 2.41.0.28.gd7d8841f67
> >
>
> --
> Peter Xu
>
Peter Xu May 14, 2024, 1:06 p.m. UTC | #3
On Tue, May 14, 2024 at 11:25:26AM +0400, Marc-André Lureau wrote:
> Hi
> 
> On Tue, May 14, 2024 at 8:35 AM Peter Xu <peterx@redhat.com> wrote:
> >
> > Hey, Marc-Andre,
> >
> > On Mon, May 13, 2024 at 11:19:04AM +0400, marcandre.lureau@redhat.com wrote:
> > > diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> > > index ae831b6b3e..7f9fb5eacc 100644
> > > --- a/hw/display/virtio-gpu.c
> > > +++ b/hw/display/virtio-gpu.c
> > > @@ -1234,7 +1234,8 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
> > >      }
> > >      qemu_put_be32(f, 0); /* end of list */
> > >
> > > -    return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
> > > +    return vmstate_save_state_v(f, &vmstate_virtio_gpu_scanouts, g,
> > > +                                NULL, g->vmstate_version, NULL);
> > >  }
> > >
> > >  static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
> > > @@ -1339,7 +1340,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
> > >      }
> > >
> > >      /* load & apply scanout state */
> > > -    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
> > > +    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, g->vmstate_version);
> >
> > [sorry for a late response; attending a conf, and will reply to the v1
> >  thread later for the other discussions..]
> >
> > These two changes shouldn't be needed if we go with the .field_exists()
> > approach, am I right?  IIUC in that case we can keep the version 1 here and
> > don't boost anything, because we relied on the machine versions.
> >
> > IIUC this might be the reason why we found 9.0 mahines are broken on
> > migration.  E.g, IIUC my original patch should work for 9.0<->9.0 too.
> >
> 
> Indeed, but for consistency, shouldn't it use the x-vmstate-version
> value for the top-level VMSD save/load ?
> 
> Otherwise, it feels a bit odd that this x-vmstate-version is only used
> for the nested "virtio-gpu-one-scanout" version.
> 
> Or perhaps we should rename it to x-scanout-vmstate-version ? wdyt

Makes sense to me.  In another place I used to have a field called
preempt_pre_7_2.. which is pretty wierd but it would be more accurate I
suppose if the field name reflects how that was defined, especially
differenciate that v.s. VMSD versioning as they're confusing indeed when
used together.

So if a rename I suppose we can even "vmstate-version".  I just wished VMSD
versioning could work with bi-directional migration already then we save
all the fuss... we used to have the chance before introducing
field_exists() (I suppose this one came later), but we didn't care or
notice at that time, sign.  We'll just need a handshake between src/dst so
that when src sees dst uses VMSD v1 it sends v1-only fields even if it
knows as far as v2.

For the long run we may be able to have some small helper so we fetch the
machine type globally, then maybe we can in the future pass in the test
function as:

bool test_function (void *opaque)
{
  return MACHINE_TYPE_BEFORE(8, 2);
}

Then it'll also avoid even introducing a variable.  Maybe we can provide
this test_function() directly too, one for each release.

Thanks,

> 
> 
> > Thanks,
> >
> > >
> > >      return 0;
> > >  }
> > > @@ -1659,6 +1660,7 @@ static Property virtio_gpu_properties[] = {
> > >      DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
> > >                      VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
> > >      DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
> > > +    DEFINE_PROP_UINT8("x-vmstate-version", VirtIOGPU, vmstate_version, 1),
> > >      DEFINE_PROP_END_OF_LIST(),
> > >  };
> > >
> > > --
> > > 2.41.0.28.gd7d8841f67
> > >
> >
> > --
> > Peter Xu
> >
>
diff mbox series

Patch

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index ed44cdad6b..af1c77eb3f 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -177,6 +177,7 @@  typedef struct VGPUDMABuf {
 struct VirtIOGPU {
     VirtIOGPUBase parent_obj;
 
+    uint8_t vmstate_version;
     uint64_t conf_max_hostmem;
 
     VirtQueue *ctrl_vq;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index c7ceb11501..cf840e0502 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -42,6 +42,7 @@  GlobalProperty hw_compat_8_2[] = {
     { "migration", "zero-page-detection", "legacy"},
     { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
     { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+    { "virtio-gpu-device", "x-vmstate-version", "1" },
 };
 const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2);
 
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index ae831b6b3e..7f9fb5eacc 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1234,7 +1234,8 @@  static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
     }
     qemu_put_be32(f, 0); /* end of list */
 
-    return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
+    return vmstate_save_state_v(f, &vmstate_virtio_gpu_scanouts, g,
+                                NULL, g->vmstate_version, NULL);
 }
 
 static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
@@ -1339,7 +1340,7 @@  static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
     }
 
     /* load & apply scanout state */
-    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
+    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, g->vmstate_version);
 
     return 0;
 }
@@ -1659,6 +1660,7 @@  static Property virtio_gpu_properties[] = {
     DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
                     VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
     DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
+    DEFINE_PROP_UINT8("x-vmstate-version", VirtIOGPU, vmstate_version, 1),
     DEFINE_PROP_END_OF_LIST(),
 };