From: Michael Baum Date: Thu, 3 Sep 2020 10:13:47 +0000 (+0000) Subject: net/mlx5: share Rx hash queue code X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=5a959cbfa68cfd15ca024a2883c6bacd7aa046bb;p=dpdk.git net/mlx5: share Rx hash queue code Move Rx hash queue object similar resources allocations from DevX and Verbs modules to a shared location. Signed-off-by: Michael Baum Acked-by: Matan Azrad --- diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c index 45691849c2..3f30ebff0a 100644 --- a/drivers/net/mlx5/linux/mlx5_verbs.c +++ b/drivers/net/mlx5/linux/mlx5_verbs.c @@ -502,45 +502,24 @@ mlx5_ibv_ind_table_destroy(struct mlx5_ind_table_obj *ind_tbl) * * @param dev * Pointer to Ethernet device. - * @param rss_key - * RSS key for the Rx hash queue. - * @param rss_key_len - * RSS key length. - * @param hash_fields - * Verbs protocol hash field to make the RSS on. - * @param queues - * Queues entering in hash queue. In case of empty hash_fields only the - * first queue index will be taken for the indirection table. - * @param queues_n - * Number of queues. + * @param hrxq + * Pointer to Rx Hash queue. * @param tunnel * Tunnel type. * * @return - * The Verbs object initialized index, 0 otherwise and rte_errno is set. + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -static uint32_t -mlx5_ibv_hrxq_new(struct rte_eth_dev *dev, - const uint8_t *rss_key, uint32_t rss_key_len, - uint64_t hash_fields, - const uint16_t *queues, uint32_t queues_n, +static int +mlx5_ibv_hrxq_new(struct rte_eth_dev *dev, struct mlx5_hrxq *hrxq, int tunnel __rte_unused) { struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_hrxq *hrxq = NULL; - uint32_t hrxq_idx = 0; struct ibv_qp *qp = NULL; - struct mlx5_ind_table_obj *ind_tbl; + struct mlx5_ind_table_obj *ind_tbl = hrxq->ind_table; + const uint8_t *rss_key = hrxq->rss_key; + uint64_t hash_fields = hrxq->hash_fields; int err; - - queues_n = hash_fields ? queues_n : 1; - ind_tbl = mlx5_ind_table_obj_get(dev, queues, queues_n); - if (!ind_tbl) - ind_tbl = mlx5_ind_table_obj_new(dev, queues, queues_n); - if (!ind_tbl) { - rte_errno = ENOMEM; - return 0; - } #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT struct mlx5dv_qp_init_attr qp_init_attr; @@ -570,7 +549,7 @@ mlx5_ibv_hrxq_new(struct rte_eth_dev *dev, .rx_hash_conf = (struct ibv_rx_hash_conf){ .rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ, - .rx_hash_key_len = rss_key_len, + .rx_hash_key_len = hrxq->rss_key_len, .rx_hash_key = (void *)(uintptr_t)rss_key, .rx_hash_fields_mask = hash_fields, @@ -591,7 +570,7 @@ mlx5_ibv_hrxq_new(struct rte_eth_dev *dev, .rx_hash_conf = (struct ibv_rx_hash_conf){ .rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ, - .rx_hash_key_len = rss_key_len, + .rx_hash_key_len = hrxq->rss_key_len, .rx_hash_key = (void *)(uintptr_t)rss_key, .rx_hash_fields_mask = hash_fields, @@ -604,10 +583,6 @@ mlx5_ibv_hrxq_new(struct rte_eth_dev *dev, rte_errno = errno; goto error; } - hrxq = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_HRXQ], &hrxq_idx); - if (!hrxq) - goto error; - hrxq->ind_table = ind_tbl; hrxq->qp = qp; #ifdef HAVE_IBV_FLOW_DV_SUPPORT hrxq->action = mlx5_glue->dv_create_flow_action_dest_ibv_qp(hrxq->qp); @@ -616,22 +591,13 @@ mlx5_ibv_hrxq_new(struct rte_eth_dev *dev, goto error; } #endif - hrxq->rss_key_len = rss_key_len; - hrxq->hash_fields = hash_fields; - memcpy(hrxq->rss_key, rss_key, rss_key_len); - rte_atomic32_inc(&hrxq->refcnt); - ILIST_INSERT(priv->sh->ipool[MLX5_IPOOL_HRXQ], &priv->hrxqs, hrxq_idx, - hrxq, next); - return hrxq_idx; + return 0; error: err = rte_errno; /* Save rte_errno before cleanup. */ - mlx5_ind_table_obj_release(dev, ind_tbl); if (qp) claim_zero(mlx5_glue->destroy_qp(qp)); - if (hrxq) - mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx); rte_errno = err; /* Restore rte_errno. */ - return 0; + return -rte_errno; } /** diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 12017e8fb5..579c96128e 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -745,10 +745,8 @@ struct mlx5_obj_ops { int (*ind_table_new)(struct rte_eth_dev *dev, const unsigned int log_n, struct mlx5_ind_table_obj *ind_tbl); void (*ind_table_destroy)(struct mlx5_ind_table_obj *ind_tbl); - uint32_t (*hrxq_new)(struct rte_eth_dev *dev, const uint8_t *rss_key, - uint32_t rss_key_len, uint64_t hash_fields, - const uint16_t *queues, uint32_t queues_n, - int tunnel __rte_unused); + int (*hrxq_new)(struct rte_eth_dev *dev, struct mlx5_hrxq *hrxq, + int tunnel __rte_unused); void (*hrxq_destroy)(struct mlx5_hrxq *hrxq); }; diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c index ebc3929704..cfb926492d 100644 --- a/drivers/net/mlx5/mlx5_devx.c +++ b/drivers/net/mlx5/mlx5_devx.c @@ -679,54 +679,33 @@ mlx5_devx_ind_table_destroy(struct mlx5_ind_table_obj *ind_tbl) * * @param dev * Pointer to Ethernet device. - * @param rss_key - * RSS key for the Rx hash queue. - * @param rss_key_len - * RSS key length. - * @param hash_fields - * Verbs protocol hash field to make the RSS on. - * @param queues - * Queues entering in hash queue. In case of empty hash_fields only the - * first queue index will be taken for the indirection table. - * @param queues_n - * Number of queues. + * @param hrxq + * Pointer to Rx Hash queue. * @param tunnel * Tunnel type. * * @return - * The DevX object initialized index, 0 otherwise and rte_errno is set. + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -static uint32_t -mlx5_devx_hrxq_new(struct rte_eth_dev *dev, - const uint8_t *rss_key, uint32_t rss_key_len, - uint64_t hash_fields, - const uint16_t *queues, uint32_t queues_n, +static int +mlx5_devx_hrxq_new(struct rte_eth_dev *dev, struct mlx5_hrxq *hrxq, int tunnel __rte_unused) { struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_hrxq *hrxq = NULL; - uint32_t hrxq_idx = 0; - struct mlx5_ind_table_obj *ind_tbl; - struct mlx5_devx_obj *tir = NULL; - struct mlx5_rxq_data *rxq_data = (*priv->rxqs)[queues[0]]; + struct mlx5_ind_table_obj *ind_tbl = hrxq->ind_table; + struct mlx5_rxq_data *rxq_data = (*priv->rxqs)[ind_tbl->queues[0]]; struct mlx5_rxq_ctrl *rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq); struct mlx5_devx_tir_attr tir_attr; - int err; - uint32_t i; + const uint8_t *rss_key = hrxq->rss_key; + uint64_t hash_fields = hrxq->hash_fields; bool lro = true; + uint32_t i; + int err; - queues_n = hash_fields ? queues_n : 1; - ind_tbl = mlx5_ind_table_obj_get(dev, queues, queues_n); - if (!ind_tbl) - ind_tbl = mlx5_ind_table_obj_new(dev, queues, queues_n); - if (!ind_tbl) { - rte_errno = ENOMEM; - return 0; - } /* Enable TIR LRO only if all the queues were configured for. */ - for (i = 0; i < queues_n; ++i) { - if (!(*priv->rxqs)[queues[i]]->lro) { + for (i = 0; i < ind_tbl->queues_n; ++i) { + if (!(*priv->rxqs)[ind_tbl->queues[i]]->lro) { lro = false; break; } @@ -776,18 +755,13 @@ mlx5_devx_hrxq_new(struct rte_eth_dev *dev, tir_attr.lro_enable_mask = MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO | MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO; } - tir = mlx5_devx_cmd_create_tir(priv->sh->ctx, &tir_attr); - if (!tir) { + hrxq->tir = mlx5_devx_cmd_create_tir(priv->sh->ctx, &tir_attr); + if (!hrxq->tir) { DRV_LOG(ERR, "Port %u cannot create DevX TIR.", dev->data->port_id); rte_errno = errno; goto error; } - hrxq = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_HRXQ], &hrxq_idx); - if (!hrxq) - goto error; - hrxq->ind_table = ind_tbl; - hrxq->tir = tir; #ifdef HAVE_IBV_FLOW_DV_SUPPORT hrxq->action = mlx5_glue->dv_create_flow_action_dest_devx_tir (hrxq->tir->obj); @@ -796,22 +770,13 @@ mlx5_devx_hrxq_new(struct rte_eth_dev *dev, goto error; } #endif - hrxq->rss_key_len = rss_key_len; - hrxq->hash_fields = hash_fields; - memcpy(hrxq->rss_key, rss_key, rss_key_len); - rte_atomic32_inc(&hrxq->refcnt); - ILIST_INSERT(priv->sh->ipool[MLX5_IPOOL_HRXQ], &priv->hrxqs, hrxq_idx, - hrxq, next); - return hrxq_idx; + return 0; error: err = rte_errno; /* Save rte_errno before cleanup. */ - mlx5_ind_table_obj_release(dev, ind_tbl); - if (tir) - claim_zero(mlx5_devx_cmd_destroy(tir)); - if (hrxq) - mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx); + if (hrxq->tir) + claim_zero(mlx5_devx_cmd_destroy(hrxq->tir)); rte_errno = err; /* Restore rte_errno. */ - return 0; + return -rte_errno; } /** diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index fa414863e3..d636c57387 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -8949,7 +8949,7 @@ __flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow, rss_desc->queue, rss_desc->queue_num); if (!hrxq_idx) { - hrxq_idx = priv->obj_ops->hrxq_new + hrxq_idx = mlx5_hrxq_new (dev, rss_desc->key, MLX5_RSS_HASH_KEY_LEN, dev_flow->hash_fields, diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index f8edae1856..2ce91f7617 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -1986,7 +1986,7 @@ flow_verbs_apply(struct rte_eth_dev *dev, struct rte_flow *flow, rss_desc->queue, rss_desc->queue_num); if (!hrxq_idx) - hrxq_idx = priv->obj_ops->hrxq_new + hrxq_idx = mlx5_hrxq_new (dev, rss_desc->key, MLX5_RSS_HASH_KEY_LEN, dev_flow->hash_fields, @@ -1995,7 +1995,7 @@ flow_verbs_apply(struct rte_eth_dev *dev, struct rte_flow *flow, !!(handle->layers & MLX5_FLOW_LAYER_TUNNEL)); hrxq = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_HRXQ], - hrxq_idx); + hrxq_idx); if (!hrxq) { rte_flow_error_set (error, rte_errno, diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c index c353139c13..234ee28e8a 100644 --- a/drivers/net/mlx5/mlx5_rxq.c +++ b/drivers/net/mlx5/mlx5_rxq.c @@ -1811,7 +1811,7 @@ mlx5_ind_table_obj_verify(struct rte_eth_dev *dev) * @return * The Verbs/DevX object initialized, NULL otherwise and rte_errno is set. */ -struct mlx5_ind_table_obj * +static struct mlx5_ind_table_obj * mlx5_ind_table_obj_new(struct rte_eth_dev *dev, const uint16_t *queues, uint32_t queues_n) { @@ -1937,6 +1937,74 @@ mlx5_hrxq_release(struct rte_eth_dev *dev, uint32_t hrxq_idx) return 1; } +/** + * Create an Rx Hash queue. + * + * @param dev + * Pointer to Ethernet device. + * @param rss_key + * RSS key for the Rx hash queue. + * @param rss_key_len + * RSS key length. + * @param hash_fields + * Verbs protocol hash field to make the RSS on. + * @param queues + * Queues entering in hash queue. In case of empty hash_fields only the + * first queue index will be taken for the indirection table. + * @param queues_n + * Number of queues. + * @param tunnel + * Tunnel type. + * + * @return + * The DevX object initialized index, 0 otherwise and rte_errno is set. + */ +uint32_t +mlx5_hrxq_new(struct rte_eth_dev *dev, + const uint8_t *rss_key, uint32_t rss_key_len, + uint64_t hash_fields, + const uint16_t *queues, uint32_t queues_n, + int tunnel __rte_unused) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_hrxq *hrxq = NULL; + uint32_t hrxq_idx = 0; + struct mlx5_ind_table_obj *ind_tbl; + int ret; + + queues_n = hash_fields ? queues_n : 1; + ind_tbl = mlx5_ind_table_obj_get(dev, queues, queues_n); + if (!ind_tbl) + ind_tbl = mlx5_ind_table_obj_new(dev, queues, queues_n); + if (!ind_tbl) { + rte_errno = ENOMEM; + return 0; + } + hrxq = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_HRXQ], &hrxq_idx); + if (!hrxq) + goto error; + hrxq->ind_table = ind_tbl; + hrxq->rss_key_len = rss_key_len; + hrxq->hash_fields = hash_fields; + memcpy(hrxq->rss_key, rss_key, rss_key_len); + ret = priv->obj_ops->hrxq_new(dev, hrxq, tunnel); + if (ret < 0) { + rte_errno = errno; + goto error; + } + rte_atomic32_inc(&hrxq->refcnt); + ILIST_INSERT(priv->sh->ipool[MLX5_IPOOL_HRXQ], &priv->hrxqs, hrxq_idx, + hrxq, next); + return hrxq_idx; +error: + ret = rte_errno; /* Save rte_errno before cleanup. */ + mlx5_ind_table_obj_release(dev, ind_tbl); + if (hrxq) + mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx); + rte_errno = ret; /* Restore rte_errno. */ + return 0; +} + /** * Verify the Rx Queue list is empty * diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h index 237344fd40..164f36b002 100644 --- a/drivers/net/mlx5/mlx5_rxtx.h +++ b/drivers/net/mlx5/mlx5_rxtx.h @@ -365,14 +365,16 @@ int mlx5_rxq_release(struct rte_eth_dev *dev, uint16_t idx); int mlx5_rxq_verify(struct rte_eth_dev *dev); int rxq_alloc_elts(struct mlx5_rxq_ctrl *rxq_ctrl); int mlx5_ind_table_obj_verify(struct rte_eth_dev *dev); -struct mlx5_ind_table_obj *mlx5_ind_table_obj_new(struct rte_eth_dev *dev, - const uint16_t *queues, - uint32_t queues_n); struct mlx5_ind_table_obj *mlx5_ind_table_obj_get(struct rte_eth_dev *dev, const uint16_t *queues, uint32_t queues_n); int mlx5_ind_table_obj_release(struct rte_eth_dev *dev, struct mlx5_ind_table_obj *ind_tbl); +uint32_t mlx5_hrxq_new(struct rte_eth_dev *dev, + const uint8_t *rss_key, uint32_t rss_key_len, + uint64_t hash_fields, + const uint16_t *queues, uint32_t queues_n, + int tunnel __rte_unused); uint32_t mlx5_hrxq_get(struct rte_eth_dev *dev, const uint8_t *rss_key, uint32_t rss_key_len, uint64_t hash_fields,