Blame SOURCES/kvm-virtio-pci-speedup-MSI-X-masking-and-unmasking.patch

8be556
From faa5a68c3133624759bc7e36714fd6629bcd00d8 Mon Sep 17 00:00:00 2001
8be556
From: Xiao Wang <jasowang@redhat.com>
8be556
Date: Thu, 18 Jun 2015 06:11:45 +0200
8be556
Subject: [PATCH 024/217] virtio-pci: speedup MSI-X masking and unmasking
8be556
8be556
Message-id: <1434607916-15166-10-git-send-email-jasowang@redhat.com>
8be556
Patchwork-id: 66307
8be556
O-Subject: [RHEL7.2 qemu-kvm-rhev PATCH 09/20] virtio-pci: speedup MSI-X masking and unmasking
8be556
Bugzilla: 1231610
8be556
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8be556
RH-Acked-by: Vlad Yasevich <vyasevic@redhat.com>
8be556
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
8be556
8be556
This patch tries to speed up the MSI-X masking and unmasking through
8be556
the mapping between vector and queues. With this patch it will there's
8be556
no need to go through all possible virtqueues, which may help to
8be556
reduce the time spent when doing MSI-X masking/unmasking a single
8be556
vector when more than hundreds or even thousands of virtqueues were
8be556
supported.
8be556
8be556
Tested with 80 queue pairs virito-net-pci by changing the smp affinity
8be556
in the background and doing netperf in the same time:
8be556
8be556
Before the patch:
8be556
5711.70 Gbits/sec
8be556
After the patch:
8be556
6830.98 Gbits/sec
8be556
8be556
About 19.6% improvements in throughput.
8be556
8be556
Cc: Michael S. Tsirkin <mst@redhat.com>
8be556
Signed-off-by: Jason Wang <jasowang@redhat.com>
8be556
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8be556
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
8be556
(cherry picked from commit 851c2a75a6e80c8aa5e713864d98cfb512e7229b)
8be556
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
8be556
---
8be556
 hw/virtio/virtio-pci.c | 40 +++++++++++++++++++++-------------------
8be556
 1 file changed, 21 insertions(+), 19 deletions(-)
8be556
8be556
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
8be556
index 6b064b9..b91e799 100644
8be556
--- a/hw/virtio/virtio-pci.c
8be556
+++ b/hw/virtio/virtio-pci.c
8be556
@@ -630,28 +630,30 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
8be556
 {
8be556
     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
8be556
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
8be556
-    int ret, queue_no;
8be556
+    VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
8be556
+    int ret, index, unmasked = 0;
8be556
 
8be556
-    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
8be556
-        if (!virtio_queue_get_num(vdev, queue_no)) {
8be556
+    while (vq) {
8be556
+        index = virtio_get_queue_index(vq);
8be556
+        if (!virtio_queue_get_num(vdev, index)) {
8be556
             break;
8be556
         }
8be556
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
8be556
-            continue;
8be556
-        }
8be556
-        ret = virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg);
8be556
+        ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
8be556
         if (ret < 0) {
8be556
             goto undo;
8be556
         }
8be556
+        vq = virtio_vector_next_queue(vq);
8be556
+        ++unmasked;
8be556
     }
8be556
+
8be556
     return 0;
8be556
 
8be556
 undo:
8be556
-    while (--queue_no >= 0) {
8be556
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
8be556
-            continue;
8be556
-        }
8be556
-        virtio_pci_vq_vector_mask(proxy, queue_no, vector);
8be556
+    vq = virtio_vector_first_queue(vdev, vector);
8be556
+    while (vq && --unmasked >= 0) {
8be556
+        index = virtio_get_queue_index(vq);
8be556
+        virtio_pci_vq_vector_mask(proxy, index, vector);
8be556
+        vq = virtio_vector_next_queue(vq);
8be556
     }
8be556
     return ret;
8be556
 }
8be556
@@ -660,16 +662,16 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
8be556
 {
8be556
     VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
8be556
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
8be556
-    int queue_no;
8be556
+    VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
8be556
+    int index;
8be556
 
8be556
-    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
8be556
-        if (!virtio_queue_get_num(vdev, queue_no)) {
8be556
+    while (vq) {
8be556
+        index = virtio_get_queue_index(vq);
8be556
+        if (!virtio_queue_get_num(vdev, index)) {
8be556
             break;
8be556
         }
8be556
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
8be556
-            continue;
8be556
-        }
8be556
-        virtio_pci_vq_vector_mask(proxy, queue_no, vector);
8be556
+        virtio_pci_vq_vector_mask(proxy, index, vector);
8be556
+        vq = virtio_vector_next_queue(vq);
8be556
     }
8be556
 }
8be556
 
8be556
-- 
8be556
1.8.3.1
8be556