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

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