Hi Chenbo On 6/16/20 6:29 AM, Xia, Chenbo wrote: > Hi Maxime, > >> -----Original Message----- >> From: dev <dev-boun...@dpdk.org> On Behalf Of Maxime Coquelin >> Sent: Thursday, May 14, 2020 4:02 PM >> To: Ye, Xiaolong <xiaolong...@intel.com>; shah...@mellanox.com; >> ma...@mellanox.com; amore...@redhat.com; Wang, Xiao W >> <xiao.w.w...@intel.com>; viachesl...@mellanox.com; dev@dpdk.org >> Cc: jasow...@redhat.com; l...@redhat.com; Maxime Coquelin >> <maxime.coque...@redhat.com> >> Subject: [dpdk-dev] [PATCH 6/9] vhost: add support for virtio status >> >> This patch adds support to the new Virtio device status Vhost-user protocol >> feature. >> >> Getting such information in the backend helps to know when the driver is done >> with the device configuration and so makes the initialization phase more >> robust. >> >> Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com> >> --- >> lib/librte_vhost/rte_vhost.h | 4 ++++ >> lib/librte_vhost/vhost.h | 9 ++++++++ >> lib/librte_vhost/vhost_user.c | 40 +++++++++++++++++++++++++++++++++++ >> lib/librte_vhost/vhost_user.h | 6 ++++-- >> 4 files changed, 57 insertions(+), 2 deletions(-) >> >> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h >> index >> 5c72fba797..b4b7aa1928 100644 >> --- a/lib/librte_vhost/rte_vhost.h >> +++ b/lib/librte_vhost/rte_vhost.h >> @@ -85,6 +85,10 @@ extern "C" { >> #define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12 #endif >> >> +#ifndef VHOST_USER_PROTOCOL_F_STATUS >> +#define VHOST_USER_PROTOCOL_F_STATUS 15 #endif >> + >> /** Indicate whether protocol features negotiation is supported. */ #ifndef >> VHOST_USER_F_PROTOCOL_FEATURES >> #define VHOST_USER_F_PROTOCOL_FEATURES 30 >> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index >> df98d15de6..9a9c0a98f5 100644 >> --- a/lib/librte_vhost/vhost.h >> +++ b/lib/librte_vhost/vhost.h >> @@ -202,6 +202,14 @@ struct vhost_virtqueue { >> TAILQ_HEAD(, vhost_iotlb_entry) iotlb_pending_list; } >> __rte_cache_aligned; >> >> +/* Virtio device status as per Virtio specification */ >> +#define VIRTIO_DEVICE_STATUS_ACK 0x01 >> +#define VIRTIO_DEVICE_STATUS_DRIVER 0x02 >> +#define VIRTIO_DEVICE_STATUS_DRIVER_OK 0x04 >> +#define VIRTIO_DEVICE_STATUS_FEATURES_OK 0x08 >> +#define VIRTIO_DEVICE_STATUS_DEV_NEED_RESET 0x40 >> +#define VIRTIO_DEVICE_STATUS_FAILED 0x80 >> + >> /* Old kernels have no such macros defined */ #ifndef >> VIRTIO_NET_F_GUEST_ANNOUNCE >> #define VIRTIO_NET_F_GUEST_ANNOUNCE 21 @@ -364,6 +372,7 @@ struct >> virtio_net { >> uint64_t log_addr; >> struct rte_ether_addr mac; >> uint16_t mtu; >> + uint8_t status; >> >> struct vhost_device_ops const *notify_ops; >> >> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c >> index >> 4a847f368c..e5a44be58d 100644 >> --- a/lib/librte_vhost/vhost_user.c >> +++ b/lib/librte_vhost/vhost_user.c >> @@ -87,6 +87,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] >> = { >> [VHOST_USER_POSTCOPY_END] = "VHOST_USER_POSTCOPY_END", >> [VHOST_USER_GET_INFLIGHT_FD] = "VHOST_USER_GET_INFLIGHT_FD", >> [VHOST_USER_SET_INFLIGHT_FD] = "VHOST_USER_SET_INFLIGHT_FD", >> + [VHOST_USER_SET_STATUS] = "VHOST_USER_SET_STATUS", >> }; >> >> static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg); @@ >> -1328,6 >> +1329,11 @@ virtio_is_ready(struct virtio_net *dev) >> return 0; >> } >> >> + /* If supported, ensure the frontend is really done with config */ >> + if (dev->protocol_features & (1ULL << >> VHOST_USER_PROTOCOL_F_STATUS)) >> + if (!(dev->status & VIRTIO_DEVICE_STATUS_DRIVER_OK)) >> + return 0; >> + >> dev->flags |= VIRTIO_DEV_READY; >> >> VHOST_LOG_CONFIG(INFO, >> @@ -2425,6 +2431,39 @@ vhost_user_postcopy_end(struct virtio_net **pdev, >> struct VhostUserMsg *msg, >> return RTE_VHOST_MSG_RESULT_REPLY; >> } >> >> +static int >> +vhost_user_set_status(struct virtio_net **pdev, struct VhostUserMsg *msg, >> + int main_fd __rte_unused) >> +{ >> + struct virtio_net *dev = *pdev; >> + >> + /* As per Virtio specification, the device status is 8bits long */ >> + if (msg->payload.u64 > UINT8_MAX) { >> + VHOST_LOG_CONFIG(ERR, "Invalid VHOST_USER_SET_STATUS >> payload 0x%" PRIx64 "\n", >> + msg->payload.u64); >> + return RTE_VHOST_MSG_RESULT_ERR; >> + } >> + >> + dev->status = msg->payload.u64; >> + >> + VHOST_LOG_CONFIG(INFO, "New device status(0x%08x):\n" >> + "\t-ACKNOWLEDGE: %u\n" >> + "\t-DRIVER: %u\n" >> + "\t-FEATURES_OK: %u\n" >> + "\t-DRIVER_OK: %u\n" >> + "\t-DEVICE_NEED_RESET: %u\n" >> + "\t-FAILED: %u\n", >> + dev->status, >> + !!(dev->status & VIRTIO_DEVICE_STATUS_ACK), >> + !!(dev->status & VIRTIO_DEVICE_STATUS_DRIVER), >> + !!(dev->status & >> VIRTIO_DEVICE_STATUS_FEATURES_OK), >> + !!(dev->status & VIRTIO_DEVICE_STATUS_DRIVER_OK), >> + !!(dev->status & >> VIRTIO_DEVICE_STATUS_DEV_NEED_RESET), >> + !!(dev->status & VIRTIO_DEVICE_STATUS_FAILED)); >> + >> + return RTE_VHOST_MSG_RESULT_OK; > > I see in your patch for virtio-user SET_STATUS support > (http://patchwork.dpdk.org/patch/70677/), the > VHOST_USER_SET_STATUS msg may request a reply, but this func does not handle > this case. If we don't > handle here, vhost_user_msg_handler will return RTE_VHOST_MSG_RESULT_ERR > later. So should we > handle the case here? > Why should the reply be handled in this function? After this function is called, vhost_user_msg_handler() should handle the replies in:
if (msg.flags & VHOST_USER_NEED_REPLY) { msg.payload.u64 = ret == RTE_VHOST_MSG_RESULT_ERR; msg.size = sizeof(msg.payload.u64); msg.fd_num = 0; send_vhost_reply(fd, &msg); } else if (ret == RTE_VHOST_MSG_RESULT_ERR) { VHOST_LOG_CONFIG(ERR, "vhost message handling failed.\n"); return -1; } Am I missing something? > Thanks, > Chenbo > >> +} >> + >> typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, >> struct VhostUserMsg *msg, >> int main_fd); >> @@ -2457,6 +2496,7 @@ static vhost_message_handler_t >> vhost_message_handlers[VHOST_USER_MAX] = { >> [VHOST_USER_POSTCOPY_END] = vhost_user_postcopy_end, >> [VHOST_USER_GET_INFLIGHT_FD] = vhost_user_get_inflight_fd, >> [VHOST_USER_SET_INFLIGHT_FD] = vhost_user_set_inflight_fd, >> + [VHOST_USER_SET_STATUS] = vhost_user_set_status, >> }; >> >> /* return bytes# of read on success or negative val on failure. */ diff >> --git >> a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h index >> 1f65efa4a9..74fd361e3a 100644 >> --- a/lib/librte_vhost/vhost_user.h >> +++ b/lib/librte_vhost/vhost_user.h >> @@ -23,7 +23,8 @@ >> (1ULL << >> VHOST_USER_PROTOCOL_F_CRYPTO_SESSION) | \ >> (1ULL << >> VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) | \ >> (1ULL << >> VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) | \ >> - (1ULL << >> VHOST_USER_PROTOCOL_F_PAGEFAULT)) >> + (1ULL << >> VHOST_USER_PROTOCOL_F_PAGEFAULT) | \ >> + (1ULL << >> VHOST_USER_PROTOCOL_F_STATUS)) >> >> typedef enum VhostUserRequest { >> VHOST_USER_NONE = 0, >> @@ -56,7 +57,8 @@ typedef enum VhostUserRequest { >> VHOST_USER_POSTCOPY_END = 30, >> VHOST_USER_GET_INFLIGHT_FD = 31, >> VHOST_USER_SET_INFLIGHT_FD = 32, >> - VHOST_USER_MAX = 33 >> + VHOST_USER_SET_STATUS = 36, >> + VHOST_USER_MAX = 37 >> } VhostUserRequest; >> >> typedef enum VhostUserSlaveRequest { >> -- >> 2.25.4 > -- Adrián Moreno