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.
63 lines
2.2 KiB
63 lines
2.2 KiB
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 |
|
|
|
|