On Wed, Dec 03, 2025 at 07:54:30PM +0100, Laurent Vivier wrote: > Advertise multi-queue support in vhost-user by setting VIRTIO_NET_F_MQ > and VHOST_USER_PROTOCOL_F_MQ feature flags, and increase > VHOST_USER_MAX_VQS from 2 to 32, supporting up to 16 queue pairs. > > Currently, only the first RX queue (queue 0) is used for receiving > packets. The guest kernel selects which TX queue to use for > transmission. Full multi-RX queue load balancing will be implemented in > future work. > > Update the QEMU usage hint to show the required parameters for enabling > multiqueue: queues parameter on the netdev, and mq=true on the > virtio-net device. > > Signed-off-by: Laurent Vivier Reviewed-by: David Gibson > --- > tap.c | 7 +++++-- > vhost_user.c | 10 ++++++---- > virtio.h | 2 +- > 3 files changed, 12 insertions(+), 7 deletions(-) > > diff --git a/tap.c b/tap.c > index 2cda8c9772b8..591b49491aa3 100644 > --- a/tap.c > +++ b/tap.c > @@ -1314,8 +1314,11 @@ static void tap_backend_show_hints(struct ctx *c) > break; > case MODE_VU: > info("You can start qemu with:"); > - info(" kvm ... -chardev socket,id=chr0,path=%s -netdev vhost-user,id=netdev0,chardev=chr0 -device virtio-net,netdev=netdev0 -object memory-backend-memfd,id=memfd0,share=on,size=$RAMSIZE -numa node,memdev=memfd0\n", > - c->sock_path); > + info(" kvm ... -chardev socket,id=chr0,path=%s " > + "-netdev vhost-user,id=netdev0,chardev=chr0,queues=$QUEUES " > + "-device virtio-net,netdev=netdev0,mq=true " > + "-object memory-backend-memfd,id=memfd0,share=on,size=$RAMSIZE " > + "-numa node,memdev=memfd0\n", c->sock_path); > break; > } > } > diff --git a/vhost_user.c b/vhost_user.c > index aa7c869d9e56..845fdb551c84 100644 > --- a/vhost_user.c > +++ b/vhost_user.c > @@ -323,6 +323,7 @@ static bool vu_get_features_exec(struct vu_dev *vdev, > uint64_t features = > 1ULL << VIRTIO_F_VERSION_1 | > 1ULL << VIRTIO_NET_F_MRG_RXBUF | > + 1ULL << VIRTIO_NET_F_MQ | > 1ULL << VHOST_F_LOG_ALL | > 1ULL << VHOST_USER_F_PROTOCOL_FEATURES; > > @@ -767,7 +768,8 @@ static void vu_check_queue_msg_file(struct vhost_user_msg *vmsg) > int idx = vmsg->payload.u64 & VHOST_USER_VRING_IDX_MASK; > > if (idx >= VHOST_USER_MAX_VQS) > - die("Invalid vhost-user queue index: %u", idx); > + die("Invalid vhost-user queue index: %u (maximum %u)", idx, > + VHOST_USER_MAX_VQS); > > if (nofd) { > vmsg_close_fds(vmsg); > @@ -896,7 +898,8 @@ static bool vu_get_protocol_features_exec(struct vu_dev *vdev, > uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK | > 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD | > 1ULL << VHOST_USER_PROTOCOL_F_DEVICE_STATE | > - 1ULL << VHOST_USER_PROTOCOL_F_RARP; > + 1ULL << VHOST_USER_PROTOCOL_F_RARP | > + 1ULL << VHOST_USER_PROTOCOL_F_MQ; > > (void)vdev; > vmsg_set_reply_u64(vmsg, features); > @@ -935,10 +938,9 @@ static bool vu_get_queue_num_exec(struct vu_dev *vdev, > { > (void)vdev; > > - /* NOLINTNEXTLINE(misc-redundant-expression) */ > vmsg_set_reply_u64(vmsg, VHOST_USER_MAX_VQS / 2); > > - debug("VHOST_USER_MAX_VQS %u", VHOST_USER_MAX_VQS / 2); > + debug("queue num %u", VHOST_USER_MAX_VQS / 2); > > return true; > } > diff --git a/virtio.h b/virtio.h > index 12caaa0b6def..176c935cecc7 100644 > --- a/virtio.h > +++ b/virtio.h > @@ -88,7 +88,7 @@ struct vu_dev_region { > uint64_t mmap_addr; > }; > > -#define VHOST_USER_MAX_VQS 2 > +#define VHOST_USER_MAX_VQS 32 > > /* > * Set a reasonable maximum number of ram slots, which will be supported by > -- > 2.51.1 > -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson