Re: [PATCH 06/31] vhost: Route guest->host notification through shadow virtqueue

2022-02-08 Thread Jason Wang


在 2022/1/31 下午7:33, Eugenio Perez Martin 写道:

On Fri, Jan 28, 2022 at 7:57 AM Jason Wang  wrote:


在 2022/1/22 上午4:27, Eugenio Pérez 写道:

At this moment no buffer forwarding will be performed in SVQ mode: Qemu
just forward the guest's kicks to the device. This commit also set up
SVQs in the vhost device.

Host memory notifiers regions are left out for simplicity, and they will
not be addressed in this series.


I wonder if it's better to squash this into patch 5 since it gives us a
full guest->host forwarding.


I'm fine with that if you think it makes the review easier.



Yes please.





Signed-off-by: Eugenio Pérez 
---
   include/hw/virtio/vhost-vdpa.h |   4 ++
   hw/virtio/vhost-vdpa.c | 122 -
   2 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 3ce79a646d..009a9f3b6b 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -12,6 +12,8 @@
   #ifndef HW_VIRTIO_VHOST_VDPA_H
   #define HW_VIRTIO_VHOST_VDPA_H

+#include 
+
   #include "hw/virtio/virtio.h"
   #include "standard-headers/linux/vhost_types.h"

@@ -27,6 +29,8 @@ typedef struct vhost_vdpa {
   bool iotlb_batch_begin_sent;
   MemoryListener listener;
   struct vhost_vdpa_iova_range iova_range;
+bool shadow_vqs_enabled;
+GPtrArray *shadow_vqs;
   struct vhost_dev *dev;
   VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
   } VhostVDPA;
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 6c10a7f05f..18de14f0fb 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -17,12 +17,14 @@
   #include "hw/virtio/vhost.h"
   #include "hw/virtio/vhost-backend.h"
   #include "hw/virtio/virtio-net.h"
+#include "hw/virtio/vhost-shadow-virtqueue.h"
   #include "hw/virtio/vhost-vdpa.h"
   #include "exec/address-spaces.h"
   #include "qemu/main-loop.h"
   #include "cpu.h"
   #include "trace.h"
   #include "qemu-common.h"
+#include "qapi/error.h"

   /*
* Return one past the end of the end of section. Be careful with uint64_t
@@ -409,8 +411,14 @@ err:

   static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)
   {
+struct vhost_vdpa *v = dev->opaque;
   int i;

+if (v->shadow_vqs_enabled) {
+/* SVQ is not compatible with host notifiers mr */


I guess there should be a TODO or FIXME here.


Sure I can add it.


+return;
+}
+
   for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) {
   if (vhost_vdpa_host_notifier_init(dev, i)) {
   goto err;
@@ -424,6 +432,17 @@ err:
   return;
   }

+static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev)
+{
+struct vhost_vdpa *v = dev->opaque;
+size_t idx;
+
+for (idx = 0; idx < v->shadow_vqs->len; ++idx) {
+vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, idx));
+}
+g_ptr_array_free(v->shadow_vqs, true);
+}
+
   static int vhost_vdpa_cleanup(struct vhost_dev *dev)
   {
   struct vhost_vdpa *v;
@@ -432,6 +451,7 @@ static int vhost_vdpa_cleanup(struct vhost_dev *dev)
   trace_vhost_vdpa_cleanup(dev, v);
   vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
   memory_listener_unregister(>listener);
+vhost_vdpa_svq_cleanup(dev);

   dev->opaque = NULL;
   ram_block_discard_disable(false);
@@ -507,9 +527,15 @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev,

   static int vhost_vdpa_reset_device(struct vhost_dev *dev)
   {
+struct vhost_vdpa *v = dev->opaque;
   int ret;
   uint8_t status = 0;

+for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
+VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
+vhost_svq_stop(svq);
+}
+
   ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, );
   trace_vhost_vdpa_reset_device(dev, status);
   return ret;
@@ -639,13 +665,28 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev 
*dev,
   return ret;
   }

-static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev,
-   struct vhost_vring_file *file)
+static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
   {
   trace_vhost_vdpa_set_vring_kick(dev, file->index, file->fd);
   return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file);
   }

+static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev,
+   struct vhost_vring_file *file)
+{
+struct vhost_vdpa *v = dev->opaque;
+int vdpa_idx = vhost_vdpa_get_vq_index(dev, file->index);
+
+if (v->shadow_vqs_enabled) {
+VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx);
+vhost_svq_set_svq_kick_fd(svq, file->fd);
+return 0;
+} else {
+return vhost_vdpa_set_vring_dev_kick(dev, file);
+}
+}
+
   static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
  

