X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fmlx5%2Fmlx5_txq.c;h=0f30a5d529167b87d394c04aac9ff8228437ff81;hb=1be514fbcea9e8964296b46c91dbb56715503ae7;hp=c1d36c329c425d0a8dc5bd4c0d71dbd754e3c7c2;hpb=86d259cec852ef8735bd1fc459d328e607d7d7e8;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index c1d36c329c..0f30a5d529 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -16,8 +16,6 @@ #include #include -#include -#include #include #include #include @@ -182,37 +180,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 +252,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_RST2RDY, + (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; @@ -509,15 +421,35 @@ mlx5_tx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx, res = mlx5_tx_queue_pre_setup(dev, idx, &desc); if (res) return res; - if (hairpin_conf->peer_count != 1 || - hairpin_conf->peers[0].port != dev->data->port_id || - hairpin_conf->peers[0].queue >= priv->rxqs_n) { - DRV_LOG(ERR, "port %u unable to setup hairpin queue index %u " - " invalid hairpind configuration", dev->data->port_id, - idx); + if (hairpin_conf->peer_count != 1) { rte_errno = EINVAL; + DRV_LOG(ERR, "port %u unable to setup Tx hairpin queue index %u" + " peer count is %u", dev->data->port_id, + idx, hairpin_conf->peer_count); return -rte_errno; } + if (hairpin_conf->peers[0].port == dev->data->port_id) { + if (hairpin_conf->peers[0].queue >= priv->rxqs_n) { + rte_errno = EINVAL; + DRV_LOG(ERR, "port %u unable to setup Tx hairpin queue" + " index %u, Rx %u is larger than %u", + dev->data->port_id, idx, + hairpin_conf->peers[0].queue, priv->txqs_n); + return -rte_errno; + } + } else { + if (hairpin_conf->manual_bind == 0 || + hairpin_conf->tx_explicit == 0) { + rte_errno = EINVAL; + DRV_LOG(ERR, "port %u unable to setup Tx hairpin queue" + " index %u peer port %u with attributes %u %u", + dev->data->port_id, idx, + hairpin_conf->peers[0].port, + hairpin_conf->manual_bind, + hairpin_conf->tx_explicit); + return -rte_errno; + } + } txq_ctrl = mlx5_txq_hairpin_new(dev, idx, desc, hairpin_conf); if (!txq_ctrl) { DRV_LOG(ERR, "port %u unable to allocate queue index %u", @@ -1209,7 +1141,7 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, rte_errno = ENOMEM; goto error; } - rte_atomic32_inc(&tmpl->refcnt); + __atomic_fetch_add(&tmpl->refcnt, 1, __ATOMIC_RELAXED); tmpl->type = MLX5_TXQ_TYPE_STANDARD; LIST_INSERT_HEAD(&priv->txqsctrl, tmpl, next); return tmpl; @@ -1253,7 +1185,7 @@ mlx5_txq_hairpin_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, tmpl->txq.idx = idx; tmpl->hairpin_conf = *hairpin_conf; tmpl->type = MLX5_TXQ_TYPE_HAIRPIN; - rte_atomic32_inc(&tmpl->refcnt); + __atomic_fetch_add(&tmpl->refcnt, 1, __ATOMIC_RELAXED); LIST_INSERT_HEAD(&priv->txqsctrl, tmpl, next); return tmpl; } @@ -1278,7 +1210,7 @@ mlx5_txq_get(struct rte_eth_dev *dev, uint16_t idx) if (txq_data) { ctrl = container_of(txq_data, struct mlx5_txq_ctrl, txq); - rte_atomic32_inc(&ctrl->refcnt); + __atomic_fetch_add(&ctrl->refcnt, 1, __ATOMIC_RELAXED); } return ctrl; } @@ -1298,23 +1230,34 @@ int mlx5_txq_release(struct rte_eth_dev *dev, uint16_t idx) { struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_txq_ctrl *txq; + struct mlx5_txq_ctrl *txq_ctrl; if (!(*priv->txqs)[idx]) return 0; - txq = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq); - if (!rte_atomic32_dec_and_test(&txq->refcnt)) + txq_ctrl = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq); + if (__atomic_sub_fetch(&txq_ctrl->refcnt, 1, __ATOMIC_RELAXED) != 0) return 1; - if (txq->obj) { - priv->obj_ops.txq_obj_release(txq->obj); - txq->obj = NULL; + if (txq_ctrl->obj) { + priv->obj_ops.txq_obj_release(txq_ctrl->obj); + LIST_REMOVE(txq_ctrl->obj, next); + mlx5_free(txq_ctrl->obj); + txq_ctrl->obj = NULL; + } + if (txq_ctrl->type == MLX5_TXQ_TYPE_STANDARD) { + if (txq_ctrl->txq.fcqs) { + mlx5_free(txq_ctrl->txq.fcqs); + txq_ctrl->txq.fcqs = NULL; + } + txq_free_elts(txq_ctrl); } - txq_free_elts(txq); - mlx5_mr_btree_free(&txq->txq.mr_ctrl.cache_bh); - LIST_REMOVE(txq, next); - mlx5_free(txq); - (*priv->txqs)[idx] = NULL; dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED; + if (!__atomic_load_n(&txq_ctrl->refcnt, __ATOMIC_RELAXED)) { + if (txq_ctrl->type == MLX5_TXQ_TYPE_STANDARD) + mlx5_mr_btree_free(&txq_ctrl->txq.mr_ctrl.cache_bh); + LIST_REMOVE(txq_ctrl, next); + mlx5_free(txq_ctrl); + (*priv->txqs)[idx] = NULL; + } return 0; } @@ -1338,7 +1281,7 @@ mlx5_txq_releasable(struct rte_eth_dev *dev, uint16_t idx) if (!(*priv->txqs)[idx]) return -1; txq = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq); - return (rte_atomic32_read(&txq->refcnt) == 1); + return (__atomic_load_n(&txq->refcnt, __ATOMIC_RELAXED) == 1); } /** @@ -1385,7 +1328,7 @@ mlx5_txq_dynf_timestamp_set(struct rte_eth_dev *dev) (RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME, NULL); off = rte_mbuf_dynfield_lookup (RTE_MBUF_DYNFIELD_TIMESTAMP_NAME, NULL); - if (nbit > 0 && off >= 0 && sh->txpp.refcnt) + if (nbit >= 0 && off >= 0 && sh->txpp.refcnt) mask = 1ULL << nbit; for (i = 0; i != priv->txqs_n; ++i) { data = (*priv->txqs)[i];