All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt
@ 2021-04-08  9:38 Cindy Lu
  2021-04-08  9:38 ` [PATCH v5 1/6] virtio: introduce new type in interrupt process Cindy Lu
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

These code are all tested in vp-vdpa (support configure interrupt)
vdpa_sim (not support configure interrupt)

test in virtio-pci bus and virtio-mmio bus

Change in v2:
Add support fot virtio-mmio bus
active the notifier wihle the backend support configure intterrput
misc fixes form v1

Change in v3
fix the coding style problems

Change in v4
misc fixes form v3
merge the set_config_notifier to set_guest_notifier
when vdpa start, check the feature by VIRTIO_NET_F_STATUS 

Change in v5
misc fixes form v4
split the code for introduce configure interrupt type and callback fucntion 
will init the configure interrupt in virtio-pci and virtio-mmio bus, but will 
only active while using vhost-vdpa backend


Cindy Lu (6):
  virtio: introduce new type in interrupt process
  vhost: add new call back function for config interrupt
  virtio:add support in configure interrupt
  vhost-vdpa: add support for configure interrupt
  virtio-mmio: add support for configure interrupt
  virtio-pci: add support for configure interrupt

 hw/display/vhost-user-gpu.c       |  14 ++-
 hw/net/vhost_net.c                |   9 ++
 hw/net/virtio-net.c               |  21 +++-
 hw/s390x/virtio-ccw.c             |   6 +-
 hw/virtio/trace-events            |   2 +
 hw/virtio/vhost-user-fs.c         |  12 ++-
 hw/virtio/vhost-vdpa.c            |  33 ++++++-
 hw/virtio/vhost-vsock-common.c    |  12 ++-
 hw/virtio/vhost.c                 |  38 +++++++-
 hw/virtio/virtio-crypto.c         |  13 ++-
 hw/virtio/virtio-mmio.c           |  28 +++++-
 hw/virtio/virtio-pci.c            | 157 ++++++++++++++++++++++++------
 hw/virtio/virtio.c                |  25 +++++
 include/hw/virtio/vhost-backend.h |   3 +
 include/hw/virtio/vhost.h         |   3 +
 include/hw/virtio/virtio.h        |  14 ++-
 include/net/vhost_net.h           |   3 +
 17 files changed, 334 insertions(+), 59 deletions(-)

-- 
2.21.3



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v5 1/6] virtio: introduce new type in interrupt process
  2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
@ 2021-04-08  9:38 ` Cindy Lu
  2021-04-09  6:57   ` Jason Wang
  2021-04-08  9:38 ` [PATCH v5 2/6] vhost: add new call back function for config interrupt Cindy Lu
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

To support config interrupt we need to add
a new type of interrupt process. So we introduce
the vector type
enum virtio_vector_type {
聽 聽 聽 聽 VIRTIO_VQ_VECTOR,
聽 聽 聽 聽 VIRTIO_CONFIG_VECTOR,
聽 聽 聽 聽 VIRTIO_VECTOR_UNKNOWN,
聽 聽 };
聽 聽
Now the bus which support configure interrupt is
virtio-mmio and vritio-pci. For other drivers, the function will
only check if the interrupt type is the VIRTIO_CONFIG_VQ. If not
the function will fail.

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/display/vhost-user-gpu.c    | 14 +++++---
 hw/net/virtio-net.c            | 15 +++++---
 hw/s390x/virtio-ccw.c          |  6 ++--
 hw/virtio/vhost-user-fs.c      | 12 ++++---
 hw/virtio/vhost-vsock-common.c | 12 ++++---
 hw/virtio/virtio-crypto.c      | 13 ++++---
 hw/virtio/virtio-mmio.c        |  2 +-
 hw/virtio/virtio-pci.c         | 66 ++++++++++++++++++++--------------
 include/hw/virtio/virtio.h     |  9 +++--
 9 files changed, 95 insertions(+), 54 deletions(-)

diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 51f1747c4a..959ad115b6 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -487,18 +487,24 @@ vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val)
 }
 
 static bool
-vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
+vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx,
+                                            int type)
 {
     VhostUserGPU *g = VHOST_USER_GPU(vdev);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return false;
+    }
     return vhost_virtqueue_pending(&g->vhost->dev, idx);
 }
 
 static void
-vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
+vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask,
+                                        int type)
 {
     VhostUserGPU *g = VHOST_USER_GPU(vdev);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return;
+    }
     vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
 }
 
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9179013ac4..00d95e6615 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3055,22 +3055,27 @@ static NetClientInfo net_virtio_info = {
     .announce = virtio_net_announce,
 };
 
-static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
+static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx,
+                                int type)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
     assert(n->vhost_started);
-    return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
+    if (type == VIRTIO_VQ_VECTOR) {
+        return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
+    }
+    return false;
 }
 
 static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
-                                           bool mask)
+                                           bool mask, int type)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
     NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
     assert(n->vhost_started);
-    vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
-                             vdev, idx, mask);
+    if (type == VIRTIO_VQ_VECTOR) {
+        vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
+     }
 }
 
 static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 4582e94ae7..234f749548 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1003,16 +1003,16 @@ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
          * need to manually trigger any guest masking callbacks here.
          */
         if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
-            k->guest_notifier_mask(vdev, n, false);
+            k->guest_notifier_mask(vdev, n, false, VIRTIO_VQ_VECTOR);
         }
         /* get lost events and re-inject */
         if (k->guest_notifier_pending &&
-            k->guest_notifier_pending(vdev, n)) {
+            k->guest_notifier_pending(vdev, n, VIRTIO_VQ_VECTOR)) {
             event_notifier_set(notifier);
         }
     } else {
         if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
-            k->guest_notifier_mask(vdev, n, true);
+            k->guest_notifier_mask(vdev, n, true, VIRTIO_VQ_VECTOR);
         }
         if (with_irqfd) {
             virtio_ccw_remove_irqfd(dev, n);
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 1bc5d03a00..22358767f1 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -143,17 +143,21 @@ static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 }
 
 static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
-                                            bool mask)
+                                            bool mask, int type)
 {
     VHostUserFS *fs = VHOST_USER_FS(vdev);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return;
+    }
     vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
 }
 
-static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
+static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx, int type)
 {
     VHostUserFS *fs = VHOST_USER_FS(vdev);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return false;
+     }
     return vhost_virtqueue_pending(&fs->vhost_dev, idx);
 }
 
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
index 5b2ebf3496..92c133c54c 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -97,18 +97,22 @@ static void vhost_vsock_common_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 }
 
 static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
-                                            bool mask)
+                                            bool mask, int type)
 {
     VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return;
+    }
     vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask);
 }
 
 static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
-                                               int idx)
+                                               int idx, int type)
 {
     VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return false;
+    }
     return vhost_virtqueue_pending(&vvc->vhost_dev, idx);
 }
 
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 54f9bbb789..ab7958465c 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -941,23 +941,28 @@ static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status)
 }
 
 static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
-                                           bool mask)
+                                           bool mask, int type)
 {
     VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
     int queue = virtio_crypto_vq2q(idx);
 
     assert(vcrypto->vhost_started);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return;
+    }
     cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
 }
 
-static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
+static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx,
+                                           int type)
 {
     VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
     int queue = virtio_crypto_vq2q(idx);
 
     assert(vcrypto->vhost_started);
-
+    if (type != VIRTIO_VQ_VECTOR) {
+        return false;
+    }
     return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
 }
 
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index e1b5c3b81e..1aa1aaeca4 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -627,7 +627,7 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
     }
 
     if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
-        vdc->guest_notifier_mask(vdev, n, !assign);
+        vdc->guest_notifier_mask(vdev, n, !assign, VIRTIO_VQ_VECTOR);
     }
 
     return 0;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 36524a5728..481f6e7505 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -691,23 +691,17 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
 }
 
 static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
-                                 unsigned int queue_no,
+                                 EventNotifier *n,
                                  unsigned int vector)
 {
     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
-    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
 }
 
 static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
-                                      unsigned int queue_no,
+                                      EventNotifier *n ,
                                       unsigned int vector)
 {
-    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
     int ret;
 
@@ -722,7 +716,8 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
     unsigned int vector;
     int ret, queue_no;
-
+    VirtQueue *vq;
+    EventNotifier *n;
     for (queue_no = 0; queue_no < nvqs; queue_no++) {
         if (!virtio_queue_get_num(vdev, queue_no)) {
             break;
@@ -739,7 +734,9 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
          * Otherwise, delay until unmasked in the frontend.
          */
         if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-            ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
+            vq = virtio_get_queue(vdev, queue_no);
+            n = virtio_queue_get_guest_notifier(vq);
+            ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
             if (ret < 0) {
                 kvm_virtio_pci_vq_vector_release(proxy, vector);
                 goto undo;
@@ -755,7 +752,9 @@ undo:
             continue;
         }
         if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+            vq = virtio_get_queue(vdev, queue_no);
+            n = virtio_queue_get_guest_notifier(vq);
+            kvm_virtio_pci_irqfd_release(proxy, n, vector);
         }
         kvm_virtio_pci_vq_vector_release(proxy, vector);
     }
@@ -769,7 +768,8 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
     unsigned int vector;
     int queue_no;
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-
+    VirtQueue *vq;
+    EventNotifier *n;
     for (queue_no = 0; queue_no < nvqs; queue_no++) {
         if (!virtio_queue_get_num(vdev, queue_no)) {
             break;
@@ -782,7 +782,9 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
          * Otherwise, it was cleaned when masked in the frontend.
          */
         if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+            vq = virtio_get_queue(vdev, queue_no);
+            n = virtio_queue_get_guest_notifier(vq);
+            kvm_virtio_pci_irqfd_release(proxy, n, vector);
         }
         kvm_virtio_pci_vq_vector_release(proxy, vector);
     }
@@ -791,12 +793,12 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
 static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
                                        unsigned int queue_no,
                                        unsigned int vector,
-                                       MSIMessage msg)
+                                       MSIMessage msg,
+                                       int type,
+                                        EventNotifier *n)
 {
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     VirtIOIRQFD *irqfd;
     int ret = 0;
 
@@ -816,21 +818,23 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
      * Otherwise, set it up now.
      */
     if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-        k->guest_notifier_mask(vdev, queue_no, false);
+        k->guest_notifier_mask(vdev, queue_no, false, type);
         /* Test after unmasking to avoid losing events. */
         if (k->guest_notifier_pending &&
-            k->guest_notifier_pending(vdev, queue_no)) {
+            k->guest_notifier_pending(vdev, queue_no, type)) {
             event_notifier_set(n);
         }
     } else {
-        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
+        ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
     }
     return ret;
 }
 
 static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
                                              unsigned int queue_no,
-                                             unsigned int vector)
+                                             unsigned int vector,
+                                             int type,
+                                             EventNotifier *n)
 {
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
@@ -839,9 +843,9 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
      * Otherwise, clean it up now.
      */ 
     if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-        k->guest_notifier_mask(vdev, queue_no, true);
+        k->guest_notifier_mask(vdev, queue_no, true, type);
     } else {
-        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+        kvm_virtio_pci_irqfd_release(proxy, n, vector);
     }
 }
 
@@ -851,6 +855,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
+    EventNotifier *n;
     int ret, index, unmasked = 0;
 
     while (vq) {
@@ -859,7 +864,9 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
             break;
         }
         if (index < proxy->nvqs_with_notifiers) {
-            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
+            n = virtio_queue_get_guest_notifier(vq);
+            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg,
+                        VIRTIO_VQ_VECTOR, n);
             if (ret < 0) {
                 goto undo;
             }
@@ -875,7 +882,9 @@ undo:
     while (vq && unmasked >= 0) {
         index = virtio_get_queue_index(vq);
         if (index < proxy->nvqs_with_notifiers) {
-            virtio_pci_vq_vector_mask(proxy, index, vector);
+            n = virtio_queue_get_guest_notifier(vq);
+            virtio_pci_vq_vector_mask(proxy, index, vector,
+                 VIRTIO_VQ_VECTOR, n);
             --unmasked;
         }
         vq = virtio_vector_next_queue(vq);
@@ -888,15 +897,18 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
+    EventNotifier *n;
     int index;
 
     while (vq) {
         index = virtio_get_queue_index(vq);
+         n = virtio_queue_get_guest_notifier(vq);
         if (!virtio_queue_get_num(vdev, index)) {
             break;
         }
         if (index < proxy->nvqs_with_notifiers) {
-            virtio_pci_vq_vector_mask(proxy, index, vector);
+            virtio_pci_vq_vector_mask(proxy, index, vector,
+                VIRTIO_VQ_VECTOR, n);
         }
         vq = virtio_vector_next_queue(vq);
     }
@@ -926,7 +938,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
         vq = virtio_get_queue(vdev, queue_no);
         notifier = virtio_queue_get_guest_notifier(vq);
         if (k->guest_notifier_pending) {
-            if (k->guest_notifier_pending(vdev, queue_no)) {
+            if (k->guest_notifier_pending(vdev, queue_no, VIRTIO_VQ_VECTOR)) {
                 msix_set_pending(dev, vector);
             }
         } else if (event_notifier_test_and_clear(notifier)) {
@@ -958,7 +970,7 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
     if (!msix_enabled(&proxy->pci_dev) &&
         vdev->use_guest_notifier_mask &&
         vdc->guest_notifier_mask) {
-        vdc->guest_notifier_mask(vdev, n, !assign);
+        vdc->guest_notifier_mask(vdev, n, !assign, VIRTIO_VQ_VECTOR);
     }
 
     return 0;
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b7ece7a6a8..5a1940fe70 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -67,6 +67,11 @@ typedef struct VirtQueueElement
 
 #define VIRTIO_NO_VECTOR 0xffff
 
+enum virtio_vector_type {
+    VIRTIO_VQ_VECTOR,
+    VIRTIO_CONFIG_VECTOR,
+    VIRTIO_VECTOR_UNKNOWN,
+};
 #define TYPE_VIRTIO_DEVICE "virtio-device"
 OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
 
@@ -138,13 +143,13 @@ struct VirtioDeviceClass {
      * If backend does not support masking,
      * must check in frontend instead.
      */
-    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n);
+    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n, int type);
     /* Mask/unmask events from this vq. Any events reported
      * while masked will become pending.
      * If backend does not support masking,
      * must mask in frontend instead.
      */
-    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
+    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask, int type);
     int (*start_ioeventfd)(VirtIODevice *vdev);
     void (*stop_ioeventfd)(VirtIODevice *vdev);
     /* Saving and loading of a device; trying to deprecate save/load
-- 
2.21.3



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v5 2/6] vhost: add new call back function for config interrupt
  2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
  2021-04-08  9:38 ` [PATCH v5 1/6] virtio: introduce new type in interrupt process Cindy Lu
@ 2021-04-08  9:38 ` Cindy Lu
  2021-04-09  7:12   ` Jason Wang
  2021-04-08  9:38 ` [PATCH v5 3/6] virtio:add support in configure interrupt Cindy Lu
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

to support configure interrupt, we need to
Add new call back function for config interrupt.
now聽this call back function only used in vhost-vdpa driver

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/trace-events            | 2 ++
 hw/virtio/vhost-vdpa.c            | 7 +++++++
 include/hw/virtio/vhost-backend.h | 3 +++
 3 files changed, 12 insertions(+)

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 2060a144a2..6710835b46 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -52,6 +52,8 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
 vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
 vhost_vdpa_set_owner(void *dev) "dev: %p"
 vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
+vhost_vdpa_set_config_call(void *dev, int *fd)"dev: %p fd: %p"
+
 
 # virtio.c
 virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 01d2101d09..9ba2a2bed4 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -545,6 +545,12 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
     trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
     return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
 }
+static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
+                                       int *fd)
+{
+    trace_vhost_vdpa_set_config_call(dev, fd);
+    return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, fd);
+}
 
 static int vhost_vdpa_get_features(struct vhost_dev *dev,
                                      uint64_t *features)
@@ -611,4 +617,5 @@ const VhostOps vdpa_ops = {
         .vhost_get_device_id = vhost_vdpa_get_device_id,
         .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
         .vhost_force_iommu = vhost_vdpa_force_iommu,
+        .vhost_set_config_call = vhost_vdpa_set_config_call,
 };
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 8a6f8e2a7a..adaf6982d2 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -125,6 +125,8 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
 
 typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
 
+typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
+                                       int *fd);
 typedef struct VhostOps {
     VhostBackendType backend_type;
     vhost_backend_init vhost_backend_init;
@@ -170,6 +172,7 @@ typedef struct VhostOps {
     vhost_vq_get_addr_op  vhost_vq_get_addr;
     vhost_get_device_id_op vhost_get_device_id;
     vhost_force_iommu_op vhost_force_iommu;
+    vhost_set_config_call_op vhost_set_config_call;
 } VhostOps;
 
 extern const VhostOps user_ops;
-- 
2.21.3



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v5 3/6] virtio:add support in configure interrupt
  2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
  2021-04-08  9:38 ` [PATCH v5 1/6] virtio: introduce new type in interrupt process Cindy Lu
  2021-04-08  9:38 ` [PATCH v5 2/6] vhost: add new call back function for config interrupt Cindy Lu
@ 2021-04-08  9:38 ` Cindy Lu
  2021-04-09  7:21   ` Jason Wang
  2021-04-08  9:38 ` [PATCH v5 4/6] vhost-vdpa: add support for " Cindy Lu
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

Add configure notifier support in virtio and related driver
When peer is vhost vdpa, setup the configure interrupt function
vhost_net_start and release the resource when vhost_net_stop

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/net/vhost_net.c         |  9 +++++++++
 hw/net/virtio-net.c        |  6 ++++++
 hw/virtio/vhost.c          | 38 +++++++++++++++++++++++++++++++++++++-
 hw/virtio/virtio.c         | 25 +++++++++++++++++++++++++
 include/hw/virtio/vhost.h  |  3 +++
 include/hw/virtio/virtio.h |  5 +++++
 include/net/vhost_net.h    |  3 +++
 7 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 24d555e764..12e30dc25e 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -426,6 +426,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
     vhost_virtqueue_mask(&net->dev, dev, idx, mask);
 }
 
+bool vhost_net_config_pending(VHostNetState *net, int idx)
+{
+    return vhost_config_pending(&net->dev, idx);
+}
+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev,
+                              bool mask)
+{
+    vhost_config_mask(&net->dev, dev,  mask);
+}
 VHostNetState *get_vhost_net(NetClientState *nc)
 {
     VHostNetState *vhost_net = 0;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 00d95e6615..e30a7d9835 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3064,6 +3064,9 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx,
     if (type == VIRTIO_VQ_VECTOR) {
         return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
     }
+    if (type == VIRTIO_CONFIG_VECTOR) {
+        return vhost_net_config_pending(get_vhost_net(nc->peer), idx);
+    }
     return false;
 }
 
@@ -3076,6 +3079,9 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
     if (type == VIRTIO_VQ_VECTOR) {
         vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
      }
+    if (type == VIRTIO_CONFIG_VECTOR) {
+        vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask);
+     }
 }
 
 static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 614ccc2bcb..b5e915d5cf 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1313,6 +1313,10 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
             goto fail;
         }
     }
+    r = event_notifier_init(&hdev->masked_config_notifier, 0);
+    if (r < 0) {
+        return r;
+    }
 
     if (busyloop_timeout) {
         for (i = 0; i < hdev->nvqs; ++i) {
@@ -1405,6 +1409,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
     for (i = 0; i < hdev->nvqs; ++i) {
         vhost_virtqueue_cleanup(hdev->vqs + i);
     }
+    event_notifier_cleanup(&hdev->masked_config_notifier);
     if (hdev->mem) {
         /* those are only safe after successful init */
         memory_listener_unregister(&hdev->memory_listener);
@@ -1498,6 +1503,10 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n)
     return event_notifier_test_and_clear(&vq->masked_notifier);
 }
 
+bool vhost_config_pending(struct vhost_dev *hdev, int n)
+{
+    return event_notifier_test_and_clear(&hdev->masked_config_notifier);
+}
 /* Mask/unmask events from this vq. */
 void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
                          bool mask)
@@ -1522,6 +1531,28 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
         VHOST_OPS_DEBUG("vhost_set_vring_call failed");
     }
 }
+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev,
+                         bool mask)
+{
+   int fd;
+   int r;
+   EventNotifier *masked_config_notifier = &hdev->masked_config_notifier;
+   EventNotifier *config_notifier = &vdev->config_notifier;
+   if (vdev->use_config_notifier != true) {
+        return;
+    }
+    assert(hdev->vhost_ops);
+    if (mask) {
+        assert(vdev->use_guest_notifier_mask);
+        fd = event_notifier_get_fd(masked_config_notifier);
+    } else {
+        fd = event_notifier_get_fd(config_notifier);
+    }
+   r = hdev->vhost_ops->vhost_set_config_call(hdev, &fd);
+   if (r < 0) {
+        error_report("vhost_set_config_call failed");
+    }
+}
 
 uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
                             uint64_t features)
@@ -1732,7 +1763,12 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
             goto fail_vq;
         }
     }
-
+    if (vdev->use_config_notifier == true) {
+        event_notifier_test_and_clear(&hdev->masked_config_notifier);
+        if (!vdev->use_guest_notifier_mask) {
+            vhost_config_mask(hdev, vdev,  false);
+        }
+    }
     if (hdev->log_enabled) {
         uint64_t log_base;
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ceb58fda6c..774ac3893b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3278,6 +3278,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
             virtio_vmstate_change, vdev);
     vdev->device_endian = virtio_default_endian();
     vdev->use_guest_notifier_mask = true;
+    vdev->use_config_notifier = false;
 }
 
 /*
@@ -3502,6 +3503,16 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
     }
 }
 
+static void virtio_config_read(EventNotifier *n)
+{
+    VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
+    if (vdev->use_config_notifier == false) {
+        return;
+    }
+    if (event_notifier_test_and_clear(n)) {
+        virtio_notify_config(vdev);
+    }
+}
 void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
                                                 bool with_irqfd)
 {
@@ -3517,6 +3528,16 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
         virtio_queue_guest_notifier_read(&vq->guest_notifier);
     }
 }
+void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
+                                                bool with_irqfd)
+{
+    if (assign && !with_irqfd) {
+        event_notifier_set_handler(&vdev->config_notifier,
+                                   virtio_config_read);
+    } else {
+       event_notifier_set_handler(&vdev->config_notifier, NULL);
+    }
+}
 
 EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
 {
@@ -3591,6 +3612,10 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
     return &vq->host_notifier;
 }
 
+EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev)
+{
+    return &vdev->config_notifier;
+}
 void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
 {
     vq->host_notifier_enabled = enabled;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 4a8bc75415..22efa7008e 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -91,6 +91,7 @@ struct vhost_dev {
     QLIST_HEAD(, vhost_iommu) iommu_list;
     IOMMUNotifier n;
     const VhostDevConfigOps *config_ops;
+    EventNotifier masked_config_notifier;
 };
 
 struct vhost_net {
@@ -108,6 +109,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+bool vhost_config_pending(struct vhost_dev *hdev, int n);
+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev,  bool mask);
 
 /* Test and clear masked event pending status.
  * Should be called after unmask to avoid losing events.
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 5a1940fe70..fd17dbb097 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -113,6 +113,8 @@ struct VirtIODevice
     bool use_guest_notifier_mask;
     AddressSpace *dma_as;
     QLIST_HEAD(, VirtQueue) *vector_queues;
+    EventNotifier config_notifier;
+    bool use_config_notifier;
 };
 
 struct VirtioDeviceClass {
@@ -315,11 +317,14 @@ uint16_t virtio_get_queue_index(VirtQueue *vq);
 EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
 void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
                                                 bool with_irqfd);
+void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
+                                                bool with_irqfd);
 int virtio_device_start_ioeventfd(VirtIODevice *vdev);
 int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
 void virtio_device_release_ioeventfd(VirtIODevice *vdev);
 bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
 EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
+EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev);
 void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
 void virtio_queue_host_notifier_read(EventNotifier *n);
 void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 172b0051d8..0d38c97c94 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -36,6 +36,9 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
 bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
                               int idx, bool mask);
+bool vhost_net_config_pending(VHostNetState *net, int n);
+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev,
+                              bool mask);
 int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
 VHostNetState *get_vhost_net(NetClientState *nc);
 
-- 
2.21.3



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v5 4/6] vhost-vdpa: add support for configure interrupt
  2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
                   ` (2 preceding siblings ...)
  2021-04-08  9:38 ` [PATCH v5 3/6] virtio:add support in configure interrupt Cindy Lu
@ 2021-04-08  9:38 ` Cindy Lu
  2021-04-09  7:24   ` Jason Wang
  2021-04-08  9:38 ` [PATCH v5 5/6] virtio-mmio: " Cindy Lu
  2021-04-08  9:38 ` [PATCH v5 6/6] virtio-pci: " Cindy Lu
  5 siblings, 1 reply; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

Add support for configure interrupt. Set the notifier's fd to
the kernel driver when vdpa start. also set -1 while vdpa stop.
then the kernel will release the related resource

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/vhost-vdpa.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 9ba2a2bed4..7825366f64 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -467,11 +467,33 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
     }
     return ret;
  }
-
+static void vhost_vdpa_config_notify_start(struct vhost_dev *dev,
+                                struct VirtIODevice *vdev, bool start)
+{
+    int fd = 0;
+    int r = 0;
+    if (!(dev->features & (0x1ULL << VIRTIO_NET_F_STATUS))) {
+        return;
+    }
+    if (start) {
+        fd = event_notifier_get_fd(&vdev->config_notifier);
+        r = dev->vhost_ops->vhost_set_config_call(dev, &fd);
+        if (!r) {
+            vdev->use_config_notifier = true;
+            event_notifier_set(&vdev->config_notifier);
+        }
+    } else {
+        fd = -1;
+        vdev->use_config_notifier = false;
+        r = dev->vhost_ops->vhost_set_config_call(dev, &fd);
+    }
+    return;
+}
 static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
 {
     struct vhost_vdpa *v = dev->opaque;
     trace_vhost_vdpa_dev_start(dev, started);
+    VirtIODevice *vdev = dev->vdev;
     if (started) {
         uint8_t status = 0;
         memory_listener_register(&v->listener, &address_space_memory);
@@ -479,8 +501,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
         vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
         vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
 
+        vhost_vdpa_config_notify_start(dev, vdev, true);
         return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
     } else {
+        vhost_vdpa_config_notify_start(dev, vdev, false);
         vhost_vdpa_reset_device(dev);
         vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
                                    VIRTIO_CONFIG_S_DRIVER);
-- 
2.21.3



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v5 5/6] virtio-mmio: add support for configure interrupt
  2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
                   ` (3 preceding siblings ...)
  2021-04-08  9:38 ` [PATCH v5 4/6] vhost-vdpa: add support for " Cindy Lu
@ 2021-04-08  9:38 ` Cindy Lu
  2021-04-09  7:27   ` Jason Wang
  2021-04-08  9:38 ` [PATCH v5 6/6] virtio-pci: " Cindy Lu
  5 siblings, 1 reply; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

add configure interrupt support for virtio-mmio bus. This
interrupt will working while backend is vhost-vdpa

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/virtio-mmio.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 1aa1aaeca4..64b347421b 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -632,7 +632,26 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
 
     return 0;
 }
+static int virtio_mmio_set_config_notifier(DeviceState *d,  bool assign)
+{
+    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+        VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
 
+    EventNotifier *notifier = virtio_get_config_notifier(vdev);
+    int r = 0;
+    if (assign) {
+        r = event_notifier_init(notifier, 0);
+        virtio_set_config_notifier_fd_handler(vdev, true, false);
+    } else {
+        virtio_set_config_notifier_fd_handler(vdev, false, false);
+        event_notifier_cleanup(notifier);
+    }
+        if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
+            vdc->guest_notifier_mask(vdev, 0, !assign, VIRTIO_CONFIG_VECTOR);
+    }
+    return r;
+}
 static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
                                            bool assign)
 {
@@ -654,8 +673,15 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
             goto assign_error;
         }
     }
+   r = virtio_mmio_set_config_notifier(d, assign);
+   if (r < 0) {
+            goto config_assign_error;
+   }
 
     return 0;
+config_assign_error:
+    assert(assign);
+    r = virtio_mmio_set_config_notifier(d, false);
 
 assign_error:
     /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
-- 
2.21.3



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v5 6/6] virtio-pci: add support for configure interrupt
  2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
                   ` (4 preceding siblings ...)
  2021-04-08  9:38 ` [PATCH v5 5/6] virtio-mmio: " Cindy Lu
@ 2021-04-08  9:38 ` Cindy Lu
  2021-04-09  7:39   ` Jason Wang
  5 siblings, 1 reply; 18+ messages in thread
From: Cindy Lu @ 2021-04-08  9:38 UTC (permalink / raw)
  To: lulu, mst, jasowang, qemu-devel

Add support for configure interrupt, use kvm_irqfd_assign and set the
gsi to kernel. When the configure notifier was eventfd_signal by host
kernel, this will finally inject an msix interrupt to guest

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 hw/virtio/virtio-pci.c | 91 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 88 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 481f6e7505..7b02f42c06 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -664,7 +664,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
 }
 
 static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
-                                        unsigned int queue_no,
                                         unsigned int vector)
 {
     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
@@ -726,7 +725,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
         if (vector >= msix_nr_vectors_allocated(dev)) {
             continue;
         }
-        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
+        ret = kvm_virtio_pci_vq_vector_use(proxy,  vector);
         if (ret < 0) {
             goto undo;
         }
@@ -760,6 +759,56 @@ undo:
     }
     return ret;
 }
+static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
+{
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    unsigned int vector;
+    int ret;
+    EventNotifier *n = virtio_get_config_notifier(vdev);
+    vector = vdev->config_vector ;
+    ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
+    if (ret < 0) {
+        goto undo;
+    }
+    ret = kvm_virtio_pci_irqfd_use(proxy,  n, vector);
+    if (ret < 0) {
+        goto undo;
+    }
+    return 0;
+undo:
+    kvm_virtio_pci_irqfd_release(proxy, n, vector);
+    return ret;
+}
+static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
+{
+    PCIDevice *dev = &proxy->pci_dev;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    unsigned int vector;
+    EventNotifier *n = virtio_get_config_notifier(vdev);
+    vector = vdev->config_vector ;
+    if (vector >= msix_nr_vectors_allocated(dev)) {
+        return;
+    }
+    kvm_virtio_pci_irqfd_release(proxy, n, vector);
+    kvm_virtio_pci_vq_vector_release(proxy, vector);
+}
+static int virtio_pci_set_config_notifier(DeviceState *d,  bool assign)
+{
+    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    EventNotifier *notifier = virtio_get_config_notifier(vdev);
+    int r = 0;
+    if (assign) {
+        r = event_notifier_init(notifier, 0);
+        virtio_set_config_notifier_fd_handler(vdev, true, true);
+        kvm_virtio_pci_vector_config_use(proxy);
+    } else {
+        virtio_set_config_notifier_fd_handler(vdev, false, true);
+        kvm_virtio_pci_vector_config_release(proxy);
+        event_notifier_cleanup(notifier);
+    }
+    return r;
+}
 
 static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
 {
@@ -858,6 +907,14 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
     EventNotifier *n;
     int ret, index, unmasked = 0;
 
+   if (vdev->use_config_notifier == true) {
+        n = virtio_get_config_notifier(vdev);
+        ret = virtio_pci_vq_vector_unmask(proxy, 0, vector, msg,
+                    VIRTIO_CONFIG_VECTOR, n);
+        if (ret < 0) {
+            goto config_undo;
+       }
+    }
     while (vq) {
         index = virtio_get_queue_index(vq);
         if (!virtio_queue_get_num(vdev, index)) {
@@ -889,6 +946,10 @@ undo:
         }
         vq = virtio_vector_next_queue(vq);
     }
+ config_undo:
+            n = virtio_get_config_notifier(vdev);
+            virtio_pci_vq_vector_mask(proxy, 0, vector,
+                VIRTIO_CONFIG_VECTOR, n);
     return ret;
 }
 
@@ -900,6 +961,10 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
     EventNotifier *n;
     int index;
 
+   if (vdev->use_config_notifier == true) {
+        n = virtio_get_config_notifier(vdev);
+        virtio_pci_vq_vector_mask(proxy, 0, vector, VIRTIO_CONFIG_VECTOR, n);
+   }
     while (vq) {
         index = virtio_get_queue_index(vq);
          n = virtio_queue_get_guest_notifier(vq);
@@ -945,6 +1010,21 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
             msix_set_pending(dev, vector);
         }
     }
+   if (vdev->use_config_notifier == true) {
+        vector = vdev->config_vector;
+        notifier = virtio_get_config_notifier(vdev);
+        if (vector < vector_start || vector >= vector_end ||
+            !msix_is_masked(dev, vector)) {
+            return;
+        }
+        if (k->guest_notifier_pending) {
+            if (k->guest_notifier_pending(vdev, 0,  VIRTIO_CONFIG_VECTOR)) {
+                msix_set_pending(dev, vector);
+            }
+        } else if (event_notifier_test_and_clear(notifier)) {
+            msix_set_pending(dev, vector);
+        }
+    }
 }
 
 static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
@@ -1032,6 +1112,10 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
                 goto assign_error;
             }
         }
+            r = virtio_pci_set_config_notifier(d, assign);
+            if (r < 0) {
+                goto config_error;
+         }
         r = msix_set_vector_notifiers(&proxy->pci_dev,
                                       virtio_pci_vector_unmask,
                                       virtio_pci_vector_mask,
@@ -1048,7 +1132,8 @@ notifiers_error:
         assert(assign);
         kvm_virtio_pci_vector_release(proxy, nvqs);
     }
-
+ config_error:
+        kvm_virtio_pci_vector_config_release(proxy);
 assign_error:
     /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
     assert(assign);
-- 
2.21.3



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 1/6] virtio: introduce new type in interrupt process
  2021-04-08  9:38 ` [PATCH v5 1/6] virtio: introduce new type in interrupt process Cindy Lu
@ 2021-04-09  6:57   ` Jason Wang
  2021-04-12  8:09     ` Cindy Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Wang @ 2021-04-09  6:57 UTC (permalink / raw)
  To: Cindy Lu, mst, qemu-devel


在 2021/4/8 下午5:38, Cindy Lu 写道:
> To support config interrupt we need to add
> a new type of interrupt process. So we introduce
> the vector type
> enum virtio_vector_type {
> 聽 聽 聽 聽 VIRTIO_VQ_VECTOR,
> 聽 聽 聽 聽 VIRTIO_CONFIG_VECTOR,
> 聽 聽 聽 聽 VIRTIO_VECTOR_UNKNOWN,
> 聽 聽 };
> 聽 聽


I see some tranditiaonl chinese characters here.

Plaese correctly congirue your locale.

So consider we use int for queue_index, can we simply use -1 as a hint 
for the config interrupt then there's no need for this extra enum?


> Now the bus which support configure interrupt is
> virtio-mmio and vritio-pci. For other drivers, the function will
> only check if the interrupt type is the VIRTIO_CONFIG_VQ. If not
> the function will fail.
>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/display/vhost-user-gpu.c    | 14 +++++---
>   hw/net/virtio-net.c            | 15 +++++---
>   hw/s390x/virtio-ccw.c          |  6 ++--
>   hw/virtio/vhost-user-fs.c      | 12 ++++---
>   hw/virtio/vhost-vsock-common.c | 12 ++++---
>   hw/virtio/virtio-crypto.c      | 13 ++++---
>   hw/virtio/virtio-mmio.c        |  2 +-
>   hw/virtio/virtio-pci.c         | 66 ++++++++++++++++++++--------------
>   include/hw/virtio/virtio.h     |  9 +++--
>   9 files changed, 95 insertions(+), 54 deletions(-)
>
> diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
> index 51f1747c4a..959ad115b6 100644
> --- a/hw/display/vhost-user-gpu.c
> +++ b/hw/display/vhost-user-gpu.c
> @@ -487,18 +487,24 @@ vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val)
>   }
>   
>   static bool
> -vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx,
> +                                            int type)
>   {
>       VhostUserGPU *g = VHOST_USER_GPU(vdev);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return false;
> +    }
>       return vhost_virtqueue_pending(&g->vhost->dev, idx);
>   }
>   
>   static void
> -vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
> +vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask,
> +                                        int type)
>   {
>       VhostUserGPU *g = VHOST_USER_GPU(vdev);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return;
> +    }
>       vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
>   }
>   
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 9179013ac4..00d95e6615 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -3055,22 +3055,27 @@ static NetClientInfo net_virtio_info = {
>       .announce = virtio_net_announce,
>   };
>   
> -static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx,
> +                                int type)
>   {
>       VirtIONet *n = VIRTIO_NET(vdev);
>       NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
>       assert(n->vhost_started);
> -    return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> +    if (type == VIRTIO_VQ_VECTOR) {
> +        return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> +    }
> +    return false;
>   }
>   
>   static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> -                                           bool mask)
> +                                           bool mask, int type)
>   {
>       VirtIONet *n = VIRTIO_NET(vdev);
>       NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
>       assert(n->vhost_started);
> -    vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
> -                             vdev, idx, mask);
> +    if (type == VIRTIO_VQ_VECTOR) {
> +        vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
> +     }
>   }
>   
>   static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index 4582e94ae7..234f749548 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -1003,16 +1003,16 @@ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
>            * need to manually trigger any guest masking callbacks here.
>            */
>           if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> -            k->guest_notifier_mask(vdev, n, false);
> +            k->guest_notifier_mask(vdev, n, false, VIRTIO_VQ_VECTOR);
>           }
>           /* get lost events and re-inject */
>           if (k->guest_notifier_pending &&
> -            k->guest_notifier_pending(vdev, n)) {
> +            k->guest_notifier_pending(vdev, n, VIRTIO_VQ_VECTOR)) {
>               event_notifier_set(notifier);
>           }
>       } else {
>           if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> -            k->guest_notifier_mask(vdev, n, true);
> +            k->guest_notifier_mask(vdev, n, true, VIRTIO_VQ_VECTOR);
>           }
>           if (with_irqfd) {
>               virtio_ccw_remove_irqfd(dev, n);
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> index 1bc5d03a00..22358767f1 100644
> --- a/hw/virtio/vhost-user-fs.c
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -143,17 +143,21 @@ static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
>   }
>   
>   static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> -                                            bool mask)
> +                                            bool mask, int type)
>   {
>       VHostUserFS *fs = VHOST_USER_FS(vdev);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return;
> +    }
>       vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
>   }
>   
> -static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx, int type)
>   {
>       VHostUserFS *fs = VHOST_USER_FS(vdev);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return false;
> +     }
>       return vhost_virtqueue_pending(&fs->vhost_dev, idx);
>   }
>   
> diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
> index 5b2ebf3496..92c133c54c 100644
> --- a/hw/virtio/vhost-vsock-common.c
> +++ b/hw/virtio/vhost-vsock-common.c
> @@ -97,18 +97,22 @@ static void vhost_vsock_common_handle_output(VirtIODevice *vdev, VirtQueue *vq)
>   }
>   
>   static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
> -                                            bool mask)
> +                                            bool mask, int type)
>   {
>       VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return;
> +    }
>       vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask);
>   }
>   
>   static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
> -                                               int idx)
> +                                               int idx, int type)
>   {
>       VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return false;
> +    }
>       return vhost_virtqueue_pending(&vvc->vhost_dev, idx);
>   }
>   
> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> index 54f9bbb789..ab7958465c 100644
> --- a/hw/virtio/virtio-crypto.c
> +++ b/hw/virtio/virtio-crypto.c
> @@ -941,23 +941,28 @@ static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status)
>   }
>   
>   static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
> -                                           bool mask)
> +                                           bool mask, int type)
>   {
>       VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
>       int queue = virtio_crypto_vq2q(idx);
>   
>       assert(vcrypto->vhost_started);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return;
> +    }
>       cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
>   }
>   
> -static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
> +static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx,
> +                                           int type)
>   {
>       VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
>       int queue = virtio_crypto_vq2q(idx);
>   
>       assert(vcrypto->vhost_started);
> -
> +    if (type != VIRTIO_VQ_VECTOR) {
> +        return false;
> +    }
>       return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
>   }
>   
> diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> index e1b5c3b81e..1aa1aaeca4 100644
> --- a/hw/virtio/virtio-mmio.c
> +++ b/hw/virtio/virtio-mmio.c
> @@ -627,7 +627,7 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
>       }
>   
>       if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> -        vdc->guest_notifier_mask(vdev, n, !assign);
> +        vdc->guest_notifier_mask(vdev, n, !assign, VIRTIO_VQ_VECTOR);
>       }
>   
>       return 0;
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 36524a5728..481f6e7505 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -691,23 +691,17 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
>   }
>   
>   static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
> -                                 unsigned int queue_no,
> +                                 EventNotifier *n,
>                                    unsigned int vector)


All the changes of switching to use EventNotifier should be done as a 
separate patch.

Thanks


