Re: [PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device

2023-09-06 Thread Matias Ezequiel Vara Larsen
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

2023-09-05 Thread Alex Bennée


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

2023-09-05 Thread Matias Ezequiel Vara Larsen
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

2023-07-10 Thread Michael S. Tsirkin
> +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

2023-07-10 Thread Alex Bennée
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