[PULL 23/65] qapi: introduce device-sync-config

Michael S. Tsirkin posted 65 patches 2 weeks, 4 days ago
[PULL 23/65] qapi: introduce device-sync-config
Posted by Michael S. Tsirkin 2 weeks, 4 days ago
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>

Add command to sync config from vhost-user backend to the device. It
may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
triggered interrupt to the guest or just not available (not supported
by vhost-user server).

Command result is racy if allow it during migration. Let's not allow
that.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Raphael Norwitz <raphael@enfabrica.net>
Message-Id: <20240920094936.450987-4-vsementsov@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 qapi/qdev.json            | 24 ++++++++++++++++++++++++
 include/hw/qdev-core.h    |  6 ++++++
 hw/block/vhost-user-blk.c |  1 +
 hw/virtio/virtio-pci.c    |  9 +++++++++
 system/qdev-monitor.c     | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 78 insertions(+)

diff --git a/qapi/qdev.json b/qapi/qdev.json
index 53d147c7b4..2a581129c9 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -163,3 +163,27 @@
 ##
 { 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
   'data': { '*device': 'str', 'path': 'str' } }
+
+##
+# @device-sync-config:
+#
+# Synchronize device configuration from host to guest part.  First,
+# copy the configuration from the host part (backend) to the guest
+# part (frontend).  Then notify guest software that device
+# configuration changed.
+#
+# The command may be used to notify the guest about block device
+# capcity change.  Currently only vhost-user-blk device supports
+# this.
+#
+# @id: the device's ID or QOM path
+#
+# Features:
+#
+# @unstable: The command is experimental.
+#
+# Since: 9.1
+##
+{ 'command': 'device-sync-config',
+  'features': [ 'unstable' ],
+  'data': {'id': 'str'} }
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index aa97c34a4b..94914858d8 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -95,6 +95,7 @@ typedef void (*DeviceUnrealize)(DeviceState *dev);
 typedef void (*DeviceReset)(DeviceState *dev);
 typedef void (*BusRealize)(BusState *bus, Error **errp);
 typedef void (*BusUnrealize)(BusState *bus);
+typedef int (*DeviceSyncConfig)(DeviceState *dev, Error **errp);
 
 /**
  * struct DeviceClass - The base class for all devices.
@@ -103,6 +104,9 @@ typedef void (*BusUnrealize)(BusState *bus);
  * property is changed to %true.
  * @unrealize: Callback function invoked when the #DeviceState:realized
  * property is changed to %false.
+ * @sync_config: Callback function invoked when QMP command device-sync-config
+ * is called. Should synchronize device configuration from host to guest part
+ * and notify the guest about the change.
  * @hotpluggable: indicates if #DeviceClass is hotpluggable, available
  * as readonly "hotpluggable" property of #DeviceState instance
  *
@@ -162,6 +166,7 @@ struct DeviceClass {
     DeviceReset legacy_reset;
     DeviceRealize realize;
     DeviceUnrealize unrealize;
+    DeviceSyncConfig sync_config;
 
     /**
      * @vmsd: device state serialisation description for
@@ -547,6 +552,7 @@ bool qdev_hotplug_allowed(DeviceState *dev, Error **errp);
  */
 HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev);
 void qdev_unplug(DeviceState *dev, Error **errp);
+int qdev_sync_config(DeviceState *dev, Error **errp);
 void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
                                   DeviceState *dev, Error **errp);
 void qdev_machine_creation_done(void);
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 48b3dabb8d..7996e49821 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -591,6 +591,7 @@ static void vhost_user_blk_class_init(ObjectClass *klass, void *data)
 
     device_class_set_props(dc, vhost_user_blk_properties);
     dc->vmsd = &vmstate_vhost_user_blk;
+    dc->sync_config = vhost_user_blk_sync_config;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     vdc->realize = vhost_user_blk_device_realize;
     vdc->unrealize = vhost_user_blk_device_unrealize;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 4d832fe845..c5a809b956 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2385,6 +2385,14 @@ static void virtio_pci_dc_realize(DeviceState *qdev, Error **errp)
     vpciklass->parent_dc_realize(qdev, errp);
 }
 
+static int virtio_pci_sync_config(DeviceState *dev, Error **errp)
+{
+    VirtIOPCIProxy *proxy = VIRTIO_PCI(dev);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
+    return qdev_sync_config(DEVICE(vdev), errp);
+}
+
 static void virtio_pci_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -2401,6 +2409,7 @@ static void virtio_pci_class_init(ObjectClass *klass, void *data)
     device_class_set_parent_realize(dc, virtio_pci_dc_realize,
                                     &vpciklass->parent_dc_realize);
     rc->phases.hold = virtio_pci_bus_reset_hold;
+    dc->sync_config = virtio_pci_sync_config;
 }
 
 static const TypeInfo virtio_pci_info = {
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 6671137a91..127456080b 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -23,6 +23,7 @@
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
 #include "sysemu/arch_init.h"
+#include "sysemu/runstate.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
 #include "qapi/qmp/dispatch.h"
@@ -977,6 +978,43 @@ void qmp_device_del(const char *id, Error **errp)
     }
 }
 
+int qdev_sync_config(DeviceState *dev, Error **errp)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (!dc->sync_config) {
+        error_setg(errp, "device-sync-config is not supported for '%s'",
+                   object_get_typename(OBJECT(dev)));
+        return -ENOTSUP;
+    }
+
+    return dc->sync_config(dev, errp);
+}
+
+void qmp_device_sync_config(const char *id, Error **errp)
+{
+    DeviceState *dev;
+
+    /*
+     * During migration there is a race between syncing`configuration
+     * and migrating it (if migrate first, that target would get
+     * outdated version), so let's just not allow it.
+     */
+
+    if (migration_is_running()) {
+        error_setg(errp, "Config synchronization is not allowed "
+                   "during migration");
+        return;
+    }
+
+    dev = find_device_state(id, true, errp);
+    if (!dev) {
+        return;
+    }
+
+    qdev_sync_config(dev, errp);
+}
+
 void hmp_device_add(Monitor *mon, const QDict *qdict)
 {
     Error *err = NULL;
-- 
MST
Re: [PULL 23/65] qapi: introduce device-sync-config
Posted by Daniel P. Berrangé 2 weeks, 4 days ago
On Mon, Nov 04, 2024 at 04:07:00PM -0500, Michael S. Tsirkin wrote:
> From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> 
> Add command to sync config from vhost-user backend to the device. It
> may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
> triggered interrupt to the guest or just not available (not supported
> by vhost-user server).
> 
> Command result is racy if allow it during migration. Let's not allow
> that.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
> Acked-by: Raphael Norwitz <raphael@enfabrica.net>
> Message-Id: <20240920094936.450987-4-vsementsov@yandex-team.ru>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>  qapi/qdev.json            | 24 ++++++++++++++++++++++++
>  include/hw/qdev-core.h    |  6 ++++++
>  hw/block/vhost-user-blk.c |  1 +
>  hw/virtio/virtio-pci.c    |  9 +++++++++
>  system/qdev-monitor.c     | 38 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 78 insertions(+)
> 
> diff --git a/qapi/qdev.json b/qapi/qdev.json
> index 53d147c7b4..2a581129c9 100644
> --- a/qapi/qdev.json
> +++ b/qapi/qdev.json
> @@ -163,3 +163,27 @@
>  ##
>  { 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
>    'data': { '*device': 'str', 'path': 'str' } }
> +
> +##
> +# @device-sync-config:
> +#
> +# Synchronize device configuration from host to guest part.  First,
> +# copy the configuration from the host part (backend) to the guest
> +# part (frontend).  Then notify guest software that device
> +# configuration changed.
> +#
> +# The command may be used to notify the guest about block device
> +# capcity change.  Currently only vhost-user-blk device supports
> +# this.
> +#
> +# @id: the device's ID or QOM path
> +#
> +# Features:
> +#
> +# @unstable: The command is experimental.
> +#
> +# Since: 9.1
> +##

Again, we're in the 9.2 dev cycle currently.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [PULL 23/65] qapi: introduce device-sync-config
Posted by Michael S. Tsirkin 2 weeks, 3 days ago
On Tue, Nov 05, 2024 at 09:10:07AM +0000, Daniel P. Berrangé wrote:
> On Mon, Nov 04, 2024 at 04:07:00PM -0500, Michael S. Tsirkin wrote:
> > From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> > 
> > Add command to sync config from vhost-user backend to the device. It
> > may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
> > triggered interrupt to the guest or just not available (not supported
> > by vhost-user server).
> > 
> > Command result is racy if allow it during migration. Let's not allow
> > that.
> > 
> > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> > Reviewed-by: Markus Armbruster <armbru@redhat.com>
> > Acked-by: Raphael Norwitz <raphael@enfabrica.net>
> > Message-Id: <20240920094936.450987-4-vsementsov@yandex-team.ru>
> > Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > ---
> >  qapi/qdev.json            | 24 ++++++++++++++++++++++++
> >  include/hw/qdev-core.h    |  6 ++++++
> >  hw/block/vhost-user-blk.c |  1 +
> >  hw/virtio/virtio-pci.c    |  9 +++++++++
> >  system/qdev-monitor.c     | 38 ++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 78 insertions(+)
> > 
> > diff --git a/qapi/qdev.json b/qapi/qdev.json
> > index 53d147c7b4..2a581129c9 100644
> > --- a/qapi/qdev.json
> > +++ b/qapi/qdev.json
> > @@ -163,3 +163,27 @@
> >  ##
> >  { 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
> >    'data': { '*device': 'str', 'path': 'str' } }
> > +
> > +##
> > +# @device-sync-config:
> > +#
> > +# Synchronize device configuration from host to guest part.  First,
> > +# copy the configuration from the host part (backend) to the guest
> > +# part (frontend).  Then notify guest software that device
> > +# configuration changed.
> > +#
> > +# The command may be used to notify the guest about block device
> > +# capcity change.  Currently only vhost-user-blk device supports
> > +# this.
> > +#
> > +# @id: the device's ID or QOM path
> > +#
> > +# Features:
> > +#
> > +# @unstable: The command is experimental.
> > +#
> > +# Since: 9.1
> > +##
> 
> Again, we're in the 9.2 dev cycle currently.


Good points, Vladimir, can you fix this up pls?

> 
> With regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|