vhost: introduce reply ack feature
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Mon, 12 Dec 2016 17:54:00 +0000 (18:54 +0100)
committerYuanhan Liu <yuanhan.liu@linux.intel.com>
Tue, 17 Jan 2017 08:20:18 +0000 (09:20 +0100)
REPLY_ACK features provide a generic way for QEMU to ensure both
completion and success of a request.

As described in vhost-user spec in QEMU repository, QEMU sets
VHOST_USER_NEED_REPLY flag (bit 3) when expecting a reply_ack from
the backend. Backend must reply with 0 for success or non-zero
otherwise when flag is set.

Currently, only VHOST_USER_SET_MEM_TABLE request implements reply_ack,
in order to synchronize mapping updates.

This patch enables REPLY_ACK feature generally, but only checks error
code for VHOST_USER_SET_MEM_TABLE.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
lib/librte_vhost/vhost_user.c
lib/librte_vhost/vhost_user.h

index 50cb6d1..7343a00 100644 (file)
@@ -903,6 +903,7 @@ send_vhost_message(int sockfd, struct VhostUserMsg *msg)
                return 0;
 
        msg->flags &= ~VHOST_USER_VERSION_MASK;
+       msg->flags &= ~VHOST_USER_NEED_REPLY;
        msg->flags |= VHOST_USER_VERSION;
        msg->flags |= VHOST_USER_REPLY_MASK;
 
@@ -938,6 +939,7 @@ vhost_user_msg_handler(int vid, int fd)
                return -1;
        }
 
+       ret = 0;
        RTE_LOG(INFO, VHOST_CONFIG, "read message %s\n",
                vhost_message_str[msg.request]);
        switch (msg.request) {
@@ -967,7 +969,7 @@ vhost_user_msg_handler(int vid, int fd)
                break;
 
        case VHOST_USER_SET_MEM_TABLE:
-               vhost_user_set_mem_table(dev, &msg);
+               ret = vhost_user_set_mem_table(dev, &msg);
                break;
 
        case VHOST_USER_SET_LOG_BASE:
@@ -1025,9 +1027,16 @@ vhost_user_msg_handler(int vid, int fd)
                break;
 
        default:
+               ret = -1;
                break;
 
        }
 
+       if (msg.flags & VHOST_USER_NEED_REPLY) {
+               msg.payload.u64 = !!ret;
+               msg.size = sizeof(msg.payload.u64);
+               send_vhost_message(fd, &msg);
+       }
+
        return 0;
 }
index ba78d32..179e441 100644 (file)
 #define VHOST_USER_PROTOCOL_F_MQ       0
 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD        1
 #define VHOST_USER_PROTOCOL_F_RARP     2
+#define VHOST_USER_PROTOCOL_F_REPLY_ACK        3
 
 #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_RARP) | \
+                                        (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
 
 typedef enum VhostUserRequest {
        VHOST_USER_NONE = 0,
@@ -98,6 +100,7 @@ typedef struct VhostUserMsg {
 
 #define VHOST_USER_VERSION_MASK     0x3
 #define VHOST_USER_REPLY_MASK       (0x1 << 2)
+#define VHOST_USER_NEED_REPLY          (0x1 << 3)
        uint32_t flags;
        uint32_t size; /* the following payload size */
        union {