vhost: introduce reply ack feature

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>
This commit is contained in:
Maxime Coquelin 2016-12-12 18:54:00 +01:00 committed by Yuanhan Liu
parent b3bee7d87d
commit 73c8f9f69c
2 changed files with 14 additions and 2 deletions

View File

@ -903,6 +903,7 @@ send_vhost_message(int sockfd, struct VhostUserMsg *msg)
return 0; return 0;
msg->flags &= ~VHOST_USER_VERSION_MASK; msg->flags &= ~VHOST_USER_VERSION_MASK;
msg->flags &= ~VHOST_USER_NEED_REPLY;
msg->flags |= VHOST_USER_VERSION; msg->flags |= VHOST_USER_VERSION;
msg->flags |= VHOST_USER_REPLY_MASK; msg->flags |= VHOST_USER_REPLY_MASK;
@ -938,6 +939,7 @@ vhost_user_msg_handler(int vid, int fd)
return -1; return -1;
} }
ret = 0;
RTE_LOG(INFO, VHOST_CONFIG, "read message %s\n", RTE_LOG(INFO, VHOST_CONFIG, "read message %s\n",
vhost_message_str[msg.request]); vhost_message_str[msg.request]);
switch (msg.request) { switch (msg.request) {
@ -967,7 +969,7 @@ vhost_user_msg_handler(int vid, int fd)
break; break;
case VHOST_USER_SET_MEM_TABLE: case VHOST_USER_SET_MEM_TABLE:
vhost_user_set_mem_table(dev, &msg); ret = vhost_user_set_mem_table(dev, &msg);
break; break;
case VHOST_USER_SET_LOG_BASE: case VHOST_USER_SET_LOG_BASE:
@ -1025,9 +1027,16 @@ vhost_user_msg_handler(int vid, int fd)
break; break;
default: default:
ret = -1;
break; 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; return 0;
} }

View File

@ -46,10 +46,12 @@
#define VHOST_USER_PROTOCOL_F_MQ 0 #define VHOST_USER_PROTOCOL_F_MQ 0
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
#define VHOST_USER_PROTOCOL_F_RARP 2 #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) | \ #define VHOST_USER_PROTOCOL_FEATURES ((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \
(1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\ (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 { typedef enum VhostUserRequest {
VHOST_USER_NONE = 0, VHOST_USER_NONE = 0,
@ -98,6 +100,7 @@ typedef struct VhostUserMsg {
#define VHOST_USER_VERSION_MASK 0x3 #define VHOST_USER_VERSION_MASK 0x3
#define VHOST_USER_REPLY_MASK (0x1 << 2) #define VHOST_USER_REPLY_MASK (0x1 << 2)
#define VHOST_USER_NEED_REPLY (0x1 << 3)
uint32_t flags; uint32_t flags;
uint32_t size; /* the following payload size */ uint32_t size; /* the following payload size */
union { union {