X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_txq.c;h=21fe16b7ed0ec05c014cedf572b11c45a63d9ac9;hb=8716f9942a408a79a114ac0496e4e7d55bc9944c;hp=4ab6ac1611027d5a6c4eb6814cae73ace7961135;hpb=0febfcce36934d7265d37be818690d0fe8a2e9ec;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index 4ab6ac1611..21fe16b7ed 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -8,30 +8,20 @@ #include #include #include -#include #include -/* Verbs header. */ -/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-Wpedantic" -#endif -#include -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-Wpedantic" -#endif - #include #include #include #include +#include #include #include #include #include #include +#include #include "mlx5_defs.h" #include "mlx5_utils.h" @@ -139,6 +129,264 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev) return offloads; } +/* Fetches and drops all SW-owned and error CQEs to synchronize CQ. */ +static void +txq_sync_cq(struct mlx5_txq_data *txq) +{ + volatile struct mlx5_cqe *cqe; + int ret, i; + + i = txq->cqe_s; + do { + cqe = &txq->cqes[txq->cq_ci & txq->cqe_m]; + ret = check_cqe(cqe, txq->cqe_s, txq->cq_ci); + if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) { + if (likely(ret != MLX5_CQE_STATUS_ERR)) { + /* No new CQEs in completion queue. */ + MLX5_ASSERT(ret == MLX5_CQE_STATUS_HW_OWN); + break; + } + } + ++txq->cq_ci; + } while (--i); + /* Move all CQEs to HW ownership. */ + for (i = 0; i < txq->cqe_s; i++) { + cqe = &txq->cqes[i]; + cqe->op_own = MLX5_CQE_INVALIDATE; + } + /* Resync CQE and WQE (WQ in reset state). */ + rte_cio_wmb(); + *txq->cq_db = rte_cpu_to_be_32(txq->cq_ci); + rte_cio_wmb(); +} + +/** + * Tx queue stop. Device queue goes to the idle state, + * all involved mbufs are freed from elts/WQ. + * + * @param dev + * Pointer to Ethernet device structure. + * @param idx + * Tx queue index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_tx_queue_stop_primary(struct rte_eth_dev *dev, uint16_t idx) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_txq_data *txq = (*priv->txqs)[idx]; + struct mlx5_txq_ctrl *txq_ctrl = + container_of(txq, struct mlx5_txq_ctrl, txq); + int ret; + + 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; + } + } + /* Handle all send completions. */ + txq_sync_cq(txq); + /* Free elts stored in the SQ. */ + txq_free_elts(txq_ctrl); + /* Prevent writing new pkts to SQ by setting no free WQE.*/ + txq->wqe_ci = txq->wqe_s; + txq->wqe_pi = 0; + txq->elts_comp = 0; + /* Set the actual queue state. */ + dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED; + return 0; +} + +/** + * Tx queue stop. Device queue goes to the idle state, + * all involved mbufs are freed from elts/WQ. + * + * @param dev + * Pointer to Ethernet device structure. + * @param idx + * Tx queue index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_tx_queue_stop(struct rte_eth_dev *dev, uint16_t idx) +{ + int ret; + + if (dev->data->tx_queue_state[idx] == RTE_ETH_QUEUE_STATE_HAIRPIN) { + DRV_LOG(ERR, "Hairpin queue can't be stopped"); + rte_errno = EINVAL; + return -EINVAL; + } + if (dev->data->tx_queue_state[idx] == RTE_ETH_QUEUE_STATE_STOPPED) + return 0; + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { + ret = mlx5_mp_os_req_queue_control(dev, idx, + MLX5_MP_REQ_QUEUE_TX_STOP); + } else { + ret = mlx5_tx_queue_stop_primary(dev, idx); + } + return ret; +} + +/** + * Rx queue start. Device queue goes to the ready state, + * all required mbufs are allocated and WQ is replenished. + * + * @param dev + * Pointer to Ethernet device structure. + * @param idx + * RX queue index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_tx_queue_start_primary(struct rte_eth_dev *dev, uint16_t idx) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_txq_data *txq = (*priv->txqs)[idx]; + struct mlx5_txq_ctrl *txq_ctrl = + container_of(txq, struct mlx5_txq_ctrl, txq); + 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; + } + } + txq_ctrl->txq.wqe_ci = 0; + txq_ctrl->txq.wqe_pi = 0; + txq_ctrl->txq.elts_comp = 0; + /* Set the actual queue state. */ + dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STARTED; + return 0; +} + +/** + * Rx queue start. Device queue goes to the ready state, + * all required mbufs are allocated and WQ is replenished. + * + * @param dev + * Pointer to Ethernet device structure. + * @param idx + * RX queue index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_tx_queue_start(struct rte_eth_dev *dev, uint16_t idx) +{ + int ret; + + if (dev->data->tx_queue_state[idx] == RTE_ETH_QUEUE_STATE_HAIRPIN) { + DRV_LOG(ERR, "Hairpin queue can't be started"); + rte_errno = EINVAL; + return -EINVAL; + } + if (dev->data->tx_queue_state[idx] == RTE_ETH_QUEUE_STATE_STARTED) + return 0; + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { + ret = mlx5_mp_os_req_queue_control(dev, idx, + MLX5_MP_REQ_QUEUE_TX_START); + } else { + ret = mlx5_tx_queue_start_primary(dev, idx); + } + return ret; +} + /** * Tx queue presetup checks. * @@ -228,6 +476,7 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, DRV_LOG(DEBUG, "port %u adding Tx queue %u to list", dev->data->port_id, idx); (*priv->txqs)[idx] = &txq_ctrl->txq; + dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STARTED; return 0; } @@ -278,6 +527,7 @@ mlx5_tx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx, DRV_LOG(DEBUG, "port %u adding Tx queue %u to list", dev->data->port_id, idx); (*priv->txqs)[idx] = &txq_ctrl->txq; + dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_HAIRPIN; return 0; } @@ -343,10 +593,14 @@ txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl) { struct mlx5_priv *priv = txq_ctrl->priv; struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv)); - const size_t page_size = sysconf(_SC_PAGESIZE); #ifndef RTE_ARCH_64 unsigned int lock_idx; #endif + const size_t page_size = rte_mem_page_size(); + if (page_size == (size_t)-1) { + DRV_LOG(ERR, "Failed to get mem page size"); + rte_errno = ENOMEM; + } if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD) return; @@ -385,7 +639,12 @@ txq_uar_init_secondary(struct mlx5_txq_ctrl *txq_ctrl, int fd) void *addr; uintptr_t uar_va; uintptr_t offset; - const size_t page_size = sysconf(_SC_PAGESIZE); + const size_t page_size = rte_mem_page_size(); + if (page_size == (size_t)-1) { + DRV_LOG(ERR, "Failed to get mem page size"); + rte_errno = ENOMEM; + return -rte_errno; + } if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD) return 0; @@ -396,9 +655,9 @@ txq_uar_init_secondary(struct mlx5_txq_ctrl *txq_ctrl, int fd) */ uar_va = (uintptr_t)txq_ctrl->bf_reg; offset = uar_va & (page_size - 1); /* Offset in page. */ - addr = mmap(NULL, page_size, PROT_WRITE, MAP_SHARED, fd, - txq_ctrl->uar_mmap_offset); - if (addr == MAP_FAILED) { + addr = rte_mem_map(NULL, page_size, RTE_PROT_WRITE, RTE_MAP_SHARED, + fd, txq_ctrl->uar_mmap_offset); + if (!addr) { DRV_LOG(ERR, "port %u mmap failed for BF reg of txq %u", txq->port_id, txq->idx); @@ -421,13 +680,17 @@ static void txq_uar_uninit_secondary(struct mlx5_txq_ctrl *txq_ctrl) { struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(txq_ctrl->priv)); - const size_t page_size = sysconf(_SC_PAGESIZE); void *addr; + const size_t page_size = rte_mem_page_size(); + if (page_size == (size_t)-1) { + DRV_LOG(ERR, "Failed to get mem page size"); + rte_errno = ENOMEM; + } if (txq_ctrl->type != MLX5_TXQ_TYPE_STANDARD) return; addr = ppriv->uar_table[txq_ctrl->txq.idx]; - munmap(RTE_PTR_ALIGN_FLOOR(addr, page_size), page_size); + rte_mem_unmap(RTE_PTR_ALIGN_FLOOR(addr, page_size), page_size); } /** @@ -524,8 +787,8 @@ mlx5_txq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) MLX5_ASSERT(txq_data); MLX5_ASSERT(!txq_ctrl->obj); - tmpl = rte_calloc_socket(__func__, 1, sizeof(*tmpl), 0, - txq_ctrl->socket); + tmpl = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*tmpl), 0, + txq_ctrl->socket); if (!tmpl) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory resources", @@ -544,7 +807,7 @@ mlx5_txq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) DRV_LOG(ERR, "total data size %u power of 2 is " "too large for hairpin", priv->config.log_hp_size); - rte_free(tmpl); + mlx5_free(tmpl); rte_errno = ERANGE; return NULL; } @@ -564,7 +827,7 @@ mlx5_txq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) DRV_LOG(ERR, "port %u tx hairpin queue %u can't create sq object", dev->data->port_id, idx); - rte_free(tmpl); + mlx5_free(tmpl); rte_errno = errno; return NULL; } @@ -597,7 +860,7 @@ txq_release_sq_resources(struct mlx5_txq_obj *txq_obj) if (txq_obj->sq_umem) claim_zero(mlx5_glue->devx_umem_dereg(txq_obj->sq_umem)); if (txq_obj->sq_buf) - rte_free(txq_obj->sq_buf); + mlx5_free(txq_obj->sq_buf); if (txq_obj->cq_devx) claim_zero(mlx5_devx_cmd_destroy(txq_obj->cq_devx)); if (txq_obj->cq_dbrec_page) @@ -609,7 +872,7 @@ txq_release_sq_resources(struct mlx5_txq_obj *txq_obj) if (txq_obj->cq_umem) claim_zero(mlx5_glue->devx_umem_dereg(txq_obj->cq_umem)); if (txq_obj->cq_buf) - rte_free(txq_obj->cq_buf); + mlx5_free(txq_obj->cq_buf); } /** @@ -641,16 +904,23 @@ mlx5_txq_obj_devx_new(struct rte_eth_dev *dev, uint16_t idx) struct mlx5_devx_modify_sq_attr msq_attr = { 0 }; struct mlx5_devx_cq_attr cq_attr = { 0 }; struct mlx5_txq_obj *txq_obj = NULL; - size_t page_size = sysconf(_SC_PAGESIZE); + size_t page_size; struct mlx5_cqe *cqe; uint32_t i, nqe; + size_t alignment = (size_t)-1; int ret = 0; MLX5_ASSERT(txq_data); MLX5_ASSERT(!txq_ctrl->obj); - txq_obj = rte_calloc_socket(__func__, 1, - sizeof(struct mlx5_txq_obj), 0, - txq_ctrl->socket); + page_size = rte_mem_page_size(); + if (page_size == (size_t)-1) { + DRV_LOG(ERR, "Failed to get mem page size"); + rte_errno = ENOMEM; + return NULL; + } + txq_obj = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, + sizeof(struct mlx5_txq_obj), 0, + txq_ctrl->socket); if (!txq_obj) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory resources", @@ -673,10 +943,16 @@ mlx5_txq_obj_devx_new(struct rte_eth_dev *dev, uint16_t idx) goto error; } /* Allocate memory buffer for CQEs. */ - txq_obj->cq_buf = rte_zmalloc_socket(__func__, - nqe * sizeof(struct mlx5_cqe), - MLX5_CQE_BUF_ALIGNMENT, - sh->numa_node); + alignment = MLX5_CQE_BUF_ALIGNMENT; + if (alignment == (size_t)-1) { + DRV_LOG(ERR, "Failed to get mem page size"); + rte_errno = ENOMEM; + goto error; + } + txq_obj->cq_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, + nqe * sizeof(struct mlx5_cqe), + alignment, + sh->numa_node); if (!txq_obj->cq_buf) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory (CQ)", @@ -741,10 +1017,9 @@ mlx5_txq_obj_devx_new(struct rte_eth_dev *dev, uint16_t idx) /* Create the Work Queue. */ nqe = RTE_MIN(1UL << txq_data->elts_n, (uint32_t)sh->device_attr.max_qp_wr); - txq_obj->sq_buf = rte_zmalloc_socket(__func__, - nqe * sizeof(struct mlx5_wqe), - page_size, - sh->numa_node); + txq_obj->sq_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, + nqe * sizeof(struct mlx5_wqe), + page_size, sh->numa_node); if (!txq_obj->sq_buf) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory (SQ)", @@ -825,11 +1100,10 @@ mlx5_txq_obj_devx_new(struct rte_eth_dev *dev, uint16_t idx) dev->data->port_id, idx); goto error; } - txq_data->fcqs = rte_calloc_socket(__func__, - txq_data->cqe_s, - sizeof(*txq_data->fcqs), - RTE_CACHE_LINE_SIZE, - txq_ctrl->socket); + txq_data->fcqs = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, + txq_data->cqe_s * sizeof(*txq_data->fcqs), + RTE_CACHE_LINE_SIZE, + txq_ctrl->socket); if (!txq_data->fcqs) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory (FCQ)", dev->data->port_id, idx); @@ -857,10 +1131,10 @@ error: ret = rte_errno; /* Save rte_errno before cleanup. */ txq_release_sq_resources(txq_obj); if (txq_data->fcqs) { - rte_free(txq_data->fcqs); + mlx5_free(txq_data->fcqs); txq_data->fcqs = NULL; } - rte_free(txq_obj); + mlx5_free(txq_obj); rte_errno = ret; /* Restore rte_errno. */ return NULL; #endif @@ -1011,8 +1285,9 @@ mlx5_txq_obj_new(struct rte_eth_dev *dev, uint16_t idx, rte_errno = errno; goto error; } - txq_obj = rte_calloc_socket(__func__, 1, sizeof(struct mlx5_txq_obj), 0, - txq_ctrl->socket); + txq_obj = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, + sizeof(struct mlx5_txq_obj), 0, + txq_ctrl->socket); if (!txq_obj) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory", dev->data->port_id, idx); @@ -1054,11 +1329,9 @@ mlx5_txq_obj_new(struct rte_eth_dev *dev, uint16_t idx, txq_data->wqe_pi = 0; txq_data->wqe_comp = 0; txq_data->wqe_thres = txq_data->wqe_s / MLX5_TX_COMP_THRESH_INLINE_DIV; - txq_data->fcqs = rte_calloc_socket(__func__, - txq_data->cqe_s, - sizeof(*txq_data->fcqs), - RTE_CACHE_LINE_SIZE, - txq_ctrl->socket); + txq_data->fcqs = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, + txq_data->cqe_s * sizeof(*txq_data->fcqs), + RTE_CACHE_LINE_SIZE, txq_ctrl->socket); if (!txq_data->fcqs) { DRV_LOG(ERR, "port %u Tx queue %u cannot allocate memory (FCQ)", dev->data->port_id, idx); @@ -1114,11 +1387,11 @@ error: if (tmpl.qp) claim_zero(mlx5_glue->destroy_qp(tmpl.qp)); if (txq_data && txq_data->fcqs) { - rte_free(txq_data->fcqs); + mlx5_free(txq_data->fcqs); txq_data->fcqs = NULL; } if (txq_obj) - rte_free(txq_obj); + mlx5_free(txq_obj); priv->verbs_alloc_ctx.type = MLX5_VERBS_ALLOC_TYPE_NONE; rte_errno = ret; /* Restore rte_errno. */ return NULL; @@ -1175,11 +1448,11 @@ mlx5_txq_obj_release(struct mlx5_txq_obj *txq_obj) claim_zero(mlx5_glue->destroy_cq(txq_obj->cq)); } if (txq_obj->txq_ctrl->txq.fcqs) { - rte_free(txq_obj->txq_ctrl->txq.fcqs); + mlx5_free(txq_obj->txq_ctrl->txq.fcqs); txq_obj->txq_ctrl->txq.fcqs = NULL; } LIST_REMOVE(txq_obj, next); - rte_free(txq_obj); + mlx5_free(txq_obj); return 0; } return 1; @@ -1595,10 +1868,8 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_txq_ctrl *tmpl; - tmpl = rte_calloc_socket("TXQ", 1, - sizeof(*tmpl) + - desc * sizeof(struct rte_mbuf *), - 0, socket); + tmpl = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*tmpl) + + desc * sizeof(struct rte_mbuf *), 0, socket); if (!tmpl) { rte_errno = ENOMEM; return NULL; @@ -1638,7 +1909,7 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, LIST_INSERT_HEAD(&priv->txqsctrl, tmpl, next); return tmpl; error: - rte_free(tmpl); + mlx5_free(tmpl); return NULL; } @@ -1664,8 +1935,8 @@ mlx5_txq_hairpin_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_txq_ctrl *tmpl; - tmpl = rte_calloc_socket("TXQ", 1, - sizeof(*tmpl), 0, SOCKET_ID_ANY); + tmpl = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, sizeof(*tmpl), 0, + SOCKET_ID_ANY); if (!tmpl) { rte_errno = ENOMEM; return NULL; @@ -1734,8 +2005,9 @@ mlx5_txq_release(struct rte_eth_dev *dev, uint16_t idx) txq_free_elts(txq); mlx5_mr_btree_free(&txq->txq.mr_ctrl.cache_bh); LIST_REMOVE(txq, next); - rte_free(txq); + mlx5_free(txq); (*priv->txqs)[idx] = NULL; + dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STOPPED; return 0; } return 1;