X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5.c;h=60301d3244d2ca31765759e4f9d8ec1de409dae9;hb=93f4ece91a1f6b338cbe3272cfdadde5b402fa3d;hp=1d25a8ef5d10be48a614c0324bd7cd8661941bd5;hpb=afd7a62514adca11a2f26e4e320cc7d3aff72952;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 1d25a8ef5d..60301d3244 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ #include "mlx5_autoconf.h" #include "mlx5_mr.h" #include "mlx5_flow.h" +#include "mlx5_flow_os.h" #include "rte_pmd_mlx5.h" /* Device parameter to enable RX completion queue compression. */ @@ -186,7 +188,7 @@ static pthread_mutex_t mlx5_dev_ctx_list_mutex = PTHREAD_MUTEX_INITIALIZER; static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { #ifdef HAVE_IBV_FLOW_DV_SUPPORT - { + [MLX5_IPOOL_DECAP_ENCAP] = { .size = sizeof(struct mlx5_flow_dv_encap_decap_resource), .trunk_size = 64, .grow_trunk = 3, @@ -197,7 +199,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_encap_decap_ipool", }, - { + [MLX5_IPOOL_PUSH_VLAN] = { .size = sizeof(struct mlx5_flow_dv_push_vlan_action_resource), .trunk_size = 64, .grow_trunk = 3, @@ -208,7 +210,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_push_vlan_ipool", }, - { + [MLX5_IPOOL_TAG] = { .size = sizeof(struct mlx5_flow_dv_tag_resource), .trunk_size = 64, .grow_trunk = 3, @@ -219,7 +221,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_tag_ipool", }, - { + [MLX5_IPOOL_PORT_ID] = { .size = sizeof(struct mlx5_flow_dv_port_id_action_resource), .trunk_size = 64, .grow_trunk = 3, @@ -230,7 +232,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_port_id_ipool", }, - { + [MLX5_IPOOL_JUMP] = { .size = sizeof(struct mlx5_flow_tbl_data_entry), .trunk_size = 64, .grow_trunk = 3, @@ -241,7 +243,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_jump_ipool", }, - { + [MLX5_IPOOL_SAMPLE] = { .size = sizeof(struct mlx5_flow_dv_sample_resource), .trunk_size = 64, .grow_trunk = 3, @@ -252,7 +254,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_sample_ipool", }, - { + [MLX5_IPOOL_DEST_ARRAY] = { .size = sizeof(struct mlx5_flow_dv_dest_array_resource), .trunk_size = 64, .grow_trunk = 3, @@ -263,8 +265,20 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_dest_array_ipool", }, + [MLX5_IPOOL_TUNNEL_ID] = { + .size = sizeof(struct mlx5_flow_tunnel), + .trunk_size = MLX5_MAX_TUNNELS, + .need_lock = 1, + .release_mem_en = 1, + .type = "mlx5_tunnel_offload", + }, + [MLX5_IPOOL_TNL_TBL_ID] = { + .size = 0, + .need_lock = 1, + .type = "mlx5_flow_tnl_tbl_ipool", + }, #endif - { + [MLX5_IPOOL_MTR] = { .size = sizeof(struct mlx5_flow_meter), .trunk_size = 64, .grow_trunk = 3, @@ -275,7 +289,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_meter_ipool", }, - { + [MLX5_IPOOL_MCP] = { .size = sizeof(struct mlx5_flow_mreg_copy_resource), .trunk_size = 64, .grow_trunk = 3, @@ -286,7 +300,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_mcp_ipool", }, - { + [MLX5_IPOOL_HRXQ] = { .size = (sizeof(struct mlx5_hrxq) + MLX5_RSS_HASH_KEY_LEN), .trunk_size = 64, .grow_trunk = 3, @@ -297,7 +311,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_hrxq_ipool", }, - { + [MLX5_IPOOL_MLX5_FLOW] = { /* * MLX5_IPOOL_MLX5_FLOW size varies for DV and VERBS flows. * It set in run time according to PCI function configuration. @@ -312,7 +326,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "mlx5_flow_handle_ipool", }, - { + [MLX5_IPOOL_RTE_FLOW] = { .size = sizeof(struct rte_flow), .trunk_size = 4096, .need_lock = 1, @@ -321,20 +335,21 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .free = mlx5_free, .type = "rte_flow_ipool", }, - { + [MLX5_IPOOL_RSS_EXPANTION_FLOW_ID] = { .size = 0, .need_lock = 1, .type = "mlx5_flow_rss_id_ipool", }, - { - .size = 0, - .need_lock = 1, - .type = "mlx5_flow_tnl_flow_ipool", - }, - { - .size = 0, + [MLX5_IPOOL_RSS_SHARED_ACTIONS] = { + .size = sizeof(struct mlx5_shared_action_rss), + .trunk_size = 64, + .grow_trunk = 3, + .grow_shift = 2, .need_lock = 1, - .type = "mlx5_flow_tnl_tbl_ipool", + .release_mem_en = 1, + .malloc = mlx5_malloc, + .free = mlx5_free, + .type = "mlx5_shared_action_rss", }, }; @@ -344,6 +359,72 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { #define MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE 4096 +/** + * Initialize the ASO aging management structure. + * + * @param[in] sh + * Pointer to mlx5_dev_ctx_shared object to free + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh) +{ + int err; + + if (sh->aso_age_mng) + return 0; + sh->aso_age_mng = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*sh->aso_age_mng), + RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY); + if (!sh->aso_age_mng) { + DRV_LOG(ERR, "aso_age_mng allocation was failed."); + rte_errno = ENOMEM; + return -ENOMEM; + } + err = mlx5_aso_queue_init(sh); + if (err) { + mlx5_free(sh->aso_age_mng); + return -1; + } + rte_spinlock_init(&sh->aso_age_mng->resize_sl); + rte_spinlock_init(&sh->aso_age_mng->free_sl); + LIST_INIT(&sh->aso_age_mng->free); + return 0; +} + +/** + * Close and release all the resources of the ASO aging management structure. + * + * @param[in] sh + * Pointer to mlx5_dev_ctx_shared object to free. + */ +static void +mlx5_flow_aso_age_mng_close(struct mlx5_dev_ctx_shared *sh) +{ + int i, j; + + mlx5_aso_queue_stop(sh); + mlx5_aso_queue_uninit(sh); + if (sh->aso_age_mng->pools) { + struct mlx5_aso_age_pool *pool; + + for (i = 0; i < sh->aso_age_mng->next; ++i) { + pool = sh->aso_age_mng->pools[i]; + claim_zero(mlx5_devx_cmd_destroy + (pool->flow_hit_aso_obj)); + for (j = 0; j < MLX5_COUNTERS_PER_POOL; ++j) + if (pool->actions[j].dr_action) + claim_zero + (mlx5_flow_os_destroy_flow_action + (pool->actions[j].dr_action)); + mlx5_free(pool); + } + mlx5_free(sh->aso_age_mng->pools); + } + mlx5_free(sh->aso_age_mng); +} + /** * Initialize the shared aging list information per port. * @@ -360,6 +441,7 @@ mlx5_flow_aging_init(struct mlx5_dev_ctx_shared *sh) age_info = &sh->port[i].age_info; age_info->flags = 0; TAILQ_INIT(&age_info->aged_counters); + LIST_INIT(&age_info->aged_aso); rte_spinlock_init(&age_info->aged_sl); MLX5_AGE_SET(age_info, MLX5_AGE_TRIGGER); } @@ -401,7 +483,7 @@ mlx5_flow_destroy_counter_stat_mem_mng(struct mlx5_counter_stats_mem_mng *mng) LIST_REMOVE(mng, next); claim_zero(mlx5_devx_cmd_destroy(mng->dm)); - claim_zero(mlx5_glue->devx_umem_dereg(mng->umem)); + claim_zero(mlx5_os_umem_dereg(mng->umem)); mlx5_free(mem); } @@ -442,7 +524,7 @@ mlx5_flow_counters_mng_close(struct mlx5_dev_ctx_shared *sh) if (cnt->action) claim_zero - (mlx5_glue->destroy_flow_action + (mlx5_flow_os_destroy_flow_action (cnt->action)); if (fallback && MLX5_POOL_GET_CNT (pool, j)->dcs_when_free) @@ -461,6 +543,25 @@ mlx5_flow_counters_mng_close(struct mlx5_dev_ctx_shared *sh) memset(&sh->cmng, 0, sizeof(sh->cmng)); } +/* Send FLOW_AGED event if needed. */ +void +mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh) +{ + struct mlx5_age_info *age_info; + uint32_t i; + + for (i = 0; i < sh->max_port; i++) { + age_info = &sh->port[i].age_info; + if (!MLX5_AGE_GET(age_info, MLX5_AGE_EVENT_NEW)) + continue; + if (MLX5_AGE_GET(age_info, MLX5_AGE_TRIGGER)) + rte_eth_dev_callback_process + (&rte_eth_devices[sh->port[i].devx_ih_port_id], + RTE_ETH_EVENT_FLOW_AGED, NULL); + age_info->flags = 0; + } +} + /** * Initialize the flow resources' indexed mempool. * @@ -817,6 +918,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn, goto error; } sh->refcnt = 1; + sh->bond_dev = UINT16_MAX; sh->max_port = spawn->max_port; strncpy(sh->ibdev_name, mlx5_os_get_ctx_device_name(sh->ctx), sizeof(sh->ibdev_name) - 1); @@ -831,7 +933,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn, sh->port[i].ih_port_id = RTE_MAX_ETHPORTS; sh->port[i].devx_ih_port_id = RTE_MAX_ETHPORTS; } - sh->pd = mlx5_glue->alloc_pd(sh->ctx); + sh->pd = mlx5_os_alloc_pd(sh->ctx); if (sh->pd == NULL) { DRV_LOG(ERR, "PD allocation failure"); err = ENOMEM; @@ -931,7 +1033,7 @@ error: if (sh->tx_uar) mlx5_glue->devx_free_uar(sh->tx_uar); if (sh->pd) - claim_zero(mlx5_glue->dealloc_pd(sh->pd)); + claim_zero(mlx5_os_dealloc_pd(sh->pd)); if (sh->ctx) claim_zero(mlx5_glue->close_device(sh->ctx)); mlx5_free(sh); @@ -984,6 +1086,10 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh) * Only primary process handles async device events. **/ mlx5_flow_counters_mng_close(sh); + if (sh->aso_age_mng) { + mlx5_flow_aso_age_mng_close(sh); + sh->aso_age_mng = NULL; + } mlx5_flow_ipool_destroy(sh); mlx5_os_dev_shared_handler_uninstall(sh); if (sh->cnt_id_tbl) { @@ -995,7 +1101,7 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh) sh->tx_uar = NULL; } if (sh->pd) - claim_zero(mlx5_glue->dealloc_pd(sh->pd)); + claim_zero(mlx5_os_dealloc_pd(sh->pd)); if (sh->tis) claim_zero(mlx5_devx_cmd_destroy(sh->tis)); if (sh->td) @@ -1049,7 +1155,8 @@ mlx5_alloc_table_hash_list(struct mlx5_priv *priv __rte_unused) MLX5_ASSERT(sh); snprintf(s, sizeof(s), "%s_flow_table", priv->sh->ibdev_name); sh->flow_tbls = mlx5_hlist_create(s, MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE, - 0, 0, flow_dv_tbl_create_cb, NULL, + 0, 0, flow_dv_tbl_create_cb, + flow_dv_tbl_match_cb, flow_dv_tbl_remove_cb); if (!sh->flow_tbls) { DRV_LOG(ERR, "flow tables with hash creation failed."); @@ -1225,7 +1332,7 @@ mlx5_dev_close(struct rte_eth_dev *dev) mlx5_flex_parser_ecpri_release(dev); if (priv->rxqs != NULL) { /* XXX race condition if mlx5_rx_burst() is still running. */ - usleep(1000); + rte_delay_us_sleep(1000); for (i = 0; (i != priv->rxqs_n); ++i) mlx5_rxq_release(dev, i); priv->rxqs_n = 0; @@ -1233,7 +1340,7 @@ mlx5_dev_close(struct rte_eth_dev *dev) } if (priv->txqs != NULL) { /* XXX race condition if mlx5_tx_burst() is still running. */ - usleep(1000); + rte_delay_us_sleep(1000); for (i = 0; (i != priv->txqs_n); ++i) mlx5_txq_release(dev, i); priv->txqs_n = 0; @@ -1286,6 +1393,7 @@ mlx5_dev_close(struct rte_eth_dev *dev) if (ret) DRV_LOG(WARNING, "port %u some flows still remain", dev->data->port_id); + mlx5_cache_list_destroy(&priv->hrxqs); /* * Free the shared context in last turn, because the cleanup * routines above may use some shared fields, like @@ -1360,7 +1468,14 @@ mlx5_args_check(const char *key, const char *val, void *opaque) } mod = tmp >= 0 ? tmp : -tmp; if (strcmp(MLX5_RXQ_CQE_COMP_EN, key) == 0) { + if (tmp > MLX5_CQE_RESP_FORMAT_L34H_STRIDX) { + DRV_LOG(ERR, "invalid CQE compression " + "format parameter"); + rte_errno = EINVAL; + return -rte_errno; + } config->cqe_comp = !!tmp; + config->cqe_comp_fmt = tmp; } else if (strcmp(MLX5_RXQ_CQE_PAD_EN, key) == 0) { config->cqe_pad = !!tmp; } else if (strcmp(MLX5_RXQ_PKT_PAD_EN, key) == 0) { @@ -1924,7 +2039,7 @@ static const struct rte_pci_id mlx5_pci_id_map[] = { }, { RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, - PCI_DEVICE_ID_MELLANOX_CONNECTX6DXVF) + PCI_DEVICE_ID_MELLANOX_CONNECTXVF) }, { RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,