Vhost shadow virtqueue (SVQ) is an intermediate jump for virtqueue
notifications and buffers, allowing qemu to track them. While qemu is
forwarding the buffers and virtqueue changes, it is able to commit the
memory it's being dirtied, the same way regular qemu's VirtIO devices
do.
This commit only exposes basic SVQ allocation and free. Next patches of
the series add functionality like notifications and buffers forwarding.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
hw/virtio/vhost-shadow-virtqueue.h | 21 ++++++++++
hw/virtio/vhost-shadow-virtqueue.c | 64 ++++++++++++++++++++++++++++++
hw/virtio/meson.build | 2 +-
3 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
new file mode 100644
index 0000000000..61ea112002
--- /dev/null
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -0,0 +1,21 @@
+/*
+ * vhost shadow virtqueue
+ *
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021
+ * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef VHOST_SHADOW_VIRTQUEUE_H
+#define VHOST_SHADOW_VIRTQUEUE_H
+
+#include "hw/virtio/vhost.h"
+
+typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
+
+VhostShadowVirtqueue *vhost_svq_new(void);
+
+void vhost_svq_free(VhostShadowVirtqueue *vq);
+
+#endif
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
new file mode 100644
index 0000000000..5ee7b401cb
--- /dev/null
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -0,0 +1,64 @@
+/*
+ * vhost shadow virtqueue
+ *
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021
+ * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/virtio/vhost-shadow-virtqueue.h"
+
+#include "qemu/error-report.h"
+#include "qemu/event_notifier.h"
+
+/* Shadow virtqueue to relay notifications */
+typedef struct VhostShadowVirtqueue {
+ /* Shadow kick notifier, sent to vhost */
+ EventNotifier hdev_kick;
+ /* Shadow call notifier, sent to vhost */
+ EventNotifier hdev_call;
+} VhostShadowVirtqueue;
+
+/**
+ * Creates vhost shadow virtqueue, and instruct vhost device to use the shadow
+ * methods and file descriptors.
+ */
+VhostShadowVirtqueue *vhost_svq_new(void)
+{
+ g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
+ int r;
+
+ r = event_notifier_init(&svq->hdev_kick, 0);
+ if (r != 0) {
+ error_report("Couldn't create kick event notifier: %s",
+ strerror(errno));
+ goto err_init_hdev_kick;
+ }
+
+ r = event_notifier_init(&svq->hdev_call, 0);
+ if (r != 0) {
+ error_report("Couldn't create call event notifier: %s",
+ strerror(errno));
+ goto err_init_hdev_call;
+ }
+
+ return g_steal_pointer(&svq);
+
+err_init_hdev_call:
+ event_notifier_cleanup(&svq->hdev_kick);
+
+err_init_hdev_kick:
+ return NULL;
+}
+
+/**
+ * Free the resources of the shadow virtqueue.
+ */
+void vhost_svq_free(VhostShadowVirtqueue *vq)
+{
+ event_notifier_cleanup(&vq->hdev_kick);
+ event_notifier_cleanup(&vq->hdev_call);
+ g_free(vq);
+}
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 521f7d64a8..2dc87613bc 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c'))
virtio_ss = ss.source_set()
virtio_ss.add(files('virtio.c'))
-virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c'))
+virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c'))
virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c'))
virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c'))
virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c'))
--
2.27.0
在 2022/1/22 上午4:27, Eugenio Pérez 写道:
> Vhost shadow virtqueue (SVQ) is an intermediate jump for virtqueue
> notifications and buffers, allowing qemu to track them. While qemu is
> forwarding the buffers and virtqueue changes, it is able to commit the
> memory it's being dirtied, the same way regular qemu's VirtIO devices
> do.
>
> This commit only exposes basic SVQ allocation and free. Next patches of
> the series add functionality like notifications and buffers forwarding.
>
> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> ---
> hw/virtio/vhost-shadow-virtqueue.h | 21 ++++++++++
> hw/virtio/vhost-shadow-virtqueue.c | 64 ++++++++++++++++++++++++++++++
> hw/virtio/meson.build | 2 +-
> 3 files changed, 86 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
> create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
>
> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
> new file mode 100644
> index 0000000000..61ea112002
> --- /dev/null
> +++ b/hw/virtio/vhost-shadow-virtqueue.h
> @@ -0,0 +1,21 @@
> +/*
> + * vhost shadow virtqueue
> + *
> + * SPDX-FileCopyrightText: Red Hat, Inc. 2021
> + * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef VHOST_SHADOW_VIRTQUEUE_H
> +#define VHOST_SHADOW_VIRTQUEUE_H
> +
> +#include "hw/virtio/vhost.h"
> +
> +typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
> +
> +VhostShadowVirtqueue *vhost_svq_new(void);
> +
> +void vhost_svq_free(VhostShadowVirtqueue *vq);
> +
> +#endif
> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
> new file mode 100644
> index 0000000000..5ee7b401cb
> --- /dev/null
> +++ b/hw/virtio/vhost-shadow-virtqueue.c
> @@ -0,0 +1,64 @@
> +/*
> + * vhost shadow virtqueue
> + *
> + * SPDX-FileCopyrightText: Red Hat, Inc. 2021
> + * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/virtio/vhost-shadow-virtqueue.h"
> +
> +#include "qemu/error-report.h"
> +#include "qemu/event_notifier.h"
> +
> +/* Shadow virtqueue to relay notifications */
> +typedef struct VhostShadowVirtqueue {
> + /* Shadow kick notifier, sent to vhost */
> + EventNotifier hdev_kick;
> + /* Shadow call notifier, sent to vhost */
> + EventNotifier hdev_call;
> +} VhostShadowVirtqueue;
> +
> +/**
> + * Creates vhost shadow virtqueue, and instruct vhost device to use the shadow
> + * methods and file descriptors.
> + */
> +VhostShadowVirtqueue *vhost_svq_new(void)
> +{
> + g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
> + int r;
> +
> + r = event_notifier_init(&svq->hdev_kick, 0);
> + if (r != 0) {
> + error_report("Couldn't create kick event notifier: %s",
> + strerror(errno));
> + goto err_init_hdev_kick;
> + }
> +
> + r = event_notifier_init(&svq->hdev_call, 0);
> + if (r != 0) {
> + error_report("Couldn't create call event notifier: %s",
> + strerror(errno));
> + goto err_init_hdev_call;
> + }
> +
> + return g_steal_pointer(&svq);
> +
> +err_init_hdev_call:
> + event_notifier_cleanup(&svq->hdev_kick);
> +
> +err_init_hdev_kick:
> + return NULL;
> +}
> +
> +/**
> + * Free the resources of the shadow virtqueue.
> + */
> +void vhost_svq_free(VhostShadowVirtqueue *vq)
> +{
> + event_notifier_cleanup(&vq->hdev_kick);
> + event_notifier_cleanup(&vq->hdev_call);
> + g_free(vq);
> +}
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index 521f7d64a8..2dc87613bc 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c'))
>
> virtio_ss = ss.source_set()
> virtio_ss.add(files('virtio.c'))
> -virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c'))
> +virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c'))
I wonder if we need a dedicated config option for shadow virtqueue.
Thanks
> virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c'))
> virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c'))
> virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c'))
On Fri, Jan 28, 2022 at 7:00 AM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2022/1/22 上午4:27, Eugenio Pérez 写道:
> > Vhost shadow virtqueue (SVQ) is an intermediate jump for virtqueue
> > notifications and buffers, allowing qemu to track them. While qemu is
> > forwarding the buffers and virtqueue changes, it is able to commit the
> > memory it's being dirtied, the same way regular qemu's VirtIO devices
> > do.
> >
> > This commit only exposes basic SVQ allocation and free. Next patches of
> > the series add functionality like notifications and buffers forwarding.
> >
> > Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> > ---
> > hw/virtio/vhost-shadow-virtqueue.h | 21 ++++++++++
> > hw/virtio/vhost-shadow-virtqueue.c | 64 ++++++++++++++++++++++++++++++
> > hw/virtio/meson.build | 2 +-
> > 3 files changed, 86 insertions(+), 1 deletion(-)
> > create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
> > create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
> >
> > diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
> > new file mode 100644
> > index 0000000000..61ea112002
> > --- /dev/null
> > +++ b/hw/virtio/vhost-shadow-virtqueue.h
> > @@ -0,0 +1,21 @@
> > +/*
> > + * vhost shadow virtqueue
> > + *
> > + * SPDX-FileCopyrightText: Red Hat, Inc. 2021
> > + * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#ifndef VHOST_SHADOW_VIRTQUEUE_H
> > +#define VHOST_SHADOW_VIRTQUEUE_H
> > +
> > +#include "hw/virtio/vhost.h"
> > +
> > +typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
> > +
> > +VhostShadowVirtqueue *vhost_svq_new(void);
> > +
> > +void vhost_svq_free(VhostShadowVirtqueue *vq);
> > +
> > +#endif
> > diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
> > new file mode 100644
> > index 0000000000..5ee7b401cb
> > --- /dev/null
> > +++ b/hw/virtio/vhost-shadow-virtqueue.c
> > @@ -0,0 +1,64 @@
> > +/*
> > + * vhost shadow virtqueue
> > + *
> > + * SPDX-FileCopyrightText: Red Hat, Inc. 2021
> > + * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/virtio/vhost-shadow-virtqueue.h"
> > +
> > +#include "qemu/error-report.h"
> > +#include "qemu/event_notifier.h"
> > +
> > +/* Shadow virtqueue to relay notifications */
> > +typedef struct VhostShadowVirtqueue {
> > + /* Shadow kick notifier, sent to vhost */
> > + EventNotifier hdev_kick;
> > + /* Shadow call notifier, sent to vhost */
> > + EventNotifier hdev_call;
> > +} VhostShadowVirtqueue;
> > +
> > +/**
> > + * Creates vhost shadow virtqueue, and instruct vhost device to use the shadow
> > + * methods and file descriptors.
> > + */
> > +VhostShadowVirtqueue *vhost_svq_new(void)
> > +{
> > + g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
> > + int r;
> > +
> > + r = event_notifier_init(&svq->hdev_kick, 0);
> > + if (r != 0) {
> > + error_report("Couldn't create kick event notifier: %s",
> > + strerror(errno));
> > + goto err_init_hdev_kick;
> > + }
> > +
> > + r = event_notifier_init(&svq->hdev_call, 0);
> > + if (r != 0) {
> > + error_report("Couldn't create call event notifier: %s",
> > + strerror(errno));
> > + goto err_init_hdev_call;
> > + }
> > +
> > + return g_steal_pointer(&svq);
> > +
> > +err_init_hdev_call:
> > + event_notifier_cleanup(&svq->hdev_kick);
> > +
> > +err_init_hdev_kick:
> > + return NULL;
> > +}
> > +
> > +/**
> > + * Free the resources of the shadow virtqueue.
> > + */
> > +void vhost_svq_free(VhostShadowVirtqueue *vq)
> > +{
> > + event_notifier_cleanup(&vq->hdev_kick);
> > + event_notifier_cleanup(&vq->hdev_call);
> > + g_free(vq);
> > +}
> > diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> > index 521f7d64a8..2dc87613bc 100644
> > --- a/hw/virtio/meson.build
> > +++ b/hw/virtio/meson.build
> > @@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c'))
> >
> > virtio_ss = ss.source_set()
> > virtio_ss.add(files('virtio.c'))
> > -virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c'))
> > +virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c'))
>
>
> I wonder if we need a dedicated config option for shadow virtqueue.
>
I'd say that the changes are isolated enough and require no external
library dependencies so the gain is little. But it can be done with an
explicit enable/disable for sure.
Thanks!
> Thanks
>
>
> > virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c'))
> > virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c'))
> > virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c'))
>
On Fri, Jan 21, 2022 at 9:32 PM Eugenio Pérez <eperezma@redhat.com> wrote:
>
> Vhost shadow virtqueue (SVQ) is an intermediate jump for virtqueue
> notifications and buffers, allowing qemu to track them. While qemu is
> forwarding the buffers and virtqueue changes, it is able to commit the
> memory it's being dirtied, the same way regular qemu's VirtIO devices
> do.
>
> This commit only exposes basic SVQ allocation and free. Next patches of
> the series add functionality like notifications and buffers forwarding.
>
> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> ---
> hw/virtio/vhost-shadow-virtqueue.h | 21 ++++++++++
> hw/virtio/vhost-shadow-virtqueue.c | 64 ++++++++++++++++++++++++++++++
> hw/virtio/meson.build | 2 +-
> 3 files changed, 86 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
> create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
>
> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
> new file mode 100644
> index 0000000000..61ea112002
> --- /dev/null
> +++ b/hw/virtio/vhost-shadow-virtqueue.h
> @@ -0,0 +1,21 @@
> +/*
> + * vhost shadow virtqueue
> + *
> + * SPDX-FileCopyrightText: Red Hat, Inc. 2021
> + * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef VHOST_SHADOW_VIRTQUEUE_H
> +#define VHOST_SHADOW_VIRTQUEUE_H
> +
> +#include "hw/virtio/vhost.h"
> +
> +typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
> +
> +VhostShadowVirtqueue *vhost_svq_new(void);
> +
> +void vhost_svq_free(VhostShadowVirtqueue *vq);
> +
> +#endif
> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
> new file mode 100644
> index 0000000000..5ee7b401cb
> --- /dev/null
> +++ b/hw/virtio/vhost-shadow-virtqueue.c
> @@ -0,0 +1,64 @@
> +/*
> + * vhost shadow virtqueue
> + *
> + * SPDX-FileCopyrightText: Red Hat, Inc. 2021
> + * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/virtio/vhost-shadow-virtqueue.h"
> +
> +#include "qemu/error-report.h"
> +#include "qemu/event_notifier.h"
> +
> +/* Shadow virtqueue to relay notifications */
> +typedef struct VhostShadowVirtqueue {
This is already typedef as VhostShadowVirtqueue in the header, so I
will remove it here for the next version.
> + /* Shadow kick notifier, sent to vhost */
> + EventNotifier hdev_kick;
> + /* Shadow call notifier, sent to vhost */
> + EventNotifier hdev_call;
> +} VhostShadowVirtqueue;
> +
> +/**
> + * Creates vhost shadow virtqueue, and instruct vhost device to use the shadow
> + * methods and file descriptors.
> + */
> +VhostShadowVirtqueue *vhost_svq_new(void)
> +{
> + g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
> + int r;
> +
> + r = event_notifier_init(&svq->hdev_kick, 0);
> + if (r != 0) {
> + error_report("Couldn't create kick event notifier: %s",
> + strerror(errno));
> + goto err_init_hdev_kick;
> + }
> +
> + r = event_notifier_init(&svq->hdev_call, 0);
> + if (r != 0) {
> + error_report("Couldn't create call event notifier: %s",
> + strerror(errno));
> + goto err_init_hdev_call;
> + }
> +
> + return g_steal_pointer(&svq);
> +
> +err_init_hdev_call:
> + event_notifier_cleanup(&svq->hdev_kick);
> +
> +err_init_hdev_kick:
> + return NULL;
> +}
> +
> +/**
> + * Free the resources of the shadow virtqueue.
> + */
> +void vhost_svq_free(VhostShadowVirtqueue *vq)
> +{
> + event_notifier_cleanup(&vq->hdev_kick);
> + event_notifier_cleanup(&vq->hdev_call);
> + g_free(vq);
> +}
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index 521f7d64a8..2dc87613bc 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c'))
>
> virtio_ss = ss.source_set()
> virtio_ss.add(files('virtio.c'))
> -virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c'))
> +virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c'))
> virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c'))
> virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c'))
> virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c'))
> --
> 2.27.0
>
>
© 2016 - 2026 Red Hat, Inc.