Blame SOURCES/0004-vhost-destroy-unused-virtqueues-when-multiqueue-not-.patch

c7ffa4
From eb2b3b18edc3af42f52ca5b3f30aa8bfbd08206a Mon Sep 17 00:00:00 2001
c7ffa4
From: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
Date: Wed, 13 Dec 2017 09:51:09 +0100
c7ffa4
Subject: [PATCH 4/6] vhost: destroy unused virtqueues when multiqueue not
c7ffa4
 negotiated
c7ffa4
c7ffa4
QEMU sends VHOST_USER_SET_VRING_CALL requests for all queues
c7ffa4
declared in QEMU command line before the guest is started.
c7ffa4
It has the effect in DPDK vhost-user backend to allocate vrings
c7ffa4
for all queues declared by QEMU.
c7ffa4
c7ffa4
If the first driver being used does not support multiqueue,
c7ffa4
the device never changes to VIRTIO_DEV_RUNNING state as only
c7ffa4
the first queue pair is initialized. One driver impacted by
c7ffa4
this bug is virtio-net's iPXE driver which does not support
c7ffa4
VIRTIO_NET_F_MQ feature.
c7ffa4
c7ffa4
It is safe to destroy unused virtqueues in SET_FEATURES request
c7ffa4
handler, as it is ensured the device is not in running state
c7ffa4
at this stage, so virtqueues aren't being processed.
c7ffa4
c7ffa4
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
Acked-by: Laszlo Ersek <lersek@redhat.com>
c7ffa4
Acked-by: Yuanhan Liu <yliu@fridaylinux.org>
c7ffa4
(cherry picked from commit e29109323595beb3884da58126ebb3b878cb66f5)
c7ffa4
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
c7ffa4
---
c7ffa4
 dpdk-17.11/lib/librte_vhost/vhost_user.c | 19 +++++++++++++++++++
c7ffa4
 1 file changed, 19 insertions(+)
c7ffa4
c7ffa4
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
c7ffa4
index 471b1612c..1848c8de9 100644
c7ffa4
--- a/lib/librte_vhost/vhost_user.c
c7ffa4
+++ b/lib/librte_vhost/vhost_user.c
c7ffa4
@@ -216,6 +216,25 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
c7ffa4
 		(dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF)) ? "on" : "off",
c7ffa4
 		(dev->features & (1ULL << VIRTIO_F_VERSION_1)) ? "on" : "off");
c7ffa4
 
c7ffa4
+	if (!(dev->features & (1ULL << VIRTIO_NET_F_MQ))) {
c7ffa4
+		/*
c7ffa4
+		 * Remove all but first queue pair if MQ hasn't been
c7ffa4
+		 * negotiated. This is safe because the device is not
c7ffa4
+		 * running at this stage.
c7ffa4
+		 */
c7ffa4
+		while (dev->nr_vring > 2) {
c7ffa4
+			struct vhost_virtqueue *vq;
c7ffa4
+
c7ffa4
+			vq = dev->virtqueue[--dev->nr_vring];
c7ffa4
+			if (!vq)
c7ffa4
+				continue;
c7ffa4
+
c7ffa4
+			dev->virtqueue[dev->nr_vring] = NULL;
c7ffa4
+			cleanup_vq(vq, 1);
c7ffa4
+			free_vq(vq);
c7ffa4
+		}
c7ffa4
+	}
c7ffa4
+
c7ffa4
 	return 0;
c7ffa4
 }
c7ffa4
 
c7ffa4
-- 
c7ffa4
2.14.3
c7ffa4