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>
This commit is contained in:
parent
467fe22df9
commit
e291093235
@ -187,6 +187,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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user