X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5.c;h=ffee39c1a0c73fe00bdef4d2b8fbaf54be7151c6;hb=89ef76db3b7627d4a7e656c7e51807b5bf8bdedc;hp=35baaf7e9358f91e38a49453caf7c1c1c99e4c77;hpb=06f78b5ebcaeb46b523e947d1d3419fe05a6a8ee;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 35baaf7e93..ffee39c1a0 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -443,7 +443,8 @@ mlx5_config_doorbell_mapping_env(const struct mlx5_dev_config *config) if (config->dbnc == MLX5_ARG_UNSET) setenv(MLX5_SHUT_UP_BF, MLX5_SHUT_UP_BF_DEFAULT, 1); else - setenv(MLX5_SHUT_UP_BF, config->dbnc ? "1" : "0", 1); + setenv(MLX5_SHUT_UP_BF, + config->dbnc == MLX5_TXDB_NCACHED ? "1" : "0", 1); return value; } @@ -714,6 +715,143 @@ exit: pthread_mutex_unlock(&mlx5_ibv_list_mutex); } +/** + * Destroy table hash list and all the root entries per domain. + * + * @param[in] priv + * Pointer to the private device data structure. + */ +static void +mlx5_free_table_hash_list(struct mlx5_priv *priv) +{ + struct mlx5_ibv_shared *sh = priv->sh; + struct mlx5_flow_tbl_data_entry *tbl_data; + union mlx5_flow_tbl_key table_key = { + { + .table_id = 0, + .reserved = 0, + .domain = 0, + .direction = 0, + } + }; + struct mlx5_hlist_entry *pos; + + if (!sh->flow_tbls) + return; + pos = mlx5_hlist_lookup(sh->flow_tbls, table_key.v64); + if (pos) { + tbl_data = container_of(pos, struct mlx5_flow_tbl_data_entry, + entry); + assert(tbl_data); + mlx5_hlist_remove(sh->flow_tbls, pos); + rte_free(tbl_data); + } + table_key.direction = 1; + pos = mlx5_hlist_lookup(sh->flow_tbls, table_key.v64); + if (pos) { + tbl_data = container_of(pos, struct mlx5_flow_tbl_data_entry, + entry); + assert(tbl_data); + mlx5_hlist_remove(sh->flow_tbls, pos); + rte_free(tbl_data); + } + table_key.direction = 0; + table_key.domain = 1; + pos = mlx5_hlist_lookup(sh->flow_tbls, table_key.v64); + if (pos) { + tbl_data = container_of(pos, struct mlx5_flow_tbl_data_entry, + entry); + assert(tbl_data); + mlx5_hlist_remove(sh->flow_tbls, pos); + rte_free(tbl_data); + } + mlx5_hlist_destroy(sh->flow_tbls, NULL, NULL); +} + +/** + * Initialize flow table hash list and create the root tables entry + * for each domain. + * + * @param[in] priv + * Pointer to the private device data structure. + * + * @return + * Zero on success, positive error code otherwise. + */ +static int +mlx5_alloc_table_hash_list(struct mlx5_priv *priv) +{ + struct mlx5_ibv_shared *sh = priv->sh; + char s[MLX5_HLIST_NAMESIZE]; + int err = 0; + + 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); + if (!sh->flow_tbls) { + DRV_LOG(ERR, "flow tables with hash creation failed.\n"); + err = ENOMEM; + return err; + } +#ifndef HAVE_MLX5DV_DR + /* + * In case we have not DR support, the zero tables should be created + * because DV expect to see them even if they cannot be created by + * RDMA-CORE. + */ + union mlx5_flow_tbl_key table_key = { + { + .table_id = 0, + .reserved = 0, + .domain = 0, + .direction = 0, + } + }; + struct mlx5_flow_tbl_data_entry *tbl_data = rte_zmalloc(NULL, + sizeof(*tbl_data), 0); + + if (!tbl_data) { + err = ENOMEM; + goto error; + } + tbl_data->entry.key = table_key.v64; + err = mlx5_hlist_insert(sh->flow_tbls, &tbl_data->entry); + if (err) + goto error; + rte_atomic32_init(&tbl_data->tbl.refcnt); + rte_atomic32_inc(&tbl_data->tbl.refcnt); + table_key.direction = 1; + tbl_data = rte_zmalloc(NULL, sizeof(*tbl_data), 0); + if (!tbl_data) { + err = ENOMEM; + goto error; + } + tbl_data->entry.key = table_key.v64; + err = mlx5_hlist_insert(sh->flow_tbls, &tbl_data->entry); + if (err) + goto error; + rte_atomic32_init(&tbl_data->tbl.refcnt); + rte_atomic32_inc(&tbl_data->tbl.refcnt); + table_key.direction = 0; + table_key.domain = 1; + tbl_data = rte_zmalloc(NULL, sizeof(*tbl_data), 0); + if (!tbl_data) { + err = ENOMEM; + goto error; + } + tbl_data->entry.key = table_key.v64; + err = mlx5_hlist_insert(sh->flow_tbls, &tbl_data->entry); + if (err) + goto error; + rte_atomic32_init(&tbl_data->tbl.refcnt); + rte_atomic32_inc(&tbl_data->tbl.refcnt); + return err; +error: + mlx5_free_table_hash_list(priv); +#endif /* HAVE_MLX5DV_DR */ + return err; +} + /** * Initialize DR related data within private structure. * Routine checks the reference counter and does actual @@ -728,13 +866,28 @@ exit: static int mlx5_alloc_shared_dr(struct mlx5_priv *priv) { -#ifdef HAVE_MLX5DV_DR struct mlx5_ibv_shared *sh = priv->sh; + char s[MLX5_HLIST_NAMESIZE]; int err = 0; + + if (!sh->flow_tbls) + err = mlx5_alloc_table_hash_list(priv); + else + DRV_LOG(DEBUG, "sh->flow_tbls[%p] already created, reuse\n", + (void *)sh->flow_tbls); + if (err) + return err; + /* Create tags hash list table. */ + snprintf(s, sizeof(s), "%s_tags", sh->ibdev_name); + sh->tag_table = mlx5_hlist_create(s, MLX5_TAGS_HLIST_ARRAY_SIZE); + if (!sh->tag_table) { + DRV_LOG(ERR, "tags with hash creation failed.\n"); + err = ENOMEM; + goto error; + } +#ifdef HAVE_MLX5DV_DR void *domain; - char s[MLX5_HLIST_NAMESIZE]; - assert(sh); if (sh->dv_refcnt) { /* Shared DV/DR structures is already initialized. */ sh->dv_refcnt++; @@ -772,29 +925,13 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) sh->esw_drop_action = mlx5_glue->dr_create_flow_action_drop(); } #endif - snprintf(s, sizeof(s), "%s_flow_table", priv->sh->ibdev_name); - sh->flow_tbls = mlx5_hlist_create(s, - MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE); - if (!sh->flow_tbls) { - DRV_LOG(ERR, "flow tables with hash creation failed.\n"); - err = -ENOMEM; - goto error; - } - /* create tags hash list table. */ - snprintf(s, sizeof(s), "%s_tags", priv->sh->ibdev_name); - sh->tag_table = mlx5_hlist_create(s, MLX5_TAGS_HLIST_ARRAY_SIZE); - if (!sh->flow_tbls) { - DRV_LOG(ERR, "tags with hash creation failed.\n"); - err = -ENOMEM; - goto error; - } sh->pop_vlan_action = mlx5_glue->dr_create_flow_action_pop_vlan(); +#endif /* HAVE_MLX5DV_DR */ sh->dv_refcnt++; priv->dr_shared = 1; return 0; - error: - /* Rollback the created objects. */ + /* Rollback the created objects. */ if (sh->rx_domain) { mlx5_glue->dr_destroy_domain(sh->rx_domain); sh->rx_domain = NULL; @@ -807,10 +944,6 @@ error: mlx5_glue->dr_destroy_domain(sh->fdb_domain); sh->fdb_domain = NULL; } - if (sh->flow_tbls) { - mlx5_hlist_destroy(sh->flow_tbls, NULL, NULL); - sh->flow_tbls = NULL; - } if (sh->esw_drop_action) { mlx5_glue->destroy_flow_action(sh->esw_drop_action); sh->esw_drop_action = NULL; @@ -819,11 +952,13 @@ error: mlx5_glue->destroy_flow_action(sh->pop_vlan_action); sh->pop_vlan_action = NULL; } + if (sh->tag_table) { + /* tags should be destroyed with flow before. */ + mlx5_hlist_destroy(sh->tag_table, NULL, NULL); + sh->tag_table = NULL; + } + mlx5_free_table_hash_list(priv); return err; -#else - (void)priv; - return 0; -#endif } /** @@ -835,7 +970,6 @@ error: static void mlx5_free_shared_dr(struct mlx5_priv *priv) { -#ifdef HAVE_MLX5DV_DR struct mlx5_ibv_shared *sh; if (!priv->dr_shared) @@ -843,19 +977,10 @@ mlx5_free_shared_dr(struct mlx5_priv *priv) priv->dr_shared = 0; sh = priv->sh; assert(sh); +#ifdef HAVE_MLX5DV_DR assert(sh->dv_refcnt); if (sh->dv_refcnt && --sh->dv_refcnt) return; - if (sh->flow_tbls) { - /* flow table entries should be handled properly before. */ - mlx5_hlist_destroy(sh->flow_tbls, NULL, NULL); - sh->flow_tbls = NULL; - } - if (sh->tag_table) { - /* tags should be destroyed with flow before. */ - mlx5_hlist_destroy(sh->tag_table, NULL, NULL); - sh->tag_table = NULL; - } if (sh->rx_domain) { mlx5_glue->dr_destroy_domain(sh->rx_domain); sh->rx_domain = NULL; @@ -879,9 +1004,13 @@ mlx5_free_shared_dr(struct mlx5_priv *priv) sh->pop_vlan_action = NULL; } pthread_mutex_destroy(&sh->dv_mutex); -#else - (void)priv; -#endif +#endif /* HAVE_MLX5DV_DR */ + if (sh->tag_table) { + /* tags should be destroyed with flow before. */ + mlx5_hlist_destroy(sh->tag_table, NULL, NULL); + sh->tag_table = NULL; + } + mlx5_free_table_hash_list(priv); } /** @@ -1387,7 +1516,15 @@ mlx5_args_check(const char *key, const char *val, void *opaque) } else if (strcmp(MLX5_TXQ_MPW_EN, key) == 0) { config->mps = !!tmp; } else if (strcmp(MLX5_TX_DB_NC, key) == 0) { - config->dbnc = !!tmp; + if (tmp != MLX5_TXDB_CACHED && + tmp != MLX5_TXDB_NCACHED && + tmp != MLX5_TXDB_HEURISTIC) { + DRV_LOG(ERR, "invalid Tx doorbell " + "mapping parameter"); + rte_errno = EINVAL; + return -rte_errno; + } + config->dbnc = tmp; } else if (strcmp(MLX5_TXQ_MPW_HDR_DSEG_EN, key) == 0) { DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key); } else if (strcmp(MLX5_TXQ_MAX_INLINE_LEN, key) == 0) { @@ -1410,8 +1547,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque) if (tmp != MLX5_XMETA_MODE_LEGACY && tmp != MLX5_XMETA_MODE_META16 && tmp != MLX5_XMETA_MODE_META32) { - DRV_LOG(WARNING, "invalid extensive " - "metadata parameter"); + DRV_LOG(ERR, "invalid extensive " + "metadata parameter"); rte_errno = EINVAL; return -rte_errno; } @@ -2124,7 +2261,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, tunnel_en = ((dv_attr.tunnel_offloads_caps & MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN) && (dv_attr.tunnel_offloads_caps & - MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE)); + MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE) && + (dv_attr.tunnel_offloads_caps & + MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE)); } DRV_LOG(DEBUG, "tunnel offloading is %ssupported", tunnel_en ? "" : "not "); @@ -2225,7 +2364,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, err = ENOTSUP; goto error; } - } else if (devx_port.comp_mask & MLX5DV_DEVX_PORT_VPORT) { + } + if (devx_port.comp_mask & MLX5DV_DEVX_PORT_VPORT) { priv->vport_id = devx_port.vport_num; } else if (spawn->pf_bond >= 0) { DRV_LOG(ERR, "can't deduce vport index for port %d" @@ -2295,7 +2435,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) DRV_LOG(DEBUG, "counters are not supported"); #endif -#ifndef HAVE_IBV_FLOW_DV_SUPPORT +#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR) if (config.dv_flow_en) { DRV_LOG(WARNING, "DV flow is not supported"); config.dv_flow_en = 0; @@ -2346,7 +2486,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, else config.mps = config.mps ? mps : MLX5_MPW_DISABLED; DRV_LOG(INFO, "%sMPS is %s", - config.mps == MLX5_MPW_ENHANCED ? "enhanced " : "", + config.mps == MLX5_MPW_ENHANCED ? "enhanced " : + config.mps == MLX5_MPW ? "legacy " : "", config.mps != MLX5_MPW_DISABLED ? "enabled" : "disabled"); if (config.cqe_comp && !cqe_comp) { DRV_LOG(WARNING, "Rx CQE compression isn't supported"); @@ -2813,6 +2954,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct mlx5_dev_config dev_config; int ret; + if (rte_eal_process_type() == RTE_PROC_PRIMARY) + mlx5_pmd_socket_init(); ret = mlx5_init_once(); if (ret) { DRV_LOG(ERR, "unable to init PMD global data: %s", @@ -3143,6 +3286,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, .min_rxqs_num = MLX5_MPRQ_MIN_RXQS, }, .dv_esw_en = 1, + .dv_flow_en = 1, }; /* Device specific configuration. */ switch (pci_dev->id.device_id) {