|
|
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 |
|