RTE_VHOST_MSG_RESULT_OK = 0,
/* Message handling successful and reply prepared */
RTE_VHOST_MSG_RESULT_REPLY = 1,
+ /* Message not handled */
+ RTE_VHOST_MSG_RESULT_NOT_HANDLED,
};
/**
- * Function prototype for the vhost backend to handler specific vhost user
- * messages prior to the master message handling
+ * Function prototype for the vhost backend to handle specific vhost user
+ * messages.
*
* @param vid
* vhost device id
* @param msg
* Message pointer.
- * @param skip_master
- * If the handler requires skipping the master message handling, this variable
- * shall be written 1, otherwise 0.
* @return
- * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
- * VH_RESULT_ERR on failure
+ * RTE_VHOST_MSG_RESULT_OK on success,
+ * RTE_VHOST_MSG_RESULT_REPLY on success with reply,
+ * RTE_VHOST_MSG_RESULT_ERR on failure,
+ * RTE_VHOST_MSG_RESULT_NOT_HANDLED if message was not handled.
*/
-typedef enum rte_vhost_msg_result (*rte_vhost_msg_pre_handle)(int vid,
- void *msg, uint32_t *skip_master);
-
-/**
- * Function prototype for the vhost backend to handler specific vhost user
- * messages after the master message handling is done
- *
- * @param vid
- * vhost device id
- * @param msg
- * Message pointer.
- * @return
- * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
- * VH_RESULT_ERR on failure
- */
-typedef enum rte_vhost_msg_result (*rte_vhost_msg_post_handle)(int vid,
- void *msg);
+typedef enum rte_vhost_msg_result (*rte_vhost_msg_handle)(int vid, void *msg);
/**
* Optional vhost user message handlers.
*/
struct rte_vhost_user_extern_ops {
- rte_vhost_msg_pre_handle pre_msg_handle;
- rte_vhost_msg_post_handle post_msg_handle;
+ /* Called prior to the master message handling. */
+ rte_vhost_msg_handle pre_msg_handle;
+ /* Called after the master message handling. */
+ rte_vhost_msg_handle post_msg_handle;
};
/**
int did = -1;
int ret;
int unlock_required = 0;
- uint32_t skip_master = 0;
+ bool handled;
int request;
dev = get_device(vid);
}
ret = read_vhost_message(fd, &msg);
- if (ret <= 0 || msg.request.master >= VHOST_USER_MAX) {
+ if (ret <= 0) {
if (ret < 0)
RTE_LOG(ERR, VHOST_CONFIG,
"vhost read message failed\n");
- else if (ret == 0)
+ else
RTE_LOG(INFO, VHOST_CONFIG,
"vhost peer closed\n");
- else
- RTE_LOG(ERR, VHOST_CONFIG,
- "vhost read incorrect message\n");
return -1;
}
ret = 0;
- if (msg.request.master != VHOST_USER_IOTLB_MSG)
- RTE_LOG(INFO, VHOST_CONFIG, "read message %s\n",
- vhost_message_str[msg.request.master]);
- else
- RTE_LOG(DEBUG, VHOST_CONFIG, "read message %s\n",
- vhost_message_str[msg.request.master]);
+ request = msg.request.master;
+ if (request > VHOST_USER_NONE && request < VHOST_USER_MAX &&
+ vhost_message_str[request]) {
+ if (request != VHOST_USER_IOTLB_MSG)
+ RTE_LOG(INFO, VHOST_CONFIG, "read message %s\n",
+ vhost_message_str[request]);
+ else
+ RTE_LOG(DEBUG, VHOST_CONFIG, "read message %s\n",
+ vhost_message_str[request]);
+ } else {
+ RTE_LOG(DEBUG, VHOST_CONFIG, "External request %d\n", request);
+ }
ret = vhost_user_check_and_alloc_queue_pair(dev, &msg);
if (ret < 0) {
* inactive, so it is safe. Otherwise taking the access_lock
* would cause a dead lock.
*/
- switch (msg.request.master) {
+ switch (request) {
case VHOST_USER_SET_FEATURES:
case VHOST_USER_SET_PROTOCOL_FEATURES:
case VHOST_USER_SET_OWNER:
}
+ handled = false;
if (dev->extern_ops.pre_msg_handle) {
ret = (*dev->extern_ops.pre_msg_handle)(dev->vid,
- (void *)&msg, &skip_master);
- if (ret == RTE_VHOST_MSG_RESULT_ERR)
- goto skip_to_reply;
- else if (ret == RTE_VHOST_MSG_RESULT_REPLY)
+ (void *)&msg);
+ switch (ret) {
+ case RTE_VHOST_MSG_RESULT_REPLY:
send_vhost_reply(fd, &msg);
-
- if (skip_master)
+ /* Fall-through */
+ case RTE_VHOST_MSG_RESULT_ERR:
+ case RTE_VHOST_MSG_RESULT_OK:
+ handled = true;
goto skip_to_post_handle;
+ case RTE_VHOST_MSG_RESULT_NOT_HANDLED:
+ default:
+ break;
+ }
}
- request = msg.request.master;
if (request > VHOST_USER_NONE && request < VHOST_USER_MAX) {
if (!vhost_message_handlers[request])
goto skip_to_post_handle;
RTE_LOG(ERR, VHOST_CONFIG,
"Processing %s failed.\n",
vhost_message_str[request]);
+ handled = true;
break;
case RTE_VHOST_MSG_RESULT_OK:
RTE_LOG(DEBUG, VHOST_CONFIG,
"Processing %s succeeded.\n",
vhost_message_str[request]);
+ handled = true;
break;
case RTE_VHOST_MSG_RESULT_REPLY:
RTE_LOG(DEBUG, VHOST_CONFIG,
"Processing %s succeeded and needs reply.\n",
vhost_message_str[request]);
send_vhost_reply(fd, &msg);
+ handled = true;
+ break;
+ default:
break;
}
- } else {
- RTE_LOG(ERR, VHOST_CONFIG,
- "Requested invalid message type %d.\n", request);
- ret = RTE_VHOST_MSG_RESULT_ERR;
}
skip_to_post_handle:
if (ret != RTE_VHOST_MSG_RESULT_ERR &&
dev->extern_ops.post_msg_handle) {
- ret = (*dev->extern_ops.post_msg_handle)(
- dev->vid, (void *)&msg);
- if (ret == RTE_VHOST_MSG_RESULT_ERR)
- goto skip_to_reply;
- else if (ret == RTE_VHOST_MSG_RESULT_REPLY)
+ ret = (*dev->extern_ops.post_msg_handle)(dev->vid,
+ (void *)&msg);
+ switch (ret) {
+ case RTE_VHOST_MSG_RESULT_REPLY:
send_vhost_reply(fd, &msg);
+ /* Fall-through */
+ case RTE_VHOST_MSG_RESULT_ERR:
+ case RTE_VHOST_MSG_RESULT_OK:
+ handled = true;
+ case RTE_VHOST_MSG_RESULT_NOT_HANDLED:
+ default:
+ break;
+ }
}
-skip_to_reply:
if (unlock_required)
vhost_user_unlock_all_queue_pairs(dev);
+ /* If message was not handled at this stage, treat it as an error */
+ if (!handled) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "vhost message (req: %d) was not handled.\n", request);
+ ret = RTE_VHOST_MSG_RESULT_ERR;
+ }
+
/*
* If the request required a reply that was already sent,
* this optional reply-ack won't be sent as the