From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 5008A1B1BC for ; Fri, 12 Jan 2018 16:51:17 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 850B22DB715; Fri, 12 Jan 2018 15:51:11 +0000 (UTC) Received: from localhost.localdomain (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 80CB467678; Fri, 12 Jan 2018 15:50:56 +0000 (UTC) From: Maxime Coquelin To: dev@dpdk.org, tiwei.bie@intel.com, yliu@fridaylinux.org, jfreimann@redhat.com Cc: Maxime Coquelin Date: Fri, 12 Jan 2018 16:50:16 +0100 Message-Id: <20180112155016.8990-3-maxime.coquelin@redhat.com> In-Reply-To: <20180112155016.8990-1-maxime.coquelin@redhat.com> References: <20180112155016.8990-1-maxime.coquelin@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 12 Jan 2018 15:51:11 +0000 (UTC) Subject: [dpdk-dev] [RFC 2/2] vhost-user: add support for VHOST_USER_SET_QUEUE_NUM X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jan 2018 15:51:17 -0000 With some guest drivers, the number of queues setup by the guest driver can be less than the number of queues declared in Qemu. This is the case for example with Windows virtio-net driver, which only setups as much queue pairs as the number of vCPUs. When it happens, depending on QEMU version, the vhost-user port can: - Either be started with some uninitialized queues, which ends up corrupting GPA at 0 when guest notifications get disabled, - Or be stuck forever, waiting for uninitialized rings to be ready. This patch implements handling of VHOST_USER_SET_QUEUE_NUM new protocol request, which is sent by QEMU to report the number of queue pairs initialized by the guest driver. When received, all unused queues get removed from the vhost-user port, taking care that it is not already running. Signed-off-by: Maxime Coquelin --- lib/librte_vhost/vhost_user.c | 30 ++++++++++++++++++++++++++++++ lib/librte_vhost/vhost_user.h | 5 ++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index f94fd16cf..73388027e 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -50,6 +50,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] = { [VHOST_USER_NET_SET_MTU] = "VHOST_USER_NET_SET_MTU", [VHOST_USER_SET_SLAVE_REQ_FD] = "VHOST_USER_SET_SLAVE_REQ_FD", [VHOST_USER_IOTLB_MSG] = "VHOST_USER_IOTLB_MSG", + [VHOST_USER_SET_QUEUE_NUM] = "VHOST_USER_SET_QUEUE_NUM", }; static uint64_t @@ -1137,6 +1138,32 @@ vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg) return 0; } +static int +vhost_user_set_queue_num(struct virtio_net *dev, struct VhostUserMsg *msg) +{ + uint64_t queue_num = msg->payload.u64 * 2; /* Payload is nr of qpairs */ + + if (dev->nr_vring > queue_num && dev->flags & VIRTIO_DEV_RUNNING) { + RTE_LOG(ERR, VHOST_CONFIG, + "Cannot remove queues while device is running\n"); + return -1; + } + + while (dev->nr_vring > queue_num) { + 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; +} + /* return bytes# of read on success or negative val on failure. */ static int read_vhost_message(int sockfd, struct VhostUserMsg *msg) @@ -1389,6 +1416,9 @@ vhost_user_msg_handler(int vid, int fd) case VHOST_USER_IOTLB_MSG: ret = vhost_user_iotlb_msg(&dev, &msg); break; + case VHOST_USER_SET_QUEUE_NUM: + vhost_user_set_queue_num(dev, &msg); + break; default: ret = -1; diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h index d4bd604b9..ab6557d9e 100644 --- a/lib/librte_vhost/vhost_user.h +++ b/lib/librte_vhost/vhost_user.h @@ -20,13 +20,15 @@ #define VHOST_USER_PROTOCOL_F_REPLY_ACK 3 #define VHOST_USER_PROTOCOL_F_NET_MTU 4 #define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5 +#define VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM 7 #define VHOST_USER_PROTOCOL_FEATURES ((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \ (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\ (1ULL << VHOST_USER_PROTOCOL_F_RARP) | \ (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \ (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU) | \ - (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ)) + (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ) | \ + (1ULL << VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM)) typedef enum VhostUserRequest { VHOST_USER_NONE = 0, @@ -52,6 +54,7 @@ typedef enum VhostUserRequest { VHOST_USER_NET_SET_MTU = 20, VHOST_USER_SET_SLAVE_REQ_FD = 21, VHOST_USER_IOTLB_MSG = 22, + VHOST_USER_SET_QUEUE_NUM = 24, VHOST_USER_MAX } VhostUserRequest; -- 2.14.3