>   {
>       VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
> -    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> -    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> -    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
>       return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
>   }
>   
>   static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
> -                                      unsigned int queue_no,
> +                                      EventNotifier *n ,
>                                         unsigned int vector)
>   {
> -    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> -    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> -    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
>       VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
>       int ret;
>   
> @@ -722,7 +716,8 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
>       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
>       unsigned int vector;
>       int ret, queue_no;
> -
> +    VirtQueue *vq;
> +    EventNotifier *n;
>       for (queue_no = 0; queue_no < nvqs; queue_no++) {
>           if (!virtio_queue_get_num(vdev, queue_no)) {
>               break;
> @@ -739,7 +734,9 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
>            * Otherwise, delay until unmasked in the frontend.
>            */
>           if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> -            ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
> +            vq = virtio_get_queue(vdev, queue_no);
> +            n = virtio_queue_get_guest_notifier(vq);
> +            ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
>               if (ret < 0) {
>                   kvm_virtio_pci_vq_vector_release(proxy, vector);
>                   goto undo;
> @@ -755,7 +752,9 @@ undo:
>               continue;
>           }
>           if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> -            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> +            vq = virtio_get_queue(vdev, queue_no);
> +            n = virtio_queue_get_guest_notifier(vq);
> +            kvm_virtio_pci_irqfd_release(proxy, n, vector);
>           }
>           kvm_virtio_pci_vq_vector_release(proxy, vector);
>       }
> @@ -769,7 +768,8 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
>       unsigned int vector;
>       int queue_no;
>       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> -
> +    VirtQueue *vq;
> +    EventNotifier *n;
>       for (queue_no = 0; queue_no < nvqs; queue_no++) {
>           if (!virtio_queue_get_num(vdev, queue_no)) {
>               break;
> @@ -782,7 +782,9 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
>            * Otherwise, it was cleaned when masked in the frontend.
>            */
>           if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> -            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> +            vq = virtio_get_queue(vdev, queue_no);
> +            n = virtio_queue_get_guest_notifier(vq);
> +            kvm_virtio_pci_irqfd_release(proxy, n, vector);
>           }
>           kvm_virtio_pci_vq_vector_release(proxy, vector);
>       }
> @@ -791,12 +793,12 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
>   static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
>                                          unsigned int queue_no,
>                                          unsigned int vector,
> -                                       MSIMessage msg)
> +                                       MSIMessage msg,
> +                                       int type,
> +                                        EventNotifier *n)
>   {
>       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> -    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> -    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
>       VirtIOIRQFD *irqfd;
>       int ret = 0;
>   
> @@ -816,21 +818,23 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
>        * Otherwise, set it up now.
>        */
>       if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> -        k->guest_notifier_mask(vdev, queue_no, false);
> +        k->guest_notifier_mask(vdev, queue_no, false, type);
>           /* Test after unmasking to avoid losing events. */
>           if (k->guest_notifier_pending &&
> -            k->guest_notifier_pending(vdev, queue_no)) {
> +            k->guest_notifier_pending(vdev, queue_no, type)) {
>               event_notifier_set(n);
>           }
>       } else {
> -        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
> +        ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
>       }
>       return ret;
>   }
>   
>   static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
>                                                unsigned int queue_no,
> -                                             unsigned int vector)
> +                                             unsigned int vector,
> +                                             int type,
> +                                             EventNotifier *n)
>   {
>       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> @@ -839,9 +843,9 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
>        * Otherwise, clean it up now.
>        */
>       if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> -        k->guest_notifier_mask(vdev, queue_no, true);
> +        k->guest_notifier_mask(vdev, queue_no, true, type);
>       } else {
> -        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> +        kvm_virtio_pci_irqfd_release(proxy, n, vector);
>       }
>   }
>   
> @@ -851,6 +855,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
>       VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
>       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>       VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
> +    EventNotifier *n;
>       int ret, index, unmasked = 0;
>   
>       while (vq) {
> @@ -859,7 +864,9 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
>               break;
>           }
>           if (index < proxy->nvqs_with_notifiers) {
> -            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
> +            n = virtio_queue_get_guest_notifier(vq);
> +            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg,
> +                        VIRTIO_VQ_VECTOR, n);
>               if (ret < 0) {
>                   goto undo;
>               }
> @@ -875,7 +882,9 @@ undo:
>       while (vq && unmasked >= 0) {
>           index = virtio_get_queue_index(vq);
>           if (index < proxy->nvqs_with_notifiers) {
> -            virtio_pci_vq_vector_mask(proxy, index, vector);
> +            n = virtio_queue_get_guest_notifier(vq);
> +            virtio_pci_vq_vector_mask(proxy, index, vector,
> +                 VIRTIO_VQ_VECTOR, n);
>               --unmasked;
>           }
>           vq = virtio_vector_next_queue(vq);
> @@ -888,15 +897,18 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
>       VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
>       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>       VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
> +    EventNotifier *n;
>       int index;
>   
>       while (vq) {
>           index = virtio_get_queue_index(vq);
> +         n = virtio_queue_get_guest_notifier(vq);
>           if (!virtio_queue_get_num(vdev, index)) {
>               break;
>           }
>           if (index < proxy->nvqs_with_notifiers) {
> -            virtio_pci_vq_vector_mask(proxy, index, vector);
> +            virtio_pci_vq_vector_mask(proxy, index, vector,
> +                VIRTIO_VQ_VECTOR, n);
>           }
>           vq = virtio_vector_next_queue(vq);
>       }
> @@ -926,7 +938,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
>           vq = virtio_get_queue(vdev, queue_no);
>           notifier = virtio_queue_get_guest_notifier(vq);
>           if (k->guest_notifier_pending) {
> -            if (k->guest_notifier_pending(vdev, queue_no)) {
> +            if (k->guest_notifier_pending(vdev, queue_no, VIRTIO_VQ_VECTOR)) {
>                   msix_set_pending(dev, vector);
>               }
>           } else if (event_notifier_test_and_clear(notifier)) {
> @@ -958,7 +970,7 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
>       if (!msix_enabled(&proxy->pci_dev) &&
>           vdev->use_guest_notifier_mask &&
>           vdc->guest_notifier_mask) {
> -        vdc->guest_notifier_mask(vdev, n, !assign);
> +        vdc->guest_notifier_mask(vdev, n, !assign, VIRTIO_VQ_VECTOR);
>       }
>   
>       return 0;
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index b7ece7a6a8..5a1940fe70 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -67,6 +67,11 @@ typedef struct VirtQueueElement
>   
>   #define VIRTIO_NO_VECTOR 0xffff
>   
> +enum virtio_vector_type {
> +    VIRTIO_VQ_VECTOR,
> +    VIRTIO_CONFIG_VECTOR,
> +    VIRTIO_VECTOR_UNKNOWN,
> +};
>   #define TYPE_VIRTIO_DEVICE "virtio-device"
>   OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
>   
> @@ -138,13 +143,13 @@ struct VirtioDeviceClass {
>        * If backend does not support masking,
>        * must check in frontend instead.
>        */
> -    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n);
> +    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n, int type);
>       /* Mask/unmask events from this vq. Any events reported
>        * while masked will become pending.
>        * If backend does not support masking,
>        * must mask in frontend instead.
>        */
> -    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
> +    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask, int type);
>       int (*start_ioeventfd)(VirtIODevice *vdev);
>       void (*stop_ioeventfd)(VirtIODevice *vdev);
>       /* Saving and loading of a device; trying to deprecate save/load



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 2/6] vhost: add new call back function for config interrupt
  2021-04-08  9:38 ` [PATCH v5 2/6] vhost: add new call back function for config interrupt Cindy Lu
@ 2021-04-09  7:12   ` Jason Wang
  2021-04-12  8:06     ` Cindy Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Wang @ 2021-04-09  7:12 UTC (permalink / raw)
  To: Cindy Lu, mst, qemu-devel


在 2021/4/8 下午5:38, Cindy Lu 写道:
> to support configure interrupt, we need to
> Add new call back function for config interrupt.


There're brunch of capital issues.


> now聽this call back function only used in vhost-vdpa driver


And looks like anthoer traditional chinese character.


>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/virtio/trace-events            | 2 ++
>   hw/virtio/vhost-vdpa.c            | 7 +++++++
>   include/hw/virtio/vhost-backend.h | 3 +++
>   3 files changed, 12 insertions(+)
>
> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> index 2060a144a2..6710835b46 100644
> --- a/hw/virtio/trace-events
> +++ b/hw/virtio/trace-events
> @@ -52,6 +52,8 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
>   vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
>   vhost_vdpa_set_owner(void *dev) "dev: %p"
>   vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
> +vhost_vdpa_set_config_call(void *dev, int *fd)"dev: %p fd: %p"
> +
>   
>   # virtio.c
>   virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> index 01d2101d09..9ba2a2bed4 100644
> --- a/hw/virtio/vhost-vdpa.c
> +++ b/hw/virtio/vhost-vdpa.c
> @@ -545,6 +545,12 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
>       trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
>       return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
>   }
> +static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
> +                                       int *fd)
> +{
> +    trace_vhost_vdpa_set_config_call(dev, fd);
> +    return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, fd);
> +}
>   
>   static int vhost_vdpa_get_features(struct vhost_dev *dev,
>                                        uint64_t *features)
> @@ -611,4 +617,5 @@ const VhostOps vdpa_ops = {
>           .vhost_get_device_id = vhost_vdpa_get_device_id,
>           .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
>           .vhost_force_iommu = vhost_vdpa_force_iommu,
> +        .vhost_set_config_call = vhost_vdpa_set_config_call,
>   };
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index 8a6f8e2a7a..adaf6982d2 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -125,6 +125,8 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
>   
>   typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
>   
> +typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
> +                                       int *fd);
>   typedef struct VhostOps {
>       VhostBackendType backend_type;
>       vhost_backend_init vhost_backend_init;
> @@ -170,6 +172,7 @@ typedef struct VhostOps {
>       vhost_vq_get_addr_op  vhost_vq_get_addr;
>       vhost_get_device_id_op vhost_get_device_id;
>       vhost_force_iommu_op vhost_force_iommu;
> +    vhost_set_config_call_op vhost_set_config_call;
>   } VhostOps;


Let's split the vhost-vdpa implementation into another patch.

Thanks


>   
>   extern const VhostOps user_ops;



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 3/6] virtio:add support in configure interrupt
  2021-04-08  9:38 ` [PATCH v5 3/6] virtio:add support in configure interrupt Cindy Lu
@ 2021-04-09  7:21   ` Jason Wang
  2021-04-12  8:05     ` Cindy Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Wang @ 2021-04-09  7:21 UTC (permalink / raw)
  To: Cindy Lu, mst, qemu-devel


在 2021/4/8 下午5:38, Cindy Lu 写道:
> Add configure notifier support in virtio and related driver
> When peer is vhost vdpa, setup the configure interrupt function
> vhost_net_start and release the resource when vhost_net_stop


Actually, this is the vhost support for config interrupt.


>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/net/vhost_net.c         |  9 +++++++++
>   hw/net/virtio-net.c        |  6 ++++++
>   hw/virtio/vhost.c          | 38 +++++++++++++++++++++++++++++++++++++-
>   hw/virtio/virtio.c         | 25 +++++++++++++++++++++++++
>   include/hw/virtio/vhost.h  |  3 +++
>   include/hw/virtio/virtio.h |  5 +++++
>   include/net/vhost_net.h    |  3 +++
>   7 files changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 24d555e764..12e30dc25e 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -426,6 +426,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
>       vhost_virtqueue_mask(&net->dev, dev, idx, mask);
>   }
>   
> +bool vhost_net_config_pending(VHostNetState *net, int idx)
> +{
> +    return vhost_config_pending(&net->dev, idx);
> +}
> +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev,
> +                              bool mask)
> +{
> +    vhost_config_mask(&net->dev, dev,  mask);
> +}
>   VHostNetState *get_vhost_net(NetClientState *nc)
>   {
>       VHostNetState *vhost_net = 0;
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 00d95e6615..e30a7d9835 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -3064,6 +3064,9 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx,
>       if (type == VIRTIO_VQ_VECTOR) {
>           return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
>       }
> +    if (type == VIRTIO_CONFIG_VECTOR) {
> +        return vhost_net_config_pending(get_vhost_net(nc->peer), idx);
> +    }
>       return false;
>   }
>   
> @@ -3076,6 +3079,9 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
>       if (type == VIRTIO_VQ_VECTOR) {
>           vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
>        }
> +    if (type == VIRTIO_CONFIG_VECTOR) {
> +        vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask);
> +     }
>   }
>   
>   static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 614ccc2bcb..b5e915d5cf 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -1313,6 +1313,10 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>               goto fail;
>           }
>       }
> +    r = event_notifier_init(&hdev->masked_config_notifier, 0);
> +    if (r < 0) {
> +        return r;
> +    }
>   
>       if (busyloop_timeout) {
>           for (i = 0; i < hdev->nvqs; ++i) {
> @@ -1405,6 +1409,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
>       for (i = 0; i < hdev->nvqs; ++i) {
>           vhost_virtqueue_cleanup(hdev->vqs + i);
>       }
> +    event_notifier_cleanup(&hdev->masked_config_notifier);
>       if (hdev->mem) {
>           /* those are only safe after successful init */
>           memory_listener_unregister(&hdev->memory_listener);
> @@ -1498,6 +1503,10 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n)
>       return event_notifier_test_and_clear(&vq->masked_notifier);
>   }
>   
> +bool vhost_config_pending(struct vhost_dev *hdev, int n)
> +{
> +    return event_notifier_test_and_clear(&hdev->masked_config_notifier);
> +}
>   /* Mask/unmask events from this vq. */
>   void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
>                            bool mask)
> @@ -1522,6 +1531,28 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
>           VHOST_OPS_DEBUG("vhost_set_vring_call failed");
>       }
>   }
> +void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev,
> +                         bool mask)
> +{
> +   int fd;
> +   int r;
> +   EventNotifier *masked_config_notifier = &hdev->masked_config_notifier;
> +   EventNotifier *config_notifier = &vdev->config_notifier;
> +   if (vdev->use_config_notifier != true) {
> +        return;
> +    }
> +    assert(hdev->vhost_ops);
> +    if (mask) {
> +        assert(vdev->use_guest_notifier_mask);
> +        fd = event_notifier_get_fd(masked_config_notifier);
> +    } else {
> +        fd = event_notifier_get_fd(config_notifier);
> +    }
> +   r = hdev->vhost_ops->vhost_set_config_call(hdev, &fd);
> +   if (r < 0) {
> +        error_report("vhost_set_config_call failed");
> +    }
> +}
>   
>   uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
>                               uint64_t features)
> @@ -1732,7 +1763,12 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>               goto fail_vq;
>           }
>       }
> -
> +    if (vdev->use_config_notifier == true) {
> +        event_notifier_test_and_clear(&hdev->masked_config_notifier);
> +        if (!vdev->use_guest_notifier_mask) {
> +            vhost_config_mask(hdev, vdev,  false);
> +        }
> +    }
>       if (hdev->log_enabled) {
>           uint64_t log_base;
>   
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index ceb58fda6c..774ac3893b 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -3278,6 +3278,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
>               virtio_vmstate_change, vdev);
>       vdev->device_endian = virtio_default_endian();
>       vdev->use_guest_notifier_mask = true;
> +    vdev->use_config_notifier = false;


It's still unclear to me why we need use_config_notifier. What happens 
if we don't have that?

Thanks


>   }
>   
>   /*
> @@ -3502,6 +3503,16 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
>       }
>   }
>   
> +static void virtio_config_read(EventNotifier *n)
> +{
> +    VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
> +    if (vdev->use_config_notifier == false) {
> +        return;
> +    }
> +    if (event_notifier_test_and_clear(n)) {
> +        virtio_notify_config(vdev);
> +    }
> +}
>   void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
>                                                   bool with_irqfd)
>   {
> @@ -3517,6 +3528,16 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
>           virtio_queue_guest_notifier_read(&vq->guest_notifier);
>       }
>   }
> +void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
> +                                                bool with_irqfd)
> +{
> +    if (assign && !with_irqfd) {
> +        event_notifier_set_handler(&vdev->config_notifier,
> +                                   virtio_config_read);
> +    } else {
> +       event_notifier_set_handler(&vdev->config_notifier, NULL);
> +    }
> +}
>   
>   EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
>   {
> @@ -3591,6 +3612,10 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
>       return &vq->host_notifier;
>   }
>   
> +EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev)
> +{
> +    return &vdev->config_notifier;
> +}
>   void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
>   {
>       vq->host_notifier_enabled = enabled;
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 4a8bc75415..22efa7008e 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -91,6 +91,7 @@ struct vhost_dev {
>       QLIST_HEAD(, vhost_iommu) iommu_list;
>       IOMMUNotifier n;
>       const VhostDevConfigOps *config_ops;
> +    EventNotifier masked_config_notifier;
>   };
>   
>   struct vhost_net {
> @@ -108,6 +109,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
>   void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
>   int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
>   void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
> +bool vhost_config_pending(struct vhost_dev *hdev, int n);
> +void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev,  bool mask);
>   
>   /* Test and clear masked event pending status.
>    * Should be called after unmask to avoid losing events.
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 5a1940fe70..fd17dbb097 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -113,6 +113,8 @@ struct VirtIODevice
>       bool use_guest_notifier_mask;
>       AddressSpace *dma_as;
>       QLIST_HEAD(, VirtQueue) *vector_queues;
> +    EventNotifier config_notifier;
> +    bool use_config_notifier;
>   };
>   
>   struct VirtioDeviceClass {
> @@ -315,11 +317,14 @@ uint16_t virtio_get_queue_index(VirtQueue *vq);
>   EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
>   void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
>                                                   bool with_irqfd);
> +void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
> +                                                bool with_irqfd);
>   int virtio_device_start_ioeventfd(VirtIODevice *vdev);
>   int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
>   void virtio_device_release_ioeventfd(VirtIODevice *vdev);
>   bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
>   EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
> +EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev);
>   void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
>   void virtio_queue_host_notifier_read(EventNotifier *n);
>   void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
> diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> index 172b0051d8..0d38c97c94 100644
> --- a/include/net/vhost_net.h
> +++ b/include/net/vhost_net.h
> @@ -36,6 +36,9 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
>   bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
>   void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
>                                 int idx, bool mask);
> +bool vhost_net_config_pending(VHostNetState *net, int n);
> +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev,
> +                              bool mask);
>   int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
>   VHostNetState *get_vhost_net(NetClientState *nc);
>   



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 4/6] vhost-vdpa: add support for configure interrupt
  2021-04-08  9:38 ` [PATCH v5 4/6] vhost-vdpa: add support for " Cindy Lu
@ 2021-04-09  7:24   ` Jason Wang
  2021-04-12  8:18     ` Cindy Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Wang @ 2021-04-09  7:24 UTC (permalink / raw)
  To: Cindy Lu, mst, qemu-devel


在 2021/4/8 下午5:38, Cindy Lu 写道:
> Add support for configure interrupt. Set the notifier's fd to
> the kernel driver when vdpa start. also set -1 while vdpa stop.
> then the kernel will release the related resource
>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/virtio/vhost-vdpa.c | 26 +++++++++++++++++++++++++-
>   1 file changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> index 9ba2a2bed4..7825366f64 100644
> --- a/hw/virtio/vhost-vdpa.c
> +++ b/hw/virtio/vhost-vdpa.c
> @@ -467,11 +467,33 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
>       }
>       return ret;
>    }
> -


Let's keep this blank line.


> +static void vhost_vdpa_config_notify_start(struct vhost_dev *dev,
> +                                struct VirtIODevice *vdev, bool start)
> +{
> +    int fd = 0;
> +    int r = 0;
> +    if (!(dev->features & (0x1ULL << VIRTIO_NET_F_STATUS))) {
> +        return;
> +    }
> +    if (start) {
> +        fd = event_notifier_get_fd(&vdev->config_notifier);
> +        r = dev->vhost_ops->vhost_set_config_call(dev, &fd);


So you introduce a general vhost ops but it's call by devic specific 
code (vhost-vdpa).

Any reason that we don't do that in vhost_dev_start/vhost_dev_stop?

Thanks


> +        if (!r) {
> +            vdev->use_config_notifier = true;
> +            event_notifier_set(&vdev->config_notifier);
> +        }
> +    } else {
> +        fd = -1;
> +        vdev->use_config_notifier = false;
> +        r = dev->vhost_ops->vhost_set_config_call(dev, &fd);
> +    }
> +    return;
> +}
>   static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
>   {
>       struct vhost_vdpa *v = dev->opaque;
>       trace_vhost_vdpa_dev_start(dev, started);
> +    VirtIODevice *vdev = dev->vdev;
>       if (started) {
>           uint8_t status = 0;
>           memory_listener_register(&v->listener, &address_space_memory);
> @@ -479,8 +501,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
>           vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
>           vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
>   
> +        vhost_vdpa_config_notify_start(dev, vdev, true);
>           return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
>       } else {
> +        vhost_vdpa_config_notify_start(dev, vdev, false);
>           vhost_vdpa_reset_device(dev);
>           vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
>                                      VIRTIO_CONFIG_S_DRIVER);



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 5/6] virtio-mmio: add support for configure interrupt
  2021-04-08  9:38 ` [PATCH v5 5/6] virtio-mmio: " Cindy Lu
@ 2021-04-09  7:27   ` Jason Wang
  0 siblings, 0 replies; 18+ messages in thread
From: Jason Wang @ 2021-04-09  7:27 UTC (permalink / raw)
  To: Cindy Lu, mst, qemu-devel


在 2021/4/8 下午5:38, Cindy Lu 写道:
> add configure interrupt support for virtio-mmio bus. This
> interrupt will working while backend is vhost-vdpa


So this is actually the guest notifier of config interrupt for virtio-mmio.

Thanks


>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/virtio/virtio-mmio.c | 26 ++++++++++++++++++++++++++
>   1 file changed, 26 insertions(+)
>
> diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> index 1aa1aaeca4..64b347421b 100644
> --- a/hw/virtio/virtio-mmio.c
> +++ b/hw/virtio/virtio-mmio.c
> @@ -632,7 +632,26 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
>   
>       return 0;
>   }
> +static int virtio_mmio_set_config_notifier(DeviceState *d,  bool assign)
> +{
> +    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
> +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> +        VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
>   
> +    EventNotifier *notifier = virtio_get_config_notifier(vdev);
> +    int r = 0;
> +    if (assign) {
> +        r = event_notifier_init(notifier, 0);
> +        virtio_set_config_notifier_fd_handler(vdev, true, false);
> +    } else {
> +        virtio_set_config_notifier_fd_handler(vdev, false, false);
> +        event_notifier_cleanup(notifier);
> +    }
> +        if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> +            vdc->guest_notifier_mask(vdev, 0, !assign, VIRTIO_CONFIG_VECTOR);
> +    }
> +    return r;
> +}
>   static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
>                                              bool assign)
>   {
> @@ -654,8 +673,15 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
>               goto assign_error;
>           }
>       }
> +   r = virtio_mmio_set_config_notifier(d, assign);
> +   if (r < 0) {
> +            goto config_assign_error;
> +   }
>   
>       return 0;
> +config_assign_error:
> +    assert(assign);
> +    r = virtio_mmio_set_config_notifier(d, false);
>   
>   assign_error:
>       /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 6/6] virtio-pci: add support for configure interrupt
  2021-04-08  9:38 ` [PATCH v5 6/6] virtio-pci: " Cindy Lu
@ 2021-04-09  7:39   ` Jason Wang
  2021-04-12  8:27     ` Cindy Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Wang @ 2021-04-09  7:39 UTC (permalink / raw)
  To: Cindy Lu, mst, qemu-devel


在 2021/4/8 下午5:38, Cindy Lu 写道:
> Add support for configure interrupt, use kvm_irqfd_assign and set the
> gsi to kernel. When the configure notifier was eventfd_signal by host
> kernel, this will finally inject an msix interrupt to guest
>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>   hw/virtio/virtio-pci.c | 91 ++++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 88 insertions(+), 3 deletions(-)
>
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 481f6e7505..7b02f42c06 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -664,7 +664,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
>   }
>   
>   static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
> -                                        unsigned int queue_no,
>                                           unsigned int vector)
>   {
>       VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
> @@ -726,7 +725,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
>           if (vector >= msix_nr_vectors_allocated(dev)) {
>               continue;
>           }
> -        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
> +        ret = kvm_virtio_pci_vq_vector_use(proxy,  vector);
>           if (ret < 0) {
>               goto undo;
>           }
> @@ -760,6 +759,56 @@ undo:
>       }
>       return ret;
>   }
> +static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
> +{
> +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> +    unsigned int vector;
> +    int ret;
> +    EventNotifier *n = virtio_get_config_notifier(vdev);
> +    vector = vdev->config_vector ;
> +    ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
> +    if (ret < 0) {
> +        goto undo;
> +    }
> +    ret = kvm_virtio_pci_irqfd_use(proxy,  n, vector);


So the kvm_virtio_pci_vector_use() has the following codes:

         /* If guest supports masking, set up irqfd now.
          * Otherwise, delay until unmasked in the frontend.
          */
         if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
             vq = virtio_get_queue(vdev, queue_no);
             n = virtio_queue_get_guest_notifier(vq);
             ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
             if (ret < 0) {
                 kvm_virtio_pci_vq_vector_release(proxy, vector);
                 goto undo;
             }
         }

Do we need to check the masking support here as well?

Btw, I think we can factor out the core logic (decouple the queue_no) of 
kvm_virtio_pci_vector_user() and let it be reused by config interrupt.


> +    if (ret < 0) {
> +        goto undo;
> +    }
> +    return 0;
> +undo:
> +    kvm_virtio_pci_irqfd_release(proxy, n, vector);
> +    return ret;
> +}
> +static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
> +{
> +    PCIDevice *dev = &proxy->pci_dev;
> +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> +    unsigned int vector;
> +    EventNotifier *n = virtio_get_config_notifier(vdev);
> +    vector = vdev->config_vector ;
> +    if (vector >= msix_nr_vectors_allocated(dev)) {
> +        return;
> +    }
> +    kvm_virtio_pci_irqfd_release(proxy, n, vector);
> +    kvm_virtio_pci_vq_vector_release(proxy, vector);
> +}
> +static int virtio_pci_set_config_notifier(DeviceState *d,  bool assign)
> +{
> +    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
> +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> +    EventNotifier *notifier = virtio_get_config_notifier(vdev);
> +    int r = 0;
> +    if (assign) {
> +        r = event_notifier_init(notifier, 0);
> +        virtio_set_config_notifier_fd_handler(vdev, true, true);
> +        kvm_virtio_pci_vector_config_use(proxy);
> +    } else {
> +        virtio_set_config_notifier_fd_handler(vdev, false, true);


So let's try to unify the codes between this and 
virtio_queue_set_guest_notifier_fd_handler(). Bascailly it's just 
decouple virtqueue *.


> +        kvm_virtio_pci_vector_config_release(proxy);
> +        event_notifier_cleanup(notifier);
> +    }
> +    return r;
> +}
>   
>   static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
>   {
> @@ -858,6 +907,14 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
>       EventNotifier *n;
>       int ret, index, unmasked = 0;
>   
> +   if (vdev->use_config_notifier == true) {
> +        n = virtio_get_config_notifier(vdev);
> +        ret = virtio_pci_vq_vector_unmask(proxy, 0, vector, msg,
> +                    VIRTIO_CONFIG_VECTOR, n);
> +        if (ret < 0) {
> +            goto config_undo;
> +       }
> +    }
>       while (vq) {
>           index = virtio_get_queue_index(vq);
>           if (!virtio_queue_get_num(vdev, index)) {
> @@ -889,6 +946,10 @@ undo:
>           }
>           vq = virtio_vector_next_queue(vq);
>       }
> + config_undo:
> +            n = virtio_get_config_notifier(vdev);
> +            virtio_pci_vq_vector_mask(proxy, 0, vector,
> +                VIRTIO_CONFIG_VECTOR, n);
>       return ret;
>   }
>   
> @@ -900,6 +961,10 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
>       EventNotifier *n;
>       int index;
>   
> +   if (vdev->use_config_notifier == true) {


Is this sufficient to know the vector is used by config interrupt?


> +        n = virtio_get_config_notifier(vdev);
> +        virtio_pci_vq_vector_mask(proxy, 0, vector, VIRTIO_CONFIG_VECTOR, n);
> +   }
>       while (vq) {
>           index = virtio_get_queue_index(vq);
>            n = virtio_queue_get_guest_notifier(vq);
> @@ -945,6 +1010,21 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
>               msix_set_pending(dev, vector);
>           }
>       }
> +   if (vdev->use_config_notifier == true) {
> +        vector = vdev->config_vector;
> +        notifier = virtio_get_config_notifier(vdev);
> +        if (vector < vector_start || vector >= vector_end ||
> +            !msix_is_masked(dev, vector)) {
> +            return;
> +        }
> +        if (k->guest_notifier_pending) {
> +            if (k->guest_notifier_pending(vdev, 0,  VIRTIO_CONFIG_VECTOR)) {
> +                msix_set_pending(dev, vector);
> +            }
> +        } else if (event_notifier_test_and_clear(notifier)) {
> +            msix_set_pending(dev, vector);
> +        }
> +    }


Let's unify the code here with the code that deal with vq vectors in the 
loop above.

Thanks


>   }
>   
>   static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
> @@ -1032,6 +1112,10 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
>                   goto assign_error;
>               }
>           }
> +            r = virtio_pci_set_config_notifier(d, assign);
> +            if (r < 0) {
> +                goto config_error;
> +         }
>           r = msix_set_vector_notifiers(&proxy->pci_dev,
>                                         virtio_pci_vector_unmask,
>                                         virtio_pci_vector_mask,
> @@ -1048,7 +1132,8 @@ notifiers_error:
>           assert(assign);
>           kvm_virtio_pci_vector_release(proxy, nvqs);
>       }
> -
> + config_error:
> +        kvm_virtio_pci_vector_config_release(proxy);
>   assign_error:
>       /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
>       assert(assign);



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 3/6] virtio:add support in configure interrupt
  2021-04-09  7:21   ` Jason Wang
@ 2021-04-12  8:05     ` Cindy Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Cindy Lu @ 2021-04-12  8:05 UTC (permalink / raw)
  To: Jason Wang; +Cc: QEMU Developers, Michael Tsirkin

On Fri, Apr 9, 2021 at 3:21 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/4/8 下午5:38, Cindy Lu 写道:
> > Add configure notifier support in virtio and related driver
> > When peer is vhost vdpa, setup the configure interrupt function
> > vhost_net_start and release the resource when vhost_net_stop
>
>
> Actually, this is the vhost support for config interrupt.
>
>
sure will fix this
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/net/vhost_net.c         |  9 +++++++++
> >   hw/net/virtio-net.c        |  6 ++++++
> >   hw/virtio/vhost.c          | 38 +++++++++++++++++++++++++++++++++++++-
> >   hw/virtio/virtio.c         | 25 +++++++++++++++++++++++++
> >   include/hw/virtio/vhost.h  |  3 +++
> >   include/hw/virtio/virtio.h |  5 +++++
> >   include/net/vhost_net.h    |  3 +++
> >   7 files changed, 88 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 24d555e764..12e30dc25e 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -426,6 +426,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> >       vhost_virtqueue_mask(&net->dev, dev, idx, mask);
> >   }
> >
> > +bool vhost_net_config_pending(VHostNetState *net, int idx)
> > +{
> > +    return vhost_config_pending(&net->dev, idx);
> > +}
> > +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev,
> > +                              bool mask)
> > +{
> > +    vhost_config_mask(&net->dev, dev,  mask);
> > +}
> >   VHostNetState *get_vhost_net(NetClientState *nc)
> >   {
> >       VHostNetState *vhost_net = 0;
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index 00d95e6615..e30a7d9835 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -3064,6 +3064,9 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx,
> >       if (type == VIRTIO_VQ_VECTOR) {
> >           return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> >       }
> > +    if (type == VIRTIO_CONFIG_VECTOR) {
> > +        return vhost_net_config_pending(get_vhost_net(nc->peer), idx);
> > +    }
> >       return false;
> >   }
> >
> > @@ -3076,6 +3079,9 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> >       if (type == VIRTIO_VQ_VECTOR) {
> >           vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
> >        }
> > +    if (type == VIRTIO_CONFIG_VECTOR) {
> > +        vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask);
> > +     }
> >   }
> >
> >   static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
> > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> > index 614ccc2bcb..b5e915d5cf 100644
> > --- a/hw/virtio/vhost.c
> > +++ b/hw/virtio/vhost.c
> > @@ -1313,6 +1313,10 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> >               goto fail;
> >           }
> >       }
> > +    r = event_notifier_init(&hdev->masked_config_notifier, 0);
> > +    if (r < 0) {
> > +        return r;
> > +    }
> >
> >       if (busyloop_timeout) {
> >           for (i = 0; i < hdev->nvqs; ++i) {
> > @@ -1405,6 +1409,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
> >       for (i = 0; i < hdev->nvqs; ++i) {
> >           vhost_virtqueue_cleanup(hdev->vqs + i);
> >       }
> > +    event_notifier_cleanup(&hdev->masked_config_notifier);
> >       if (hdev->mem) {
> >           /* those are only safe after successful init */
> >           memory_listener_unregister(&hdev->memory_listener);
> > @@ -1498,6 +1503,10 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n)
> >       return event_notifier_test_and_clear(&vq->masked_notifier);
> >   }
> >
> > +bool vhost_config_pending(struct vhost_dev *hdev, int n)
> > +{
> > +    return event_notifier_test_and_clear(&hdev->masked_config_notifier);
> > +}
> >   /* Mask/unmask events from this vq. */
> >   void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
> >                            bool mask)
> > @@ -1522,6 +1531,28 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
> >           VHOST_OPS_DEBUG("vhost_set_vring_call failed");
> >       }
> >   }
> > +void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev,
> > +                         bool mask)
> > +{
> > +   int fd;
> > +   int r;
> > +   EventNotifier *masked_config_notifier = &hdev->masked_config_notifier;
> > +   EventNotifier *config_notifier = &vdev->config_notifier;
> > +   if (vdev->use_config_notifier != true) {
> > +        return;
> > +    }
> > +    assert(hdev->vhost_ops);
> > +    if (mask) {
> > +        assert(vdev->use_guest_notifier_mask);
> > +        fd = event_notifier_get_fd(masked_config_notifier);
> > +    } else {
> > +        fd = event_notifier_get_fd(config_notifier);
> > +    }
> > +   r = hdev->vhost_ops->vhost_set_config_call(hdev, &fd);
> > +   if (r < 0) {
> > +        error_report("vhost_set_config_call failed");
> > +    }
> > +}
> >
> >   uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
> >                               uint64_t features)
> > @@ -1732,7 +1763,12 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
> >               goto fail_vq;
> >           }
> >       }
> > -
> > +    if (vdev->use_config_notifier == true) {
> > +        event_notifier_test_and_clear(&hdev->masked_config_notifier);
> > +        if (!vdev->use_guest_notifier_mask) {
> > +            vhost_config_mask(hdev, vdev,  false);
> > +        }
> > +    }
> >       if (hdev->log_enabled) {
> >           uint64_t log_base;
> >
> > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > index ceb58fda6c..774ac3893b 100644
> > --- a/hw/virtio/virtio.c
> > +++ b/hw/virtio/virtio.c
> > @@ -3278,6 +3278,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
> >               virtio_vmstate_change, vdev);
> >       vdev->device_endian = virtio_default_endian();
> >       vdev->use_guest_notifier_mask = true;
> > +    vdev->use_config_notifier = false;
>
>
> It's still unclear to me why we need use_config_notifier. What happens
> if we don't have that?
>
> Thanks
I just want to reduce the impact of code changes. only the driver
support  config interrupt will
run the process of handle configure interrupt,
but it should also work well if the driver does not support config
interrupt  with an interrupt  never trigger.
Sure. I will remove this bit and try again

>
>
> >   }
> >
> >   /*
> > @@ -3502,6 +3503,16 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
> >       }
> >   }
> >
> > +static void virtio_config_read(EventNotifier *n)
> > +{
> > +    VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
> > +    if (vdev->use_config_notifier == false) {
> > +        return;
> > +    }
> > +    if (event_notifier_test_and_clear(n)) {
> > +        virtio_notify_config(vdev);
> > +    }
> > +}
> >   void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
> >                                                   bool with_irqfd)
> >   {
> > @@ -3517,6 +3528,16 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
> >           virtio_queue_guest_notifier_read(&vq->guest_notifier);
> >       }
> >   }
> > +void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
> > +                                                bool with_irqfd)
> > +{
> > +    if (assign && !with_irqfd) {
> > +        event_notifier_set_handler(&vdev->config_notifier,
> > +                                   virtio_config_read);
> > +    } else {
> > +       event_notifier_set_handler(&vdev->config_notifier, NULL);
> > +    }
> > +}
> >
> >   EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
> >   {
> > @@ -3591,6 +3612,10 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
> >       return &vq->host_notifier;
> >   }
> >
> > +EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev)
> > +{
> > +    return &vdev->config_notifier;
> > +}
> >   void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
> >   {
> >       vq->host_notifier_enabled = enabled;
> > diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> > index 4a8bc75415..22efa7008e 100644
> > --- a/include/hw/virtio/vhost.h
> > +++ b/include/hw/virtio/vhost.h
> > @@ -91,6 +91,7 @@ struct vhost_dev {
> >       QLIST_HEAD(, vhost_iommu) iommu_list;
> >       IOMMUNotifier n;
> >       const VhostDevConfigOps *config_ops;
> > +    EventNotifier masked_config_notifier;
> >   };
> >
> >   struct vhost_net {
> > @@ -108,6 +109,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
> >   void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
> >   int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
> >   void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
> > +bool vhost_config_pending(struct vhost_dev *hdev, int n);
> > +void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev,  bool mask);
> >
> >   /* Test and clear masked event pending status.
> >    * Should be called after unmask to avoid losing events.
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index 5a1940fe70..fd17dbb097 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -113,6 +113,8 @@ struct VirtIODevice
> >       bool use_guest_notifier_mask;
> >       AddressSpace *dma_as;
> >       QLIST_HEAD(, VirtQueue) *vector_queues;
> > +    EventNotifier config_notifier;
> > +    bool use_config_notifier;
> >   };
> >
> >   struct VirtioDeviceClass {
> > @@ -315,11 +317,14 @@ uint16_t virtio_get_queue_index(VirtQueue *vq);
> >   EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
> >   void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
> >                                                   bool with_irqfd);
> > +void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
> > +                                                bool with_irqfd);
> >   int virtio_device_start_ioeventfd(VirtIODevice *vdev);
> >   int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
> >   void virtio_device_release_ioeventfd(VirtIODevice *vdev);
> >   bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
> >   EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
> > +EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev);
> >   void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
> >   void virtio_queue_host_notifier_read(EventNotifier *n);
> >   void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
> > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> > index 172b0051d8..0d38c97c94 100644
> > --- a/include/net/vhost_net.h
> > +++ b/include/net/vhost_net.h
> > @@ -36,6 +36,9 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
> >   bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
> >   void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> >                                 int idx, bool mask);
> > +bool vhost_net_config_pending(VHostNetState *net, int n);
> > +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev,
> > +                              bool mask);
> >   int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
> >   VHostNetState *get_vhost_net(NetClientState *nc);
> >
>



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 2/6] vhost: add new call back function for config interrupt
  2021-04-09  7:12   ` Jason Wang
@ 2021-04-12  8:06     ` Cindy Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Cindy Lu @ 2021-04-12  8:06 UTC (permalink / raw)
  To: Jason Wang; +Cc: QEMU Developers, Michael Tsirkin

On Fri, Apr 9, 2021 at 3:12 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/4/8 下午5:38, Cindy Lu 写道:
> > to support configure interrupt, we need to
> > Add new call back function for config interrupt.
>
>
> There're brunch of capital issues.
>
>
> > now聽this call back function only used in vhost-vdpa driver
>
>
> And looks like anthoer traditional chinese character.
>
>
will fix this
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/virtio/trace-events            | 2 ++
> >   hw/virtio/vhost-vdpa.c            | 7 +++++++
> >   include/hw/virtio/vhost-backend.h | 3 +++
> >   3 files changed, 12 insertions(+)
> >
> > diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> > index 2060a144a2..6710835b46 100644
> > --- a/hw/virtio/trace-events
> > +++ b/hw/virtio/trace-events
> > @@ -52,6 +52,8 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
> >   vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
> >   vhost_vdpa_set_owner(void *dev) "dev: %p"
> >   vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
> > +vhost_vdpa_set_config_call(void *dev, int *fd)"dev: %p fd: %p"
> > +
> >
> >   # virtio.c
> >   virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > index 01d2101d09..9ba2a2bed4 100644
> > --- a/hw/virtio/vhost-vdpa.c
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -545,6 +545,12 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
> >       trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
> >       return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
> >   }
> > +static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
> > +                                       int *fd)
> > +{
> > +    trace_vhost_vdpa_set_config_call(dev, fd);
> > +    return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, fd);
> > +}
> >
> >   static int vhost_vdpa_get_features(struct vhost_dev *dev,
> >                                        uint64_t *features)
> > @@ -611,4 +617,5 @@ const VhostOps vdpa_ops = {
> >           .vhost_get_device_id = vhost_vdpa_get_device_id,
> >           .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
> >           .vhost_force_iommu = vhost_vdpa_force_iommu,
> > +        .vhost_set_config_call = vhost_vdpa_set_config_call,
> >   };
> > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> > index 8a6f8e2a7a..adaf6982d2 100644
> > --- a/include/hw/virtio/vhost-backend.h
> > +++ b/include/hw/virtio/vhost-backend.h
> > @@ -125,6 +125,8 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
> >
> >   typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
> >
> > +typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
> > +                                       int *fd);
> >   typedef struct VhostOps {
> >       VhostBackendType backend_type;
> >       vhost_backend_init vhost_backend_init;
> > @@ -170,6 +172,7 @@ typedef struct VhostOps {
> >       vhost_vq_get_addr_op  vhost_vq_get_addr;
> >       vhost_get_device_id_op vhost_get_device_id;
> >       vhost_force_iommu_op vhost_force_iommu;
> > +    vhost_set_config_call_op vhost_set_config_call;
> >   } VhostOps;
>
>
> Let's split the vhost-vdpa implementation into another patch.
>
> Thanks
>
>
sure will fix this
> >
> >   extern const VhostOps user_ops;
>



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 1/6] virtio: introduce new type in interrupt process
  2021-04-09  6:57   ` Jason Wang
@ 2021-04-12  8:09     ` Cindy Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Cindy Lu @ 2021-04-12  8:09 UTC (permalink / raw)
  To: Jason Wang; +Cc: QEMU Developers, Michael Tsirkin

On Fri, Apr 9, 2021 at 2:57 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/4/8 下午5:38, Cindy Lu 写道:
> > To support config interrupt we need to add
> > a new type of interrupt process. So we introduce
> > the vector type
> > enum virtio_vector_type {
> > 聽 聽 聽 聽 VIRTIO_VQ_VECTOR,
> > 聽 聽 聽 聽 VIRTIO_CONFIG_VECTOR,
> > 聽 聽 聽 聽 VIRTIO_VECTOR_UNKNOWN,
> > 聽 聽 };
> > 聽 聽
>
>
> I see some tranditiaonl chinese characters here.
>
> Plaese correctly congirue your locale.
>
sure will fix this
> So consider we use int for queue_index, can we simply use -1 as a hint
> for the config interrupt then there's no need for this extra enum?
>
that's a good idea, I will rewrite this part
>
> > Now the bus which support configure interrupt is
> > virtio-mmio and vritio-pci. For other drivers, the function will
> > only check if the interrupt type is the VIRTIO_CONFIG_VQ. If not
> > the function will fail.
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/display/vhost-user-gpu.c    | 14 +++++---
> >   hw/net/virtio-net.c            | 15 +++++---
> >   hw/s390x/virtio-ccw.c          |  6 ++--
> >   hw/virtio/vhost-user-fs.c      | 12 ++++---
> >   hw/virtio/vhost-vsock-common.c | 12 ++++---
> >   hw/virtio/virtio-crypto.c      | 13 ++++---
> >   hw/virtio/virtio-mmio.c        |  2 +-
> >   hw/virtio/virtio-pci.c         | 66 ++++++++++++++++++++--------------
> >   include/hw/virtio/virtio.h     |  9 +++--
> >   9 files changed, 95 insertions(+), 54 deletions(-)
> >
> > diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
> > index 51f1747c4a..959ad115b6 100644
> > --- a/hw/display/vhost-user-gpu.c
> > +++ b/hw/display/vhost-user-gpu.c
> > @@ -487,18 +487,24 @@ vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val)
> >   }
> >
> >   static bool
> > -vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > +vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx,
> > +                                            int type)
> >   {
> >       VhostUserGPU *g = VHOST_USER_GPU(vdev);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return false;
> > +    }
> >       return vhost_virtqueue_pending(&g->vhost->dev, idx);
> >   }
> >
> >   static void
> > -vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
> > +vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask,
> > +                                        int type)
> >   {
> >       VhostUserGPU *g = VHOST_USER_GPU(vdev);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return;
> > +    }
> >       vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
> >   }
> >
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index 9179013ac4..00d95e6615 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -3055,22 +3055,27 @@ static NetClientInfo net_virtio_info = {
> >       .announce = virtio_net_announce,
> >   };
> >
> > -static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > +static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx,
> > +                                int type)
> >   {
> >       VirtIONet *n = VIRTIO_NET(vdev);
> >       NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
> >       assert(n->vhost_started);
> > -    return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> > +    if (type == VIRTIO_VQ_VECTOR) {
> > +        return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> > +    }
> > +    return false;
> >   }
> >
> >   static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > -                                           bool mask)
> > +                                           bool mask, int type)
> >   {
> >       VirtIONet *n = VIRTIO_NET(vdev);
> >       NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
> >       assert(n->vhost_started);
> > -    vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
> > -                             vdev, idx, mask);
> > +    if (type == VIRTIO_VQ_VECTOR) {
> > +        vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
> > +     }
> >   }
> >
> >   static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
> > diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> > index 4582e94ae7..234f749548 100644
> > --- a/hw/s390x/virtio-ccw.c
> > +++ b/hw/s390x/virtio-ccw.c
> > @@ -1003,16 +1003,16 @@ static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
> >            * need to manually trigger any guest masking callbacks here.
> >            */
> >           if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> > -            k->guest_notifier_mask(vdev, n, false);
> > +            k->guest_notifier_mask(vdev, n, false, VIRTIO_VQ_VECTOR);
> >           }
> >           /* get lost events and re-inject */
> >           if (k->guest_notifier_pending &&
> > -            k->guest_notifier_pending(vdev, n)) {
> > +            k->guest_notifier_pending(vdev, n, VIRTIO_VQ_VECTOR)) {
> >               event_notifier_set(notifier);
> >           }
> >       } else {
> >           if (k->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> > -            k->guest_notifier_mask(vdev, n, true);
> > +            k->guest_notifier_mask(vdev, n, true, VIRTIO_VQ_VECTOR);
> >           }
> >           if (with_irqfd) {
> >               virtio_ccw_remove_irqfd(dev, n);
> > diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> > index 1bc5d03a00..22358767f1 100644
> > --- a/hw/virtio/vhost-user-fs.c
> > +++ b/hw/virtio/vhost-user-fs.c
> > @@ -143,17 +143,21 @@ static void vuf_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> >   }
> >
> >   static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > -                                            bool mask)
> > +                                            bool mask, int type)
> >   {
> >       VHostUserFS *fs = VHOST_USER_FS(vdev);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return;
> > +    }
> >       vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
> >   }
> >
> > -static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > +static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx, int type)
> >   {
> >       VHostUserFS *fs = VHOST_USER_FS(vdev);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return false;
> > +     }
> >       return vhost_virtqueue_pending(&fs->vhost_dev, idx);
> >   }
> >
> > diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
> > index 5b2ebf3496..92c133c54c 100644
> > --- a/hw/virtio/vhost-vsock-common.c
> > +++ b/hw/virtio/vhost-vsock-common.c
> > @@ -97,18 +97,22 @@ static void vhost_vsock_common_handle_output(VirtIODevice *vdev, VirtQueue *vq)
> >   }
> >
> >   static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > -                                            bool mask)
> > +                                            bool mask, int type)
> >   {
> >       VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return;
> > +    }
> >       vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask);
> >   }
> >
> >   static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
> > -                                               int idx)
> > +                                               int idx, int type)
> >   {
> >       VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return false;
> > +    }
> >       return vhost_virtqueue_pending(&vvc->vhost_dev, idx);
> >   }
> >
> > diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> > index 54f9bbb789..ab7958465c 100644
> > --- a/hw/virtio/virtio-crypto.c
> > +++ b/hw/virtio/virtio-crypto.c
> > @@ -941,23 +941,28 @@ static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status)
> >   }
> >
> >   static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
> > -                                           bool mask)
> > +                                           bool mask, int type)
> >   {
> >       VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
> >       int queue = virtio_crypto_vq2q(idx);
> >
> >       assert(vcrypto->vhost_started);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return;
> > +    }
> >       cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
> >   }
> >
> > -static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
> > +static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx,
> > +                                           int type)
> >   {
> >       VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
> >       int queue = virtio_crypto_vq2q(idx);
> >
> >       assert(vcrypto->vhost_started);
> > -
> > +    if (type != VIRTIO_VQ_VECTOR) {
> > +        return false;
> > +    }
> >       return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
> >   }
> >
> > diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> > index e1b5c3b81e..1aa1aaeca4 100644
> > --- a/hw/virtio/virtio-mmio.c
> > +++ b/hw/virtio/virtio-mmio.c
> > @@ -627,7 +627,7 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
> >       }
> >
> >       if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
> > -        vdc->guest_notifier_mask(vdev, n, !assign);
> > +        vdc->guest_notifier_mask(vdev, n, !assign, VIRTIO_VQ_VECTOR);
> >       }
> >
> >       return 0;
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 36524a5728..481f6e7505 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -691,23 +691,17 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
> >   }
> >
> >   static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
> > -                                 unsigned int queue_no,
> > +                                 EventNotifier *n,
> >                                    unsigned int vector)
>
>
> All the changes of switching to use EventNotifier should be done as a
> separate patch.
>
> Thanks
>
sure will fix this
>
> >   {
> >       VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
> > -    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> > -    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> > -    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
> >       return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
> >   }
> >
> >   static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
> > -                                      unsigned int queue_no,
> > +                                      EventNotifier *n ,
> >                                         unsigned int vector)
> >   {
> > -    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> > -    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> > -    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
> >       VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
> >       int ret;
> >
> > @@ -722,7 +716,8 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
> >       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> >       unsigned int vector;
> >       int ret, queue_no;
> > -
> > +    VirtQueue *vq;
> > +    EventNotifier *n;
> >       for (queue_no = 0; queue_no < nvqs; queue_no++) {
> >           if (!virtio_queue_get_num(vdev, queue_no)) {
> >               break;
> > @@ -739,7 +734,9 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
> >            * Otherwise, delay until unmasked in the frontend.
> >            */
> >           if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -            ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
> > +            vq = virtio_get_queue(vdev, queue_no);
> > +            n = virtio_queue_get_guest_notifier(vq);
> > +            ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
> >               if (ret < 0) {
> >                   kvm_virtio_pci_vq_vector_release(proxy, vector);
> >                   goto undo;
> > @@ -755,7 +752,9 @@ undo:
> >               continue;
> >           }
> >           if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> > +            vq = virtio_get_queue(vdev, queue_no);
> > +            n = virtio_queue_get_guest_notifier(vq);
> > +            kvm_virtio_pci_irqfd_release(proxy, n, vector);
> >           }
> >           kvm_virtio_pci_vq_vector_release(proxy, vector);
> >       }
> > @@ -769,7 +768,8 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
> >       unsigned int vector;
> >       int queue_no;
> >       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> > -
> > +    VirtQueue *vq;
> > +    EventNotifier *n;
> >       for (queue_no = 0; queue_no < nvqs; queue_no++) {
> >           if (!virtio_queue_get_num(vdev, queue_no)) {
> >               break;
> > @@ -782,7 +782,9 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
> >            * Otherwise, it was cleaned when masked in the frontend.
> >            */
> >           if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> > +            vq = virtio_get_queue(vdev, queue_no);
> > +            n = virtio_queue_get_guest_notifier(vq);
> > +            kvm_virtio_pci_irqfd_release(proxy, n, vector);
> >           }
> >           kvm_virtio_pci_vq_vector_release(proxy, vector);
> >       }
> > @@ -791,12 +793,12 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
> >   static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
> >                                          unsigned int queue_no,
> >                                          unsigned int vector,
> > -                                       MSIMessage msg)
> > +                                       MSIMessage msg,
> > +                                       int type,
> > +                                        EventNotifier *n)
> >   {
> >       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> > -    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> > -    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
> >       VirtIOIRQFD *irqfd;
> >       int ret = 0;
> >
> > @@ -816,21 +818,23 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
> >        * Otherwise, set it up now.
> >        */
> >       if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -        k->guest_notifier_mask(vdev, queue_no, false);
> > +        k->guest_notifier_mask(vdev, queue_no, false, type);
> >           /* Test after unmasking to avoid losing events. */
> >           if (k->guest_notifier_pending &&
> > -            k->guest_notifier_pending(vdev, queue_no)) {
> > +            k->guest_notifier_pending(vdev, queue_no, type)) {
> >               event_notifier_set(n);
> >           }
> >       } else {
> > -        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
> > +        ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
> >       }
> >       return ret;
> >   }
> >
> >   static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
> >                                                unsigned int queue_no,
> > -                                             unsigned int vector)
> > +                                             unsigned int vector,
> > +                                             int type,
> > +                                             EventNotifier *n)
> >   {
> >       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >       VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> > @@ -839,9 +843,9 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
> >        * Otherwise, clean it up now.
> >        */
> >       if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -        k->guest_notifier_mask(vdev, queue_no, true);
> > +        k->guest_notifier_mask(vdev, queue_no, true, type);
> >       } else {
> > -        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> > +        kvm_virtio_pci_irqfd_release(proxy, n, vector);
> >       }
> >   }
> >
> > @@ -851,6 +855,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
> >       VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
> >       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >       VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
> > +    EventNotifier *n;
> >       int ret, index, unmasked = 0;
> >
> >       while (vq) {
> > @@ -859,7 +864,9 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
> >               break;
> >           }
> >           if (index < proxy->nvqs_with_notifiers) {
> > -            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
> > +            n = virtio_queue_get_guest_notifier(vq);
> > +            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg,
> > +                        VIRTIO_VQ_VECTOR, n);
> >               if (ret < 0) {
> >                   goto undo;
> >               }
> > @@ -875,7 +882,9 @@ undo:
> >       while (vq && unmasked >= 0) {
> >           index = virtio_get_queue_index(vq);
> >           if (index < proxy->nvqs_with_notifiers) {
> > -            virtio_pci_vq_vector_mask(proxy, index, vector);
> > +            n = virtio_queue_get_guest_notifier(vq);
> > +            virtio_pci_vq_vector_mask(proxy, index, vector,
> > +                 VIRTIO_VQ_VECTOR, n);
> >               --unmasked;
> >           }
> >           vq = virtio_vector_next_queue(vq);
> > @@ -888,15 +897,18 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
> >       VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
> >       VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >       VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
> > +    EventNotifier *n;
> >       int index;
> >
> >       while (vq) {
> >           index = virtio_get_queue_index(vq);
> > +         n = virtio_queue_get_guest_notifier(vq);
> >           if (!virtio_queue_get_num(vdev, index)) {
> >               break;
> >           }
> >           if (index < proxy->nvqs_with_notifiers) {
> > -            virtio_pci_vq_vector_mask(proxy, index, vector);
> > +            virtio_pci_vq_vector_mask(proxy, index, vector,
> > +                VIRTIO_VQ_VECTOR, n);
> >           }
> >           vq = virtio_vector_next_queue(vq);
> >       }
> > @@ -926,7 +938,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
> >           vq = virtio_get_queue(vdev, queue_no);
> >           notifier = virtio_queue_get_guest_notifier(vq);
> >           if (k->guest_notifier_pending) {
> > -            if (k->guest_notifier_pending(vdev, queue_no)) {
> > +            if (k->guest_notifier_pending(vdev, queue_no, VIRTIO_VQ_VECTOR)) {
> >                   msix_set_pending(dev, vector);
> >               }
> >           } else if (event_notifier_test_and_clear(notifier)) {
> > @@ -958,7 +970,7 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
> >       if (!msix_enabled(&proxy->pci_dev) &&
> >           vdev->use_guest_notifier_mask &&
> >           vdc->guest_notifier_mask) {
> > -        vdc->guest_notifier_mask(vdev, n, !assign);
> > +        vdc->guest_notifier_mask(vdev, n, !assign, VIRTIO_VQ_VECTOR);
> >       }
> >
> >       return 0;
> > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > index b7ece7a6a8..5a1940fe70 100644
> > --- a/include/hw/virtio/virtio.h
> > +++ b/include/hw/virtio/virtio.h
> > @@ -67,6 +67,11 @@ typedef struct VirtQueueElement
> >
> >   #define VIRTIO_NO_VECTOR 0xffff
> >
> > +enum virtio_vector_type {
> > +    VIRTIO_VQ_VECTOR,
> > +    VIRTIO_CONFIG_VECTOR,
> > +    VIRTIO_VECTOR_UNKNOWN,
> > +};
> >   #define TYPE_VIRTIO_DEVICE "virtio-device"
> >   OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
> >
> > @@ -138,13 +143,13 @@ struct VirtioDeviceClass {
> >        * If backend does not support masking,
> >        * must check in frontend instead.
> >        */
> > -    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n);
> > +    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n, int type);
> >       /* Mask/unmask events from this vq. Any events reported
> >        * while masked will become pending.
> >        * If backend does not support masking,
> >        * must mask in frontend instead.
> >        */
> > -    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
> > +    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask, int type);
> >       int (*start_ioeventfd)(VirtIODevice *vdev);
> >       void (*stop_ioeventfd)(VirtIODevice *vdev);
> >       /* Saving and loading of a device; trying to deprecate save/load
>



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 4/6] vhost-vdpa: add support for configure interrupt
  2021-04-09  7:24   ` Jason Wang
@ 2021-04-12  8:18     ` Cindy Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Cindy Lu @ 2021-04-12  8:18 UTC (permalink / raw)
  To: Jason Wang; +Cc: QEMU Developers, Michael Tsirkin

On Fri, Apr 9, 2021 at 3:24 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/4/8 下午5:38, Cindy Lu 写道:
> > Add support for configure interrupt. Set the notifier's fd to
> > the kernel driver when vdpa start. also set -1 while vdpa stop.
> > then the kernel will release the related resource
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/virtio/vhost-vdpa.c | 26 +++++++++++++++++++++++++-
> >   1 file changed, 25 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > index 9ba2a2bed4..7825366f64 100644
> > --- a/hw/virtio/vhost-vdpa.c
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -467,11 +467,33 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
> >       }
> >       return ret;
> >    }
> > -
>
>
> Let's keep this blank line.
>
>
sure will fix this
> > +static void vhost_vdpa_config_notify_start(struct vhost_dev *dev,
> > +                                struct VirtIODevice *vdev, bool start)
> > +{
> > +    int fd = 0;
> > +    int r = 0;
> > +    if (!(dev->features & (0x1ULL << VIRTIO_NET_F_STATUS))) {
> > +        return;
> > +    }
> > +    if (start) {
> > +        fd = event_notifier_get_fd(&vdev->config_notifier);
> > +        r = dev->vhost_ops->vhost_set_config_call(dev, &fd);
>
>
> So you introduce a general vhost ops but it's call by devic specific
> code (vhost-vdpa).
>
> Any reason that we don't do that in vhost_dev_start/vhost_dev_stop?
>
> Thanks
>
sure, will move this part to dev_start/stop
>
> > +        if (!r) {
> > +            vdev->use_config_notifier = true;
> > +            event_notifier_set(&vdev->config_notifier);
> > +        }
> > +    } else {
> > +        fd = -1;
> > +        vdev->use_config_notifier = false;
> > +        r = dev->vhost_ops->vhost_set_config_call(dev, &fd);
> > +    }
> > +    return;
> > +}
> >   static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> >   {
> >       struct vhost_vdpa *v = dev->opaque;
> >       trace_vhost_vdpa_dev_start(dev, started);
> > +    VirtIODevice *vdev = dev->vdev;
> >       if (started) {
> >           uint8_t status = 0;
> >           memory_listener_register(&v->listener, &address_space_memory);
> > @@ -479,8 +501,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> >           vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> >           vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
> >
> > +        vhost_vdpa_config_notify_start(dev, vdev, true);
> >           return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> >       } else {
> > +        vhost_vdpa_config_notify_start(dev, vdev, false);
> >           vhost_vdpa_reset_device(dev);
> >           vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> >                                      VIRTIO_CONFIG_S_DRIVER);
>



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v5 6/6] virtio-pci: add support for configure interrupt
  2021-04-09  7:39   ` Jason Wang
@ 2021-04-12  8:27     ` Cindy Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Cindy Lu @ 2021-04-12  8:27 UTC (permalink / raw)
  To: Jason Wang; +Cc: QEMU Developers, Michael Tsirkin

On Fri, Apr 9, 2021 at 3:39 PM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/4/8 下午5:38, Cindy Lu 写道:
> > Add support for configure interrupt, use kvm_irqfd_assign and set the
> > gsi to kernel. When the configure notifier was eventfd_signal by host
> > kernel, this will finally inject an msix interrupt to guest
> >
> > Signed-off-by: Cindy Lu <lulu@redhat.com>
> > ---
> >   hw/virtio/virtio-pci.c | 91 ++++++++++++++++++++++++++++++++++++++++--
> >   1 file changed, 88 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 481f6e7505..7b02f42c06 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -664,7 +664,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
> >   }
> >
> >   static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
> > -                                        unsigned int queue_no,
> >                                           unsigned int vector)
> >   {
> >       VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
> > @@ -726,7 +725,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
> >           if (vector >= msix_nr_vectors_allocated(dev)) {
> >               continue;
> >           }
> > -        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
> > +        ret = kvm_virtio_pci_vq_vector_use(proxy,  vector);
> >           if (ret < 0) {
> >               goto undo;
> >           }
> > @@ -760,6 +759,56 @@ undo:
> >       }
> >       return ret;
> >   }
> > +static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
> > +{
> > +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> > +    unsigned int vector;
> > +    int ret;
> > +    EventNotifier *n = virtio_get_config_notifier(vdev);
> > +    vector = vdev->config_vector ;
> > +    ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
> > +    if (ret < 0) {
> > +        goto undo;
> > +    }
> > +    ret = kvm_virtio_pci_irqfd_use(proxy,  n, vector);
>
>
> So the kvm_virtio_pci_vector_use() has the following codes:
>
>          /* If guest supports masking, set up irqfd now.
>           * Otherwise, delay until unmasked in the frontend.
>           */
>          if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
>              vq = virtio_get_queue(vdev, queue_no);
>              n = virtio_queue_get_guest_notifier(vq);
>              ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
>              if (ret < 0) {
>                  kvm_virtio_pci_vq_vector_release(proxy, vector);
>                  goto undo;
>              }
>          }
>
> Do we need to check the masking support here as well?
>
> Btw, I think we can factor out the core logic (decouple the queue_no) of
> kvm_virtio_pci_vector_user() and let it be reused by config interrupt.
>
sure , I will rewrite this part
>
> > +    if (ret < 0) {
> > +        goto undo;
> > +    }
> > +    return 0;
> > +undo:
> > +    kvm_virtio_pci_irqfd_release(proxy, n, vector);
> > +    return ret;
> > +}
> > +static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
> > +{
> > +    PCIDevice *dev = &proxy->pci_dev;
> > +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> > +    unsigned int vector;
> > +    EventNotifier *n = virtio_get_config_notifier(vdev);
> > +    vector = vdev->config_vector ;
> > +    if (vector >= msix_nr_vectors_allocated(dev)) {
> > +        return;
> > +    }
> > +    kvm_virtio_pci_irqfd_release(proxy, n, vector);
> > +    kvm_virtio_pci_vq_vector_release(proxy, vector);
> > +}
> > +static int virtio_pci_set_config_notifier(DeviceState *d,  bool assign)
> > +{
> > +    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
> > +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> > +    EventNotifier *notifier = virtio_get_config_notifier(vdev);
> > +    int r = 0;
> > +    if (assign) {
> > +        r = event_notifier_init(notifier, 0);
> > +        virtio_set_config_notifier_fd_handler(vdev, true, true);
> > +        kvm_virtio_pci_vector_config_use(proxy);
> > +    } else {
> > +        virtio_set_config_notifier_fd_handler(vdev, false, true);
>
>
> So let's try to unify the codes between this and
> virtio_queue_set_guest_notifier_fd_handler(). Bascailly it's just
> decouple virtqueue *.
>
sure will fix this
>
> > +        kvm_virtio_pci_vector_config_release(proxy);
> > +        event_notifier_cleanup(notifier);
> > +    }
> > +    return r;
> > +}
> >
> >   static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
> >   {
> > @@ -858,6 +907,14 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
> >       EventNotifier *n;
> >       int ret, index, unmasked = 0;
> >
> > +   if (vdev->use_config_notifier == true) {
> > +        n = virtio_get_config_notifier(vdev);
> > +        ret = virtio_pci_vq_vector_unmask(proxy, 0, vector, msg,
> > +                    VIRTIO_CONFIG_VECTOR, n);
> > +        if (ret < 0) {
> > +            goto config_undo;
> > +       }
> > +    }
> >       while (vq) {
> >           index = virtio_get_queue_index(vq);
> >           if (!virtio_queue_get_num(vdev, index)) {
> > @@ -889,6 +946,10 @@ undo:
> >           }
> >           vq = virtio_vector_next_queue(vq);
> >       }
> > + config_undo:
> > +            n = virtio_get_config_notifier(vdev);
> > +            virtio_pci_vq_vector_mask(proxy, 0, vector,
> > +                VIRTIO_CONFIG_VECTOR, n);
> >       return ret;
> >   }
> >
> > @@ -900,6 +961,10 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
> >       EventNotifier *n;
> >       int index;
> >
> > +   if (vdev->use_config_notifier == true) {
>
>
> Is this sufficient to know the vector is used by config interrupt?
>
>
> > +        n = virtio_get_config_notifier(vdev);
> > +        virtio_pci_vq_vector_mask(proxy, 0, vector, VIRTIO_CONFIG_VECTOR, n);
> > +   }
> >       while (vq) {
> >           index = virtio_get_queue_index(vq);
> >            n = virtio_queue_get_guest_notifier(vq);
> > @@ -945,6 +1010,21 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
> >               msix_set_pending(dev, vector);
> >           }
> >       }
> > +   if (vdev->use_config_notifier == true) {
> > +        vector = vdev->config_vector;
> > +        notifier = virtio_get_config_notifier(vdev);
> > +        if (vector < vector_start || vector >= vector_end ||
> > +            !msix_is_masked(dev, vector)) {
> > +            return;
> > +        }
> > +        if (k->guest_notifier_pending) {
> > +            if (k->guest_notifier_pending(vdev, 0,  VIRTIO_CONFIG_VECTOR)) {
> > +                msix_set_pending(dev, vector);
> > +            }
> > +        } else if (event_notifier_test_and_clear(notifier)) {
> > +            msix_set_pending(dev, vector);
> > +        }
> > +    }
>
>
> Let's unify the code here with the code that deal with vq vectors in the
> loop above.
>
> Thanks
>
>
> >   }
> >
> >   static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
> > @@ -1032,6 +1112,10 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
> >                   goto assign_error;
> >               }
> >           }
> > +            r = virtio_pci_set_config_notifier(d, assign);
> > +            if (r < 0) {
> > +                goto config_error;
> > +         }
> >           r = msix_set_vector_notifiers(&proxy->pci_dev,
> >                                         virtio_pci_vector_unmask,
> >                                         virtio_pci_vector_mask,
> > @@ -1048,7 +1132,8 @@ notifiers_error:
> >           assert(assign);
> >           kvm_virtio_pci_vector_release(proxy, nvqs);
> >       }
> > -
> > + config_error:
> > +        kvm_virtio_pci_vector_config_release(proxy);
> >   assign_error:
> >       /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
> >       assert(assign);
>



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2021-04-12  8:32 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08  9:38 [PATCH v5 0/6] vhost-vdpa: add support for configure interrupt Cindy Lu
2021-04-08  9:38 ` [PATCH v5 1/6] virtio: introduce new type in interrupt process Cindy Lu
2021-04-09  6:57   ` Jason Wang
2021-04-12  8:09     ` Cindy Lu
2021-04-08  9:38 ` [PATCH v5 2/6] vhost: add new call back function for config interrupt Cindy Lu
2021-04-09  7:12   ` Jason Wang
2021-04-12  8:06     ` Cindy Lu
2021-04-08  9:38 ` [PATCH v5 3/6] virtio:add support in configure interrupt Cindy Lu
2021-04-09  7:21   ` Jason Wang
2021-04-12  8:05     ` Cindy Lu
2021-04-08  9:38 ` [PATCH v5 4/6] vhost-vdpa: add support for " Cindy Lu
2021-04-09  7:24   ` Jason Wang
2021-04-12  8:18     ` Cindy Lu
2021-04-08  9:38 ` [PATCH v5 5/6] virtio-mmio: " Cindy Lu
2021-04-09  7:27   ` Jason Wang
2021-04-08  9:38 ` [PATCH v5 6/6] virtio-pci: " Cindy Lu
2021-04-09  7:39   ` Jason Wang
2021-04-12  8:27     ` Cindy Lu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.