When the slave cannot add queues dynamically, it needs to know for
how many queues to wait to be initialized.

This patch introduce new vhost-user protocol feature & request for
the master to send the number of queue pairs allocated by the
driver.

Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com>
---
 docs/interop/vhost-user.txt       | 16 ++++++++++++++++
 hw/virtio/vhost-user.c            | 24 ++++++++++++++++++++++++
 include/hw/virtio/vhost-backend.h |  3 +++
 3 files changed, 43 insertions(+)

diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
index 8a14191a1e..85c0e03a95 100644
--- a/docs/interop/vhost-user.txt
+++ b/docs/interop/vhost-user.txt
@@ -218,6 +218,9 @@ The max number of queue pairs the slave supports can be 
queried with message
 VHOST_USER_GET_QUEUE_NUM. Master should stop when the number of
 requested queues is bigger than that.
 
+When VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM is negotiated, the master must send
+the number of queue pairs initialized with message VHOST_USER_SET_QUEUE_NUM.
+
 As all queues share one connection, the master uses a unique index for each
 queue in the sent message to identify a specified queue. One queue pair
 is enabled initially. More queues are enabled dynamically, by sending
@@ -354,6 +357,7 @@ Protocol features
 #define VHOST_USER_PROTOCOL_F_MTU            4
 #define VHOST_USER_PROTOCOL_F_SLAVE_REQ      5
 #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN   6
+#define VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM  7
 
 Master message types
 --------------------
@@ -623,6 +627,18 @@ Master message types
       and expect this message once (per VQ) during device configuration
       (ie. before the master starts the VQ).
 
+ * VHOST_USER_SET_QUEUE_NUM
+
+      Id: 24
+      Equivalent ioctl: N/A
+      Master payload: u64
+
+      Set the number of queue pairs initialized.
+      Master sends such request to notify the slave the number of queue pairs
+      that have been initialized.
+      This request should only be sent if VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM
+      feature has been successfully negotiated.
+
 Slave message types
 -------------------
 
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 093675ed98..9e7728d2da 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -34,6 +34,7 @@ enum VhostUserProtocolFeature {
     VHOST_USER_PROTOCOL_F_NET_MTU = 4,
     VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
     VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
+    VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM = 7,
 
     VHOST_USER_PROTOCOL_F_MAX
 };
@@ -65,6 +66,7 @@ typedef enum VhostUserRequest {
     VHOST_USER_SET_SLAVE_REQ_FD = 21,
     VHOST_USER_IOTLB_MSG = 22,
     VHOST_USER_SET_VRING_ENDIAN = 23,
+    VHOST_USER_SET_QUEUE_NUM = 24,
     VHOST_USER_MAX
 } VhostUserRequest;
 
@@ -922,6 +924,27 @@ static void vhost_user_set_iotlb_callback(struct vhost_dev 
*dev, int enabled)
     /* No-op as the receive channel is not dedicated to IOTLB messages. */
 }
 
+static int vhost_user_set_queue_num(struct vhost_dev *dev, uint64_t queues)
+{
+    VhostUserMsg msg = {
+        .request = VHOST_USER_SET_QUEUE_NUM,
+        .size = sizeof(msg.payload.u64),
+        .flags = VHOST_USER_VERSION,
+        .payload.u64 = queues,
+    };
+
+    if (!(dev->protocol_features &
+                (1ULL << VHOST_USER_PROTOCOL_F_SET_QUEUE_NUM))) {
+        return 0;
+    }
+
+    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
 const VhostOps user_ops = {
         .backend_type = VHOST_BACKEND_TYPE_USER,
         .vhost_backend_init = vhost_user_init,
@@ -948,4 +971,5 @@ const VhostOps user_ops = {
         .vhost_net_set_mtu = vhost_user_net_set_mtu,
         .vhost_set_iotlb_callback = vhost_user_set_iotlb_callback,
         .vhost_send_device_iotlb_msg = vhost_user_send_device_iotlb_msg,
+        .vhost_set_queue_num = vhost_user_set_queue_num,
 };
diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index a7a5f22bc6..1dd3e4bbf3 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -84,6 +84,8 @@ typedef void (*vhost_set_iotlb_callback_op)(struct vhost_dev 
*dev,
                                            int enabled);
 typedef int (*vhost_send_device_iotlb_msg_op)(struct vhost_dev *dev,
                                               struct vhost_iotlb_msg *imsg);
+typedef int (*vhost_set_queue_num_op)(struct vhost_dev *dev,
+                                      uint64_t queues);
 
 typedef struct VhostOps {
     VhostBackendType backend_type;
@@ -118,6 +120,7 @@ typedef struct VhostOps {
     vhost_vsock_set_running_op vhost_vsock_set_running;
     vhost_set_iotlb_callback_op vhost_set_iotlb_callback;
     vhost_send_device_iotlb_msg_op vhost_send_device_iotlb_msg;
+    vhost_set_queue_num_op vhost_set_queue_num;
 } VhostOps;
 
 extern const VhostOps user_ops;
-- 
2.14.3


Reply via email to