DPDK patches and discussions
 help / color / mirror / Atom feed
From: Maxime Coquelin <maxime.coquelin@redhat.com>
To: dev@dpdk.org, tiwei.bie@intel.com, yliu@fridaylinux.org,
	jfreimann@redhat.com
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [dpdk-dev] [RFC 2/2] vhost-user: add support for VHOST_USER_SET_QUEUE_NUM
Date: Fri, 12 Jan 2018 16:50:16 +0100	[thread overview]
Message-ID: <20180112155016.8990-3-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20180112155016.8990-1-maxime.coquelin@redhat.com>

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 <maxime.coquelin@redhat.com>
---
 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

      parent reply	other threads:[~2018-01-12 15:51 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-12 15:50 [dpdk-dev] [RFC 0/2] vhost-user: add VHOST_USER_SET_QUEUE_NUM support Maxime Coquelin
2018-01-12 15:50 ` [dpdk-dev] [RFC 1/2] vhost-user: don't allocate new queue once device is running Maxime Coquelin
2018-01-12 15:50 ` Maxime Coquelin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180112155016.8990-3-maxime.coquelin@redhat.com \
    --to=maxime.coquelin@redhat.com \
    --cc=dev@dpdk.org \
    --cc=jfreimann@redhat.com \
    --cc=tiwei.bie@intel.com \
    --cc=yliu@fridaylinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).