[PATCH v3 5/8] net/iavf: refactor sending virtchnl messages

Anatoly Burakov anatoly.burakov at intel.com
Fri Mar 6 11:58:21 CET 2026


Currently, there is a certain amount of duplication and unnecessary
branching in the virtchnl message handling function which makes it
difficult to read and reason about.

Refactor the function to achieve the following:

- clean and explicit distinction between synchronous and asynchronous ops
- common looping and error handling logic
- fewer and clearer special cases

Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
 drivers/net/intel/iavf/iavf_vchnl.c | 151 +++++++++++++---------------
 1 file changed, 70 insertions(+), 81 deletions(-)

diff --git a/drivers/net/intel/iavf/iavf_vchnl.c b/drivers/net/intel/iavf/iavf_vchnl.c
index d240745f5c..3f6ce0dd89 100644
--- a/drivers/net/intel/iavf/iavf_vchnl.c
+++ b/drivers/net/intel/iavf/iavf_vchnl.c
@@ -361,16 +361,66 @@ iavf_get_cmd_resp_count(enum virtchnl_ops op)
 	}
 }
 
+static int
+iavf_op_needs_poll(struct iavf_info *vf)
+{
+	/* Poll if interrupts disabled or we are in interrupt thread */
+	return !vf->aq_intr_enabled || rte_thread_is_intr();
+}
+
+static int
+iavf_wait_for_msg(struct iavf_adapter *adapter, struct iavf_cmd_info *args,
+		bool poll)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+	int err = 0;
+	int i = 0;
+
+	if (args->out_buffer == NULL) {
+		PMD_DRV_LOG(ERR, "Invalid buffer for cmd %d response", args->ops);
+		return -EINVAL;
+	}
+
+	/* Wait for command completion */
+	do {
+		if (poll) {
+			enum iavf_aq_result result;
+			result = iavf_read_msg_from_pf(adapter, args->out_size,
+					args->out_buffer);
+			if (result == IAVF_MSG_CMD)
+				break;
+		} else {
+			/* check if interrupt thread has erased pending cmd */
+			if (vf->pend_cmd == VIRTCHNL_OP_UNKNOWN)
+				break;
+		}
+		iavf_msec_delay(ASQ_DELAY_MS);
+	} while (i++ < MAX_TRY_TIMES);
+
+	if (i >= MAX_TRY_TIMES) {
+		PMD_DRV_LOG(ERR, "No response for cmd %d", args->ops);
+		err = -EIO;
+	} else if (vf->cmd_retval == VIRTCHNL_STATUS_ERR_NOT_SUPPORTED) {
+		PMD_DRV_LOG(ERR, "Cmd %d not supported", args->ops);
+		err = -ENOTSUP;
+	} else if (vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Return failure %d for cmd %d",
+				vf->cmd_retval, args->ops);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
 static int
 iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args)
 {
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
-	enum iavf_aq_result result;
-	enum iavf_status ret;
+	enum iavf_status status;
 	uint32_t resp_count;
-	int err = 0;
-	int i = 0;
+	bool poll = iavf_op_needs_poll(vf);
+	int err;
 
 	if (vf->vf_reset)
 		return -EIO;
@@ -385,89 +435,28 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args)
 	if (iavf_set_pending_cmd(vf, args->ops, RTE_MAX(1U, resp_count)))
 		return -1;
 
-	ret = iavf_aq_send_msg_to_pf(hw, args->ops, IAVF_SUCCESS,
-				    args->in_args, args->in_args_size, NULL);
-	if (ret) {
+	status = iavf_aq_send_msg_to_pf(hw, args->ops, IAVF_SUCCESS,
+			args->in_args, args->in_args_size, NULL);
+	if (status != IAVF_SUCCESS) {
 		PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops);
-		iavf_clear_pending_cmd(vf);
-		return err;
+		err = (int)status;
+		goto clear_cmd;
+	} else if (resp_count == 0) {
+		/* we're not waiting on responses */
+		err = 0;
+		goto clear_cmd;
 	}
 
-	if (resp_count == 0) {
-		/* reset pending commands, counter will be overwritten on reset */
-		iavf_clear_pending_cmd(vf);
-		return 0;
-	}
-
-	switch (args->ops) {
-	case VIRTCHNL_OP_VERSION:
-	case VIRTCHNL_OP_GET_VF_RESOURCES:
-	case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
-	case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS:
-		/* for init virtchnl ops, need to poll the response */
-		do {
-			result = iavf_read_msg_from_pf(adapter, args->out_size,
-						   args->out_buffer);
-			if (result == IAVF_MSG_CMD)
-				break;
-			iavf_msec_delay(ASQ_DELAY_MS);
-		} while (i++ < MAX_TRY_TIMES);
-		if (i >= MAX_TRY_TIMES ||
-		    vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
-			err = -1;
-			PMD_DRV_LOG(ERR, "No response or return failure (%d)"
-				    " for cmd %d", vf->cmd_retval, args->ops);
-		}
-		iavf_clear_pending_cmd(vf);
-		break;
-	default:
-		if (rte_thread_is_intr()) {
-			/* For virtchnl ops were executed in eal_intr_thread,
-			 * need to poll the response.
-			 */
-			do {
-				result = iavf_read_msg_from_pf(adapter, args->out_size,
-							args->out_buffer);
-				if (result == IAVF_MSG_CMD)
-					break;
-				iavf_msec_delay(ASQ_DELAY_MS);
-			} while (i++ < MAX_TRY_TIMES);
-			if (i >= MAX_TRY_TIMES ||
-				vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
-				err = -1;
-				PMD_DRV_LOG(ERR, "No response or return failure (%d)"
-						" for cmd %d", vf->cmd_retval, args->ops);
-			}
-			iavf_clear_pending_cmd(vf);
-		} else {
-			/* For other virtchnl ops in running time,
-			 * wait for the cmd done flag.
-			 */
-			do {
-				if (vf->pend_cmd == VIRTCHNL_OP_UNKNOWN)
-					break;
-				iavf_msec_delay(ASQ_DELAY_MS);
-				/* If don't read msg or read sys event, continue */
-			} while (i++ < MAX_TRY_TIMES);
+	err = iavf_wait_for_msg(adapter, args, poll);
 
-			if (i >= MAX_TRY_TIMES) {
-				PMD_DRV_LOG(ERR, "No response for cmd %d", args->ops);
-				iavf_clear_pending_cmd(vf);
-				err = -EIO;
-			} else if (vf->cmd_retval ==
-				VIRTCHNL_STATUS_ERR_NOT_SUPPORTED) {
-				PMD_DRV_LOG(ERR, "Cmd %d not supported", args->ops);
-				err = -ENOTSUP;
-			} else if (vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
-				PMD_DRV_LOG(ERR, "Return failure %d for cmd %d",
-						vf->cmd_retval, args->ops);
-				err = -EINVAL;
-			}
-		}
-		break;
-	}
+	/* in interrupt success case, pending cmd is cleared by intr thread */
+	if (err != 0 || poll)
+		goto clear_cmd;
 
 	return err;
+clear_cmd:
+	iavf_clear_pending_cmd(vf);
+	return err;
 }
 
 static int
-- 
2.47.3



More information about the dev mailing list