Re: [PATCH 06/31] vhost: Route guest->host notification through shadow virtqueue

2022-01-27 Thread Jason Wang


在 2022/1/22 上午4:27, Eugenio Pérez 写道:

At this moment no buffer forwarding will be performed in SVQ mode: Qemu
just forward the guest's kicks to the device. This commit also set up
SVQs in the vhost device.

Host memory notifiers regions are left out for simplicity, and they will
not be addressed in this series.



I wonder if it's better to squash this into patch 5 since it gives us a 
full guest->host forwarding.





Signed-off-by: Eugenio Pérez 
---
  include/hw/virtio/vhost-vdpa.h |   4 ++
  hw/virtio/vhost-vdpa.c | 122 -
  2 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 3ce79a646d..009a9f3b6b 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -12,6 +12,8 @@
  #ifndef HW_VIRTIO_VHOST_VDPA_H
  #define HW_VIRTIO_VHOST_VDPA_H
  
+#include 

+
  #include "hw/virtio/virtio.h"
  #include "standard-headers/linux/vhost_types.h"
  
@@ -27,6 +29,8 @@ typedef struct vhost_vdpa {

  bool iotlb_batch_begin_sent;
  MemoryListener listener;
  struct vhost_vdpa_iova_range iova_range;
+bool shadow_vqs_enabled;
+GPtrArray *shadow_vqs;
  struct vhost_dev *dev;
  VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
  } VhostVDPA;
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 6c10a7f05f..18de14f0fb 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -17,12 +17,14 @@
  #include "hw/virtio/vhost.h"
  #include "hw/virtio/vhost-backend.h"
  #include "hw/virtio/virtio-net.h"
+#include "hw/virtio/vhost-shadow-virtqueue.h"
  #include "hw/virtio/vhost-vdpa.h"
  #include "exec/address-spaces.h"
  #include "qemu/main-loop.h"
  #include "cpu.h"
  #include "trace.h"
  #include "qemu-common.h"
+#include "qapi/error.h"
  
  /*

   * Return one past the end of the end of section. Be careful with uint64_t
@@ -409,8 +411,14 @@ err:
  
  static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)

  {
+struct vhost_vdpa *v = dev->opaque;
  int i;
  
+if (v->shadow_vqs_enabled) {

+/* SVQ is not compatible with host notifiers mr */



I guess there should be a TODO or FIXME here.



+return;
+}
+
  for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) {
  if (vhost_vdpa_host_notifier_init(dev, i)) {
  goto err;
@@ -424,6 +432,17 @@ err:
  return;
  }
  
+static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev)

+{
+struct vhost_vdpa *v = dev->opaque;
+size_t idx;
+
+for (idx = 0; idx < v->shadow_vqs->len; ++idx) {
+vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, idx));
+}
+g_ptr_array_free(v->shadow_vqs, true);
+}
+
  static int vhost_vdpa_cleanup(struct vhost_dev *dev)
  {
  struct vhost_vdpa *v;
@@ -432,6 +451,7 @@ static int vhost_vdpa_cleanup(struct vhost_dev *dev)
  trace_vhost_vdpa_cleanup(dev, v);
  vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
  memory_listener_unregister(>listener);
+vhost_vdpa_svq_cleanup(dev);
  
  dev->opaque = NULL;

  ram_block_discard_disable(false);
@@ -507,9 +527,15 @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev,
  
  static int vhost_vdpa_reset_device(struct vhost_dev *dev)

  {
+struct vhost_vdpa *v = dev->opaque;
  int ret;
  uint8_t status = 0;
  
+for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {

+VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
+vhost_svq_stop(svq);
+}
+
  ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, );
  trace_vhost_vdpa_reset_device(dev, status);
  return ret;
@@ -639,13 +665,28 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev 
*dev,
  return ret;
  }
  
-static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev,

-   struct vhost_vring_file *file)
+static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
  {
  trace_vhost_vdpa_set_vring_kick(dev, file->index, file->fd);
  return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file);
  }
  
+static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev,

+   struct vhost_vring_file *file)
+{
+struct vhost_vdpa *v = dev->opaque;
+int vdpa_idx = vhost_vdpa_get_vq_index(dev, file->index);
+
+if (v->shadow_vqs_enabled) {
+VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx);
+vhost_svq_set_svq_kick_fd(svq, file->fd);
+return 0;
+} else {
+return vhost_vdpa_set_vring_dev_kick(dev, file);
+}
+}
+
  static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
 struct vhost_vring_file *file)
  {
@@ -653,6 +694,33 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
  return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);