vhost-user: Introduce a new protocol feature REPLY_ACK.
This introduces the VHOST_USER_PROTOCOL_F_REPLY_ACK. If negotiated, client applications should send a u64 payload in response to any message that contains the "need_reply" bit set on the message flags. Setting the payload to "zero" indicates the command finished successfully. Likewise, setting it to "non-zero" indicates an error. Currently implemented only for SET_MEM_TABLE. Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Prerna Saxena <prerna.saxena@nutanix.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
		
							parent
							
								
									ca10203cde
								
							
						
					
					
						commit
						ca525ce561
					
				| 
						 | 
					@ -37,6 +37,8 @@ consists of 3 header fields and a payload:
 | 
				
			||||||
 * Flags: 32-bit bit field:
 | 
					 * Flags: 32-bit bit field:
 | 
				
			||||||
   - Lower 2 bits are the version (currently 0x01)
 | 
					   - Lower 2 bits are the version (currently 0x01)
 | 
				
			||||||
   - Bit 2 is the reply flag - needs to be sent on each reply from the slave
 | 
					   - Bit 2 is the reply flag - needs to be sent on each reply from the slave
 | 
				
			||||||
 | 
					   - Bit 3 is the need_reply flag - see VHOST_USER_PROTOCOL_F_REPLY_ACK for
 | 
				
			||||||
 | 
					     details.
 | 
				
			||||||
 * Size - 32-bit size of the payload
 | 
					 * Size - 32-bit size of the payload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,6 +128,8 @@ the ones that do:
 | 
				
			||||||
 * VHOST_GET_VRING_BASE
 | 
					 * VHOST_GET_VRING_BASE
 | 
				
			||||||
 * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
 | 
					 * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ Also see the section on REPLY_ACK protocol extension. ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are several messages that the master sends with file descriptors passed
 | 
					There are several messages that the master sends with file descriptors passed
 | 
				
			||||||
in the ancillary data:
 | 
					in the ancillary data:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -254,6 +258,7 @@ Protocol features
 | 
				
			||||||
#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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Message types
 | 
					Message types
 | 
				
			||||||
-------------
 | 
					-------------
 | 
				
			||||||
| 
						 | 
					@ -464,3 +469,24 @@ Message types
 | 
				
			||||||
      is present in VHOST_USER_GET_PROTOCOL_FEATURES.
 | 
					      is present in VHOST_USER_GET_PROTOCOL_FEATURES.
 | 
				
			||||||
      The first 6 bytes of the payload contain the mac address of the guest to
 | 
					      The first 6 bytes of the payload contain the mac address of the guest to
 | 
				
			||||||
      allow the vhost user backend to construct and broadcast the fake RARP.
 | 
					      allow the vhost user backend to construct and broadcast the fake RARP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VHOST_USER_PROTOCOL_F_REPLY_ACK:
 | 
				
			||||||
 | 
					-------------------------------
 | 
				
			||||||
 | 
					The original vhost-user specification only demands replies for certain
 | 
				
			||||||
 | 
					commands. This differs from the vhost protocol implementation where commands
 | 
				
			||||||
 | 
					are sent over an ioctl() call and block until the client has completed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With this protocol extension negotiated, the sender (QEMU) can set the
 | 
				
			||||||
 | 
					"need_reply" [Bit 3] flag to any command. This indicates that
 | 
				
			||||||
 | 
					the client MUST respond with a Payload VhostUserMsg indicating success or
 | 
				
			||||||
 | 
					failure. The payload should be set to zero on success or non-zero on failure,
 | 
				
			||||||
 | 
					unless the message already has an explicit reply body.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The response payload gives QEMU a deterministic indication of the result
 | 
				
			||||||
 | 
					of the command. Today, QEMU is expected to terminate the main vhost-user
 | 
				
			||||||
 | 
					loop upon receiving such errors. In future, qemu could be taught to be more
 | 
				
			||||||
 | 
					resilient for selective requests.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the message types that already solicit a reply from the client, the
 | 
				
			||||||
 | 
					presence of VHOST_USER_PROTOCOL_F_REPLY_ACK or need_reply bit being set brings
 | 
				
			||||||
 | 
					no behavioural change. (See the 'Communication' section for details.)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ enum VhostUserProtocolFeature {
 | 
				
			||||||
    VHOST_USER_PROTOCOL_F_MQ = 0,
 | 
					    VHOST_USER_PROTOCOL_F_MQ = 0,
 | 
				
			||||||
    VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
 | 
					    VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
 | 
				
			||||||
    VHOST_USER_PROTOCOL_F_RARP = 2,
 | 
					    VHOST_USER_PROTOCOL_F_RARP = 2,
 | 
				
			||||||
 | 
					    VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    VHOST_USER_PROTOCOL_F_MAX
 | 
					    VHOST_USER_PROTOCOL_F_MAX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -84,6 +85,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_MASK  (0x1 << 3)
 | 
				
			||||||
    uint32_t flags;
 | 
					    uint32_t flags;
 | 
				
			||||||
    uint32_t size; /* the following payload size */
 | 
					    uint32_t size; /* the following payload size */
 | 
				
			||||||
    union {
 | 
					    union {
 | 
				
			||||||
| 
						 | 
					@ -158,6 +160,25 @@ fail:
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int process_message_reply(struct vhost_dev *dev,
 | 
				
			||||||
 | 
					                                 VhostUserRequest request)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    VhostUserMsg msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vhost_user_read(dev, &msg) < 0) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (msg.request != request) {
 | 
				
			||||||
 | 
					        error_report("Received unexpected msg type."
 | 
				
			||||||
 | 
					                     "Expected %d received %d",
 | 
				
			||||||
 | 
					                     request, msg.request);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return msg.payload.u64 ? -1 : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool vhost_user_one_time_request(VhostUserRequest request)
 | 
					static bool vhost_user_one_time_request(VhostUserRequest request)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (request) {
 | 
					    switch (request) {
 | 
				
			||||||
| 
						 | 
					@ -248,11 +269,18 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
 | 
				
			||||||
    int fds[VHOST_MEMORY_MAX_NREGIONS];
 | 
					    int fds[VHOST_MEMORY_MAX_NREGIONS];
 | 
				
			||||||
    int i, fd;
 | 
					    int i, fd;
 | 
				
			||||||
    size_t fd_num = 0;
 | 
					    size_t fd_num = 0;
 | 
				
			||||||
 | 
					    bool reply_supported = virtio_has_feature(dev->protocol_features,
 | 
				
			||||||
 | 
					                                              VHOST_USER_PROTOCOL_F_REPLY_ACK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    VhostUserMsg msg = {
 | 
					    VhostUserMsg msg = {
 | 
				
			||||||
        .request = VHOST_USER_SET_MEM_TABLE,
 | 
					        .request = VHOST_USER_SET_MEM_TABLE,
 | 
				
			||||||
        .flags = VHOST_USER_VERSION,
 | 
					        .flags = VHOST_USER_VERSION,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (reply_supported) {
 | 
				
			||||||
 | 
					        msg.flags |= VHOST_USER_NEED_REPLY_MASK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < dev->mem->nregions; ++i) {
 | 
					    for (i = 0; i < dev->mem->nregions; ++i) {
 | 
				
			||||||
        struct vhost_memory_region *reg = dev->mem->regions + i;
 | 
					        struct vhost_memory_region *reg = dev->mem->regions + i;
 | 
				
			||||||
        ram_addr_t offset;
 | 
					        ram_addr_t offset;
 | 
				
			||||||
| 
						 | 
					@ -288,6 +316,10 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (reply_supported) {
 | 
				
			||||||
 | 
					        return process_message_reply(dev, msg.request);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue