Re: [PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device
On Tue, Sep 05, 2023 at 06:01:56PM +0100, Alex Bennée wrote: > > Matias Ezequiel Vara Larsen writes: > > > On Mon, Jul 10, 2023 at 04:35:09PM +0100, Alex Bennée wrote: > >> In theory we shouldn't need to repeat so much boilerplate to support > >> vhost-user backends. This provides a generic vhost-user-base QOM > >> object and a derived vhost-user-device for which the user needs to > >> provide the few bits of information that aren't currently provided by > >> the vhost-user protocol. This should provide a baseline implementation > >> from which the other vhost-user stub can specialise. > >> > >> Signed-off-by: Alex Bennée > >> > >> --- > >> v2 > >> - split into vub and vud > > >> + > >> +/* > >> + * Disable guest notifiers, by default all notifications will be via > >> the > >> + * asynchronous vhost-user socket. > >> + */ > >> +vdev->use_guest_notifier_mask = false; > >> + > >> +/* Allocate queues */ > >> +vub->vqs = g_ptr_array_sized_new(vub->num_vqs); > >> +for (int i = 0; i < vub->num_vqs; i++) { > >> +g_ptr_array_add(vub->vqs, > >> +virtio_add_queue(vdev, 4, vub_handle_output)); > >> +} > >> + > > > > Hello Alex, apologies if someone already asked this. If I understand > > correctly, the second parameter of virtio_add_queue() is the len of the > > queue. Why have you chosen "4" as its value? Shall qemu query the len of > > the queue from the vhost-user device instead? > > Hmm yeah that is inherited from the virtio-rng backend which has a > pretty short queue. I don't think it is intrinsic to the device > implementation (although I guess that depends if a device will have > multiple requests in flight). > > I propose making is some useful ^2 (like 64) and adding a config knob to > increase it if needed. > LGTM. Matias
Re: [PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device
Matias Ezequiel Vara Larsen writes: > On Mon, Jul 10, 2023 at 04:35:09PM +0100, Alex Bennée wrote: >> In theory we shouldn't need to repeat so much boilerplate to support >> vhost-user backends. This provides a generic vhost-user-base QOM >> object and a derived vhost-user-device for which the user needs to >> provide the few bits of information that aren't currently provided by >> the vhost-user protocol. This should provide a baseline implementation >> from which the other vhost-user stub can specialise. >> >> Signed-off-by: Alex Bennée >> >> --- >> v2 >> - split into vub and vud >> + >> +/* >> + * Disable guest notifiers, by default all notifications will be via the >> + * asynchronous vhost-user socket. >> + */ >> +vdev->use_guest_notifier_mask = false; >> + >> +/* Allocate queues */ >> +vub->vqs = g_ptr_array_sized_new(vub->num_vqs); >> +for (int i = 0; i < vub->num_vqs; i++) { >> +g_ptr_array_add(vub->vqs, >> +virtio_add_queue(vdev, 4, vub_handle_output)); >> +} >> + > > Hello Alex, apologies if someone already asked this. If I understand > correctly, the second parameter of virtio_add_queue() is the len of the > queue. Why have you chosen "4" as its value? Shall qemu query the len of > the queue from the vhost-user device instead? Hmm yeah that is inherited from the virtio-rng backend which has a pretty short queue. I don't think it is intrinsic to the device implementation (although I guess that depends if a device will have multiple requests in flight). I propose making is some useful ^2 (like 64) and adding a config knob to increase it if needed. -- Alex Bennée Virtualisation Tech Lead @ Linaro
Re: [PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device
On Mon, Jul 10, 2023 at 04:35:09PM +0100, Alex Bennée wrote: > In theory we shouldn't need to repeat so much boilerplate to support > vhost-user backends. This provides a generic vhost-user-base QOM > object and a derived vhost-user-device for which the user needs to > provide the few bits of information that aren't currently provided by > the vhost-user protocol. This should provide a baseline implementation > from which the other vhost-user stub can specialise. > > Signed-off-by: Alex Bennée > > --- > v2 > - split into vub and vud > --- > include/hw/virtio/vhost-user-device.h | 45 > hw/virtio/vhost-user-device.c | 324 ++ > hw/virtio/meson.build | 2 + > 3 files changed, 371 insertions(+) > create mode 100644 include/hw/virtio/vhost-user-device.h > create mode 100644 hw/virtio/vhost-user-device.c > > diff --git a/include/hw/virtio/vhost-user-device.h > b/include/hw/virtio/vhost-user-device.h > new file mode 100644 > index 00..9105011e25 > --- /dev/null > +++ b/include/hw/virtio/vhost-user-device.h > @@ -0,0 +1,45 @@ > +/* > + * Vhost-user generic virtio device > + * > + * Copyright (c) 2023 Linaro Ltd > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef QEMU_VHOST_USER_DEVICE_H > +#define QEMU_VHOST_USER_DEVICE_H > + > +#include "hw/virtio/vhost.h" > +#include "hw/virtio/vhost-user.h" > + > +#define TYPE_VHOST_USER_BASE "vhost-user-base" > + > +OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE) > + > +struct VHostUserBase { > +VirtIODevice parent; > +/* Properties */ > +CharBackend chardev; > +uint16_t virtio_id; > +uint32_t num_vqs; > +/* State tracking */ > +VhostUserState vhost_user; > +struct vhost_virtqueue *vhost_vq; > +struct vhost_dev vhost_dev; > +GPtrArray *vqs; > +bool connected; > +}; > + > +/* needed so we can use the base realize after specialisation > + tweaks */ > +struct VHostUserBaseClass { > +/*< private >*/ > +VirtioDeviceClass parent_class; > +/*< public >*/ > +DeviceRealize parent_realize; > +}; > + > +/* shared for the benefit of the derived pci class */ > +#define TYPE_VHOST_USER_DEVICE "vhost-user-device" > + > +#endif /* QEMU_VHOST_USER_DEVICE_H */ > diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c > new file mode 100644 > index 00..b0239fa033 > --- /dev/null > +++ b/hw/virtio/vhost-user-device.c > @@ -0,0 +1,324 @@ > +/* > + * Generic vhost-user stub. This can be used to connect to any > + * vhost-user backend. All configuration details must be handled by > + * the vhost-user daemon itself > + * > + * Copyright (c) 2023 Linaro Ltd > + * Author: Alex Bennée > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "qemu/osdep.h" > +#include "qapi/error.h" > +#include "hw/qdev-properties.h" > +#include "hw/virtio/virtio-bus.h" > +#include "hw/virtio/vhost-user-device.h" > +#include "qemu/error-report.h" > + > +static void vub_start(VirtIODevice *vdev) > +{ > +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); > +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); > +VHostUserBase *vub = VHOST_USER_BASE(vdev); > +int ret, i; > + > +if (!k->set_guest_notifiers) { > +error_report("binding does not support guest notifiers"); > +return; > +} > + > +ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev); > +if (ret < 0) { > +error_report("Error enabling host notifiers: %d", -ret); > +return; > +} > + > +ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true); > +if (ret < 0) { > +error_report("Error binding guest notifier: %d", -ret); > +goto err_host_notifiers; > +} > + > +vub->vhost_dev.acked_features = vdev->guest_features; > + > +ret = vhost_dev_start(&vub->vhost_dev, vdev, true); > +if (ret < 0) { > +error_report("Error starting vhost-user-device: %d", -ret); > +goto err_guest_notifiers; > +} > + > +/* > + * guest_notifier_mask/pending not used yet, so just unmask > + * everything here. virtio-pci will do the right thing by > + * enabling/disabling irqfd. > + */ > +for (i = 0; i < vub->vhost_dev.nvqs; i++) { > +vhost_virtqueue_mask(&vub->vhost_dev, vdev, i, false); > +} > + > +return; > + > +err_guest_notifiers: > +k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false); > +err_host_notifiers: > +vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); > +} > + > +static void vub_stop(VirtIODevice *vdev) > +{ > +VHostUserBase *vub = VHOST_USER_BASE(vdev); > +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); > +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); > +int ret; > + > +if (!k->set_guest_notifiers) { > +return; > +} > + > +vhost_dev_stop(&vub->vhost_dev, vdev, true); > + > +ret = k->set_guest_noti
Re: [PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device
> +static const TypeInfo vud_info = { > +.name = TYPE_VHOST_USER_DEVICE, > +.parent = TYPE_VHOST_USER_BASE, > +.instance_size = sizeof(VHostUserBase), > +.class_init = vud_class_init, > +.class_size = sizeof(VHostUserBaseClass), I wish you didn't tie the refactoring in with new functionality. I applied but blocked creating these for now with: Subject: [PATCH] vhost-user-device: block creating instances Message-Id: block this until we are ready to commit to this command line. Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost-user-device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c index 2b028cae08..ded97b6d70 100644 --- a/hw/virtio/vhost-user-device.c +++ b/hw/virtio/vhost-user-device.c @@ -369,6 +369,7 @@ static const TypeInfo vud_info = { .instance_size = sizeof(VHostUserBase), .class_init = vud_class_init, .class_size = sizeof(VHostUserBaseClass), +.abstract = true }; static void vu_register_types(void) -- MST
[PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device
In theory we shouldn't need to repeat so much boilerplate to support vhost-user backends. This provides a generic vhost-user-base QOM object and a derived vhost-user-device for which the user needs to provide the few bits of information that aren't currently provided by the vhost-user protocol. This should provide a baseline implementation from which the other vhost-user stub can specialise. Signed-off-by: Alex Bennée --- v2 - split into vub and vud --- include/hw/virtio/vhost-user-device.h | 45 hw/virtio/vhost-user-device.c | 324 ++ hw/virtio/meson.build | 2 + 3 files changed, 371 insertions(+) create mode 100644 include/hw/virtio/vhost-user-device.h create mode 100644 hw/virtio/vhost-user-device.c diff --git a/include/hw/virtio/vhost-user-device.h b/include/hw/virtio/vhost-user-device.h new file mode 100644 index 00..9105011e25 --- /dev/null +++ b/include/hw/virtio/vhost-user-device.h @@ -0,0 +1,45 @@ +/* + * Vhost-user generic virtio device + * + * Copyright (c) 2023 Linaro Ltd + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef QEMU_VHOST_USER_DEVICE_H +#define QEMU_VHOST_USER_DEVICE_H + +#include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-user.h" + +#define TYPE_VHOST_USER_BASE "vhost-user-base" + +OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE) + +struct VHostUserBase { +VirtIODevice parent; +/* Properties */ +CharBackend chardev; +uint16_t virtio_id; +uint32_t num_vqs; +/* State tracking */ +VhostUserState vhost_user; +struct vhost_virtqueue *vhost_vq; +struct vhost_dev vhost_dev; +GPtrArray *vqs; +bool connected; +}; + +/* needed so we can use the base realize after specialisation + tweaks */ +struct VHostUserBaseClass { +/*< private >*/ +VirtioDeviceClass parent_class; +/*< public >*/ +DeviceRealize parent_realize; +}; + +/* shared for the benefit of the derived pci class */ +#define TYPE_VHOST_USER_DEVICE "vhost-user-device" + +#endif /* QEMU_VHOST_USER_DEVICE_H */ diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c new file mode 100644 index 00..b0239fa033 --- /dev/null +++ b/hw/virtio/vhost-user-device.c @@ -0,0 +1,324 @@ +/* + * Generic vhost-user stub. This can be used to connect to any + * vhost-user backend. All configuration details must be handled by + * the vhost-user daemon itself + * + * Copyright (c) 2023 Linaro Ltd + * Author: Alex Bennée + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/qdev-properties.h" +#include "hw/virtio/virtio-bus.h" +#include "hw/virtio/vhost-user-device.h" +#include "qemu/error-report.h" + +static void vub_start(VirtIODevice *vdev) +{ +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); +VHostUserBase *vub = VHOST_USER_BASE(vdev); +int ret, i; + +if (!k->set_guest_notifiers) { +error_report("binding does not support guest notifiers"); +return; +} + +ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev); +if (ret < 0) { +error_report("Error enabling host notifiers: %d", -ret); +return; +} + +ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true); +if (ret < 0) { +error_report("Error binding guest notifier: %d", -ret); +goto err_host_notifiers; +} + +vub->vhost_dev.acked_features = vdev->guest_features; + +ret = vhost_dev_start(&vub->vhost_dev, vdev, true); +if (ret < 0) { +error_report("Error starting vhost-user-device: %d", -ret); +goto err_guest_notifiers; +} + +/* + * guest_notifier_mask/pending not used yet, so just unmask + * everything here. virtio-pci will do the right thing by + * enabling/disabling irqfd. + */ +for (i = 0; i < vub->vhost_dev.nvqs; i++) { +vhost_virtqueue_mask(&vub->vhost_dev, vdev, i, false); +} + +return; + +err_guest_notifiers: +k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false); +err_host_notifiers: +vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); +} + +static void vub_stop(VirtIODevice *vdev) +{ +VHostUserBase *vub = VHOST_USER_BASE(vdev); +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); +int ret; + +if (!k->set_guest_notifiers) { +return; +} + +vhost_dev_stop(&vub->vhost_dev, vdev, true); + +ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false); +if (ret < 0) { +error_report("vhost guest notifier cleanup failed: %d", ret); +return; +} + +vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); +} + +static void vub_set_status(VirtIODevice *vdev, uint8_t status) +{ +VHostUserBase *vub = VHOST_USER_BASE(vdev); +bool should_start = virtio_dev