? 2021/10/30 ??2:35, Eugenio P?rez ??:> If device supports host notifiers, this makes one jump less (kernel) to
> deliver SVQ notifications to it.
>
> Signed-off-by: Eugenio P?rez <eperezma at redhat.com>
> ---
> hw/virtio/vhost-shadow-virtqueue.h | 2 ++
> hw/virtio/vhost-shadow-virtqueue.c | 23 ++++++++++++++++++++++-
> 2 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/hw/virtio/vhost-shadow-virtqueue.h
b/hw/virtio/vhost-shadow-virtqueue.h
> index 30ab9643b9..eb0a54f954 100644
> --- a/hw/virtio/vhost-shadow-virtqueue.h
> +++ b/hw/virtio/vhost-shadow-virtqueue.h
> @@ -18,6 +18,8 @@ typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
> void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int
svq_kick_fd);
> const EventNotifier *vhost_svq_get_dev_kick_notifier(
> const VhostShadowVirtqueue
*svq);
> +void vhost_svq_set_host_mr_notifier(VhostShadowVirtqueue *svq, void
*addr);
> +
> void vhost_svq_start(struct vhost_dev *dev, unsigned idx,
> VhostShadowVirtqueue *svq, int svq_kick_fd);
> void vhost_svq_stop(struct vhost_dev *dev, unsigned idx,
> diff --git a/hw/virtio/vhost-shadow-virtqueue.c
b/hw/virtio/vhost-shadow-virtqueue.c
> index fda60d11db..e3dcc039b6 100644
> --- a/hw/virtio/vhost-shadow-virtqueue.c
> +++ b/hw/virtio/vhost-shadow-virtqueue.c
> @@ -29,6 +29,12 @@ typedef struct VhostShadowVirtqueue {
> * So shadow virtqueue must not clean it, or we would lose VirtQueue
one.
> */
> EventNotifier svq_kick;
> +
> + /* Device's host notifier memory region. NULL means no region */
> + void *host_notifier_mr;
> +
> + /* Virtio queue shadowing */
> + VirtQueue *vq;
> } VhostShadowVirtqueue;
>
> /**
> @@ -50,7 +56,20 @@ static void vhost_handle_guest_kick(EventNotifier *n)
> return;
> }
>
> - event_notifier_set(&svq->hdev_kick);
> + if (svq->host_notifier_mr) {
> + uint16_t *mr = svq->host_notifier_mr;
> + *mr = virtio_get_queue_index(svq->vq);
Do we need barriers around the possible MMIO here?
To avoid those complicated stuff, I'd rather simply go with eventfd path.
Note mmio and eventfd are not mutually exclusive.
Thanks
> + } else {
> + event_notifier_set(&svq->hdev_kick);
> + }
> +}
> +
> +/*
> + * Set the device's memory region notifier. addr = NULL clear it.
> + */
> +void vhost_svq_set_host_mr_notifier(VhostShadowVirtqueue *svq, void *addr)
> +{
> + svq->host_notifier_mr = addr;
> }
>
> /**
> @@ -134,6 +153,7 @@ void vhost_svq_stop(struct vhost_dev *dev, unsigned
idx,
> */
> VhostShadowVirtqueue *vhost_svq_new(struct vhost_dev *dev, int idx)
> {
> + int vq_idx = dev->vq_index + idx;
> g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue,
1);
> int r;
>
> @@ -151,6 +171,7 @@ VhostShadowVirtqueue *vhost_svq_new(struct vhost_dev
*dev, int idx)
> goto err_init_hdev_call;
> }
>
> + svq->vq = virtio_get_queue(dev->vdev, vq_idx);
> return g_steal_pointer(&svq);
>
> err_init_hdev_call: