From 5d9f3c3f48f725da0ad5a37f8e6c62c28b045efd Mon Sep 17 00:00:00 2001 From: Michael Baum Date: Thu, 1 Oct 2020 14:09:22 +0000 Subject: [PATCH] net/mlx5: separate Tx queue object modification Separate Tx object modification to the Verbs and DevX modules. Signed-off-by: Michael Baum Acked-by: Matan Azrad --- drivers/net/mlx5/linux/mlx5_os.c | 7 ++ drivers/net/mlx5/linux/mlx5_verbs.c | 65 +++++++++++++++++ drivers/net/mlx5/mlx5.h | 9 +++ drivers/net/mlx5/mlx5_devx.c | 57 +++++++++++++++ drivers/net/mlx5/mlx5_rxtx.c | 78 ++------------------- drivers/net/mlx5/mlx5_txq.c | 104 +++------------------------- 6 files changed, 152 insertions(+), 168 deletions(-) diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index 0db2b5a3c7..487714f847 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -1375,6 +1375,13 @@ err_secondary: ibv_obj_ops.drop_action_create; priv->obj_ops.drop_action_destroy = ibv_obj_ops.drop_action_destroy; +#ifndef HAVE_MLX5DV_DEVX_UAR_OFFSET + priv->obj_ops.txq_obj_modify = ibv_obj_ops.txq_obj_modify; +#else + if (!config->dv_esw_en) + priv->obj_ops.txq_obj_modify = + ibv_obj_ops.txq_obj_modify; +#endif } else { priv->obj_ops = ibv_obj_ops; } diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c index 0476d94846..7d5ea3750c 100644 --- a/drivers/net/mlx5/linux/mlx5_verbs.c +++ b/drivers/net/mlx5/linux/mlx5_verbs.c @@ -112,6 +112,70 @@ mlx5_ibv_modify_wq(struct mlx5_rxq_obj *rxq_obj, bool is_start) return mlx5_glue->modify_wq(rxq_obj->wq, &mod); } +/** + * Modify QP using Verbs API. + * + * @param txq_obj + * Verbs Tx queue object. + * @param type + * Type of change queue state. + * @param dev_port + * IB device port number. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_ibv_modify_qp(struct mlx5_txq_obj *obj, enum mlx5_txq_modify_type type, + uint8_t dev_port) +{ + struct ibv_qp_attr mod = { + .qp_state = IBV_QPS_RESET, + .port_num = dev_port, + }; + int attr_mask = (IBV_QP_STATE | IBV_QP_PORT); + int ret; + + if (type != MLX5_TXQ_MOD_RST2RDY) { + ret = mlx5_glue->modify_qp(obj->qp, &mod, IBV_QP_STATE); + if (ret) { + DRV_LOG(ERR, "Cannot change Tx QP state to RESET %s", + strerror(errno)); + rte_errno = errno; + return ret; + } + if (type == MLX5_TXQ_MOD_RDY2RST) + return 0; + } + if (type == MLX5_TXQ_MOD_ERR2RDY) + attr_mask = IBV_QP_STATE; + mod.qp_state = IBV_QPS_INIT; + ret = mlx5_glue->modify_qp(obj->qp, &mod, attr_mask); + if (ret) { + DRV_LOG(ERR, "Cannot change Tx QP state to INIT %s", + strerror(errno)); + rte_errno = errno; + return ret; + } + mod.qp_state = IBV_QPS_RTR; + ret = mlx5_glue->modify_qp(obj->qp, &mod, IBV_QP_STATE); + if (ret) { + DRV_LOG(ERR, "Cannot change Tx QP state to RTR %s", + strerror(errno)); + rte_errno = errno; + return ret; + } + mod.qp_state = IBV_QPS_RTS; + ret = mlx5_glue->modify_qp(obj->qp, &mod, IBV_QP_STATE); + if (ret) { + DRV_LOG(ERR, "Cannot change Tx QP state to RTS %s", + strerror(errno)); + rte_errno = errno; + return ret; + } + return 0; +} + /** * Create a CQ Verbs object. * @@ -1043,5 +1107,6 @@ struct mlx5_obj_ops ibv_obj_ops = { .drop_action_create = mlx5_ibv_drop_action_create, .drop_action_destroy = mlx5_ibv_drop_action_destroy, .txq_obj_new = mlx5_txq_ibv_obj_new, + .txq_obj_modify = mlx5_ibv_modify_qp, .txq_obj_release = mlx5_txq_ibv_obj_release, }; diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 3093f6e979..7cbb09bcda 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -774,6 +774,13 @@ struct mlx5_txq_obj { }; }; +enum mlx5_txq_modify_type { + MLX5_TXQ_MOD_RDY2RDY, /* modify state from ready to ready. */ + MLX5_TXQ_MOD_RST2RDY, /* modify state from reset to ready. */ + MLX5_TXQ_MOD_RDY2RST, /* modify state from ready to reset. */ + MLX5_TXQ_MOD_ERR2RDY, /* modify state from error to ready. */ +}; + /* HW objects operations structure. */ struct mlx5_obj_ops { int (*rxq_obj_modify_vlan_strip)(struct mlx5_rxq_obj *rxq_obj, int on); @@ -790,6 +797,8 @@ struct mlx5_obj_ops { int (*drop_action_create)(struct rte_eth_dev *dev); void (*drop_action_destroy)(struct rte_eth_dev *dev); int (*txq_obj_new)(struct rte_eth_dev *dev, uint16_t idx); + int (*txq_obj_modify)(struct mlx5_txq_obj *obj, + enum mlx5_txq_modify_type type, uint8_t dev_port); void (*txq_obj_release)(struct mlx5_txq_obj *txq_obj); }; diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c index 55fe946ef7..7404a15b7e 100644 --- a/drivers/net/mlx5/mlx5_devx.c +++ b/drivers/net/mlx5/mlx5_devx.c @@ -72,6 +72,62 @@ mlx5_devx_modify_rq(struct mlx5_rxq_obj *rxq_obj, bool is_start) return mlx5_devx_cmd_modify_rq(rxq_obj->rq, &rq_attr); } +/** + * Modify SQ using DevX API. + * + * @param txq_obj + * DevX Tx queue object. + * @param type + * Type of change queue state. + * @param dev_port + * Unnecessary. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_devx_modify_sq(struct mlx5_txq_obj *obj, enum mlx5_txq_modify_type type, + uint8_t dev_port) +{ + struct mlx5_devx_modify_sq_attr msq_attr = { 0 }; + int ret; + + if (type != MLX5_TXQ_MOD_RST2RDY) { + /* Change queue state to reset. */ + if (type == MLX5_TXQ_MOD_ERR2RDY) + msq_attr.sq_state = MLX5_SQC_STATE_ERR; + else + msq_attr.sq_state = MLX5_SQC_STATE_RDY; + msq_attr.state = MLX5_SQC_STATE_RST; + ret = mlx5_devx_cmd_modify_sq(obj->sq_devx, &msq_attr); + if (ret) { + DRV_LOG(ERR, "Cannot change the Tx SQ state to RESET" + " %s", strerror(errno)); + rte_errno = errno; + return ret; + } + } + if (type != MLX5_TXQ_MOD_RDY2RST) { + /* Change queue state to ready. */ + msq_attr.sq_state = MLX5_SQC_STATE_RST; + msq_attr.state = MLX5_SQC_STATE_RDY; + ret = mlx5_devx_cmd_modify_sq(obj->sq_devx, &msq_attr); + if (ret) { + DRV_LOG(ERR, "Cannot change the Tx SQ state to READY" + " %s", strerror(errno)); + rte_errno = errno; + return ret; + } + } + /* + * The dev_port variable is relevant only in Verbs API, and there is a + * pointer that points to this function and a parallel function in verbs + * intermittently, so they should have the same parameters. + */ + (void)dev_port; + return 0; +} + /** * Release the resources allocated for an RQ DevX object. * @@ -1298,5 +1354,6 @@ struct mlx5_obj_ops devx_obj_ops = { .drop_action_create = mlx5_devx_drop_action_create, .drop_action_destroy = mlx5_devx_drop_action_destroy, .txq_obj_new = mlx5_txq_devx_obj_new, + .txq_obj_modify = mlx5_devx_modify_sq, .txq_obj_release = mlx5_txq_devx_obj_release, }; diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index 2422a4d6ca..1d92b544c1 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -933,79 +933,11 @@ mlx5_queue_state_modify_primary(struct rte_eth_dev *dev, struct mlx5_txq_ctrl *txq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq); - if (txq_ctrl->obj->type == MLX5_TXQ_OBJ_TYPE_DEVX_SQ) { - struct mlx5_devx_modify_sq_attr msq_attr = { 0 }; - - /* Change queue state to reset. */ - msq_attr.sq_state = MLX5_SQC_STATE_ERR; - msq_attr.state = MLX5_SQC_STATE_RST; - ret = mlx5_devx_cmd_modify_sq(txq_ctrl->obj->sq_devx, - &msq_attr); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to RESET %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - /* Change queue state to ready. */ - msq_attr.sq_state = MLX5_SQC_STATE_RST; - msq_attr.state = MLX5_SQC_STATE_RDY; - ret = mlx5_devx_cmd_modify_sq(txq_ctrl->obj->sq_devx, - &msq_attr); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to READY %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - } else { - struct ibv_qp_attr mod = { - .qp_state = IBV_QPS_RESET, - .port_num = (uint8_t)priv->dev_port, - }; - struct ibv_qp *qp = txq_ctrl->obj->qp; - - MLX5_ASSERT - (txq_ctrl->obj->type == MLX5_TXQ_OBJ_TYPE_IBV); - - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to RESET %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - mod.qp_state = IBV_QPS_INIT; - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to INIT %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - mod.qp_state = IBV_QPS_RTR; - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to RTR %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - mod.qp_state = IBV_QPS_RTS; - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to RTS %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - } + ret = priv->obj_ops.txq_obj_modify(txq_ctrl->obj, + MLX5_TXQ_MOD_ERR2RDY, + (uint8_t)priv->dev_port); + if (ret) + return ret; } return 0; } diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index 23213d9c77..c31e446282 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -182,37 +182,10 @@ mlx5_tx_queue_stop_primary(struct rte_eth_dev *dev, uint16_t idx) MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); /* Move QP to RESET state. */ - if (txq_ctrl->obj->type == MLX5_TXQ_OBJ_TYPE_DEVX_SQ) { - struct mlx5_devx_modify_sq_attr msq_attr = { 0 }; - - /* Change queue state to reset with DevX. */ - msq_attr.sq_state = MLX5_SQC_STATE_RDY; - msq_attr.state = MLX5_SQC_STATE_RST; - ret = mlx5_devx_cmd_modify_sq(txq_ctrl->obj->sq_devx, - &msq_attr); - if (ret) { - DRV_LOG(ERR, "Cannot change the " - "Tx QP state to RESET %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - } else { - struct ibv_qp_attr mod = { - .qp_state = IBV_QPS_RESET, - .port_num = (uint8_t)priv->dev_port, - }; - struct ibv_qp *qp = txq_ctrl->obj->qp; - - /* Change queue state to reset with Verbs. */ - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change the Tx QP state to RESET " - "%s", strerror(errno)); - rte_errno = errno; - return ret; - } - } + ret = priv->obj_ops.txq_obj_modify(txq_ctrl->obj, MLX5_TXQ_MOD_RDY2RST, + (uint8_t)priv->dev_port); + if (ret) + return ret; /* Handle all send completions. */ txq_sync_cq(txq); /* Free elts stored in the SQ. */ @@ -281,70 +254,11 @@ mlx5_tx_queue_start_primary(struct rte_eth_dev *dev, uint16_t idx) int ret; MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); - if (txq_ctrl->obj->type == MLX5_TXQ_OBJ_TYPE_DEVX_SQ) { - struct mlx5_devx_modify_sq_attr msq_attr = { 0 }; - struct mlx5_txq_obj *obj = txq_ctrl->obj; - - msq_attr.sq_state = MLX5_SQC_STATE_RDY; - msq_attr.state = MLX5_SQC_STATE_RST; - ret = mlx5_devx_cmd_modify_sq(obj->sq_devx, &msq_attr); - if (ret) { - rte_errno = errno; - DRV_LOG(ERR, - "Cannot change the Tx QP state to RESET " - "%s", strerror(errno)); - return ret; - } - msq_attr.sq_state = MLX5_SQC_STATE_RST; - msq_attr.state = MLX5_SQC_STATE_RDY; - ret = mlx5_devx_cmd_modify_sq(obj->sq_devx, &msq_attr); - if (ret) { - rte_errno = errno; - DRV_LOG(ERR, - "Cannot change the Tx QP state to READY " - "%s", strerror(errno)); - return ret; - } - } else { - struct ibv_qp_attr mod = { - .qp_state = IBV_QPS_RESET, - .port_num = (uint8_t)priv->dev_port, - }; - struct ibv_qp *qp = txq_ctrl->obj->qp; - - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change the Tx QP state to RESET " - "%s", strerror(errno)); - rte_errno = errno; - return ret; - } - mod.qp_state = IBV_QPS_INIT; - ret = mlx5_glue->modify_qp(qp, &mod, - (IBV_QP_STATE | IBV_QP_PORT)); - if (ret) { - DRV_LOG(ERR, "Cannot change Tx QP state to INIT %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - mod.qp_state = IBV_QPS_RTR; - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change Tx QP state to RTR %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - mod.qp_state = IBV_QPS_RTS; - ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE); - if (ret) { - DRV_LOG(ERR, "Cannot change Tx QP state to RTS %s", - strerror(errno)); - rte_errno = errno; - return ret; - } - } + ret = priv->obj_ops.txq_obj_modify(txq_ctrl->obj, + MLX5_TXQ_MOD_RDY2RDY, + (uint8_t)priv->dev_port); + if (ret) + return ret; txq_ctrl->txq.wqe_ci = 0; txq_ctrl->txq.wqe_pi = 0; txq_ctrl->txq.elts_comp = 0; -- 2.20.1