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