X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Flinux%2Fmlx5_os.c;h=dd6c637564b93559f46cd72f00fdc7f363065173;hb=0947ed380febad9d6f794b6f4e9aa9137860a06e;hp=f17e1aac3c76fa4e64748a9f53972c6ff1fcde56;hpb=295968d1740760337e16b0d7914875c5cac52850;p=dpdk.git diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index f17e1aac3c..dd6c637564 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -112,7 +112,7 @@ static struct mlx5_indexed_pool_config icfg[] = { * Pointer to RQ channel object, which includes the channel fd * * @param[out] fd - * The file descriptor (representing the intetrrupt) used in this channel. + * The file descriptor (representing the interrupt) used in this channel. * * @return * 0 on successfully setting the fd to non-blocking, non-zero otherwise. @@ -337,6 +337,16 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) flow_dv_dest_array_clone_free_cb); if (!sh->dest_array_list) goto error; + /* Init shared flex parsers list, no need lcore_share */ + snprintf(s, sizeof(s), "%s_flex_parsers_list", sh->ibdev_name); + sh->flex_parsers_dv = mlx5_list_create(s, sh, false, + mlx5_flex_parser_create_cb, + mlx5_flex_parser_match_cb, + mlx5_flex_parser_remove_cb, + mlx5_flex_parser_clone_cb, + mlx5_flex_parser_clone_free_cb); + if (!sh->flex_parsers_dv) + goto error; #endif #ifdef HAVE_MLX5DV_DR void *domain; @@ -410,6 +420,7 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) mlx5_glue->dr_create_flow_action_default_miss(); if (!sh->default_miss_action) DRV_LOG(WARNING, "Default miss action is not supported."); + LIST_INIT(&sh->shared_rxqs); return 0; error: /* Rollback the created objects. */ @@ -484,6 +495,7 @@ mlx5_os_free_shared_dr(struct mlx5_priv *priv) MLX5_ASSERT(sh && sh->refcnt); if (sh->refcnt > 1) return; + MLX5_ASSERT(LIST_EMPTY(&sh->shared_rxqs)); #ifdef HAVE_MLX5DV_DR if (sh->rx_domain) { mlx5_glue->dr_destroy_domain(sh->rx_domain); @@ -704,10 +716,15 @@ mlx5_flow_drop_action_config(struct rte_eth_dev *dev __rte_unused) * DR supports drop action placeholder when it is supported; * otherwise, use the queue drop action. */ - if (mlx5_flow_discover_dr_action_support(dev)) - priv->root_drop_action = priv->drop_queue.hrxq->action; - else + if (!priv->sh->drop_action_check_flag) { + if (!mlx5_flow_discover_dr_action_support(dev)) + priv->sh->dr_drop_action_en = 1; + priv->sh->drop_action_check_flag = 1; + } + if (priv->sh->dr_drop_action_en) priv->root_drop_action = priv->sh->dr_drop_action; + else + priv->root_drop_action = priv->drop_queue.hrxq->action; #endif } @@ -1491,6 +1508,15 @@ err_secondary: goto error; #endif } + if (config->std_delay_drop || config->hp_delay_drop) { + if (!config->hca_attr.rq_delay_drop) { + config->std_delay_drop = 0; + config->hp_delay_drop = 0; + DRV_LOG(WARNING, + "dev_port-%u: Rxq delay drop is not supported", + priv->dev_port); + } + } if (sh->devx) { uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)]; @@ -1523,34 +1549,34 @@ err_secondary: DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported", (config->hw_fcs_strip ? "" : "not ")); if (config->mprq.enabled && mprq) { - if (config->mprq.stride_num_n && - (config->mprq.stride_num_n > mprq_max_stride_num_n || - config->mprq.stride_num_n < mprq_min_stride_num_n)) { - config->mprq.stride_num_n = - RTE_MIN(RTE_MAX(MLX5_MPRQ_STRIDE_NUM_N, - mprq_min_stride_num_n), - mprq_max_stride_num_n); + if (config->mprq.log_stride_num && + (config->mprq.log_stride_num > mprq_max_stride_num_n || + config->mprq.log_stride_num < mprq_min_stride_num_n)) { + config->mprq.log_stride_num = + RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM, + mprq_min_stride_num_n), + mprq_max_stride_num_n); DRV_LOG(WARNING, "the number of strides" " for Multi-Packet RQ is out of range," " setting default value (%u)", - 1 << config->mprq.stride_num_n); - } - if (config->mprq.stride_size_n && - (config->mprq.stride_size_n > mprq_max_stride_size_n || - config->mprq.stride_size_n < mprq_min_stride_size_n)) { - config->mprq.stride_size_n = - RTE_MIN(RTE_MAX(MLX5_MPRQ_STRIDE_SIZE_N, - mprq_min_stride_size_n), - mprq_max_stride_size_n); + 1 << config->mprq.log_stride_num); + } + if (config->mprq.log_stride_size && + (config->mprq.log_stride_size > mprq_max_stride_size_n || + config->mprq.log_stride_size < mprq_min_stride_size_n)) { + config->mprq.log_stride_size = + RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_SIZE, + mprq_min_stride_size_n), + mprq_max_stride_size_n); DRV_LOG(WARNING, "the size of a stride" " for Multi-Packet RQ is out of range," " setting default value (%u)", - 1 << config->mprq.stride_size_n); + 1 << config->mprq.log_stride_size); } - config->mprq.min_stride_size_n = mprq_min_stride_size_n; - config->mprq.max_stride_size_n = mprq_max_stride_size_n; + config->mprq.log_min_stride_size = mprq_min_stride_size_n; + config->mprq.log_max_stride_size = mprq_max_stride_size_n; } else if (config->mprq.enabled && !mprq) { DRV_LOG(WARNING, "Multi-Packet RQ isn't supported"); config->mprq.enabled = 0; @@ -1682,13 +1708,11 @@ err_secondary: err = mlx5_alloc_shared_dr(priv); if (err) goto error; + if (mlx5_flex_item_port_init(eth_dev) < 0) + goto error; } if (sh->devx && config->dv_flow_en && config->dest_tir) { priv->obj_ops = devx_obj_ops; - priv->obj_ops.drop_action_create = - ibv_obj_ops.drop_action_create; - priv->obj_ops.drop_action_destroy = - ibv_obj_ops.drop_action_destroy; mlx5_queue_counter_id_prepare(eth_dev); priv->obj_ops.lb_dummy_queue_create = mlx5_rxq_ibv_obj_dummy_lb_create; @@ -1703,8 +1727,7 @@ err_secondary: priv->obj_ops = ibv_obj_ops; } if (config->tx_pp && - (priv->config.dv_esw_en || - priv->obj_ops.txq_obj_new != mlx5_txq_devx_obj_new)) { + priv->obj_ops.txq_obj_new != mlx5_txq_devx_obj_new) { /* * HAVE_MLX5DV_DEVX_UAR_OFFSET is required to support * packet pacing and already checked above. @@ -1720,13 +1743,19 @@ err_secondary: priv->drop_queue.hrxq = mlx5_drop_action_create(eth_dev); if (!priv->drop_queue.hrxq) goto error; - /* Supported Verbs flow priority number detection. */ - err = mlx5_flow_discover_priorities(eth_dev); + /* Port representor shares the same max priority with pf port. */ + if (!priv->sh->flow_priority_check_flag) { + /* Supported Verbs flow priority number detection. */ + err = mlx5_flow_discover_priorities(eth_dev); + priv->sh->flow_max_priority = err; + priv->sh->flow_priority_check_flag = 1; + } else { + err = priv->sh->flow_max_priority; + } if (err < 0) { err = -err; goto error; } - priv->config.flow_prio = err; if (!priv->config.dv_esw_en && priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) { DRV_LOG(WARNING, "metadata mode %u is not supported " @@ -1752,10 +1781,12 @@ err_secondary: goto error; rte_rwlock_init(&priv->ind_tbls_lock); /* Query availability of metadata reg_c's. */ - err = mlx5_flow_discover_mreg_c(eth_dev); - if (err < 0) { - err = -err; - goto error; + if (!priv->sh->metadata_regc_check_flag) { + err = mlx5_flow_discover_mreg_c(eth_dev); + if (err < 0) { + err = -err; + goto error; + } } if (!mlx5_flow_ext_mreg_supported(eth_dev)) { DRV_LOG(DEBUG, @@ -1810,6 +1841,8 @@ error: claim_zero(rte_eth_switch_domain_free(priv->domain_id)); if (priv->hrxqs) mlx5_list_destroy(priv->hrxqs); + if (eth_dev && priv->flex_item_map) + mlx5_flex_item_port_cleanup(eth_dev); mlx5_free(priv); if (eth_dev != NULL) eth_dev->data->dev_private = NULL; @@ -1898,6 +1931,8 @@ mlx5_device_bond_pci_match(const char *ibdev_name, FILE *bond_file = NULL, *file; int pf = -1; int ret; + uint8_t cur_guid[32] = {0}; + uint8_t guid[32] = {0}; /* * Try to get master device name. If something goes wrong suppose @@ -1911,6 +1946,8 @@ mlx5_device_bond_pci_match(const char *ibdev_name, np = mlx5_nl_portnum(nl_rdma, ibdev_name); if (!np) return -1; + if (mlx5_get_device_guid(pci_dev, cur_guid, sizeof(cur_guid)) < 0) + return -1; /* * The master device might not be on the predefined port(not on port * index 1, it is not guaranteed), we have to scan all Infiniband @@ -1938,6 +1975,7 @@ mlx5_device_bond_pci_match(const char *ibdev_name, char tmp_str[IF_NAMESIZE + 32]; struct rte_pci_addr pci_addr; struct mlx5_switch_info info; + int ret; /* Process slave interface names in the loop. */ snprintf(tmp_str, sizeof(tmp_str), @@ -1969,15 +2007,6 @@ mlx5_device_bond_pci_match(const char *ibdev_name, tmp_str); break; } - /* Match PCI address, allows BDF0+pfx or BDFx+pfx. */ - if (pci_dev->domain == pci_addr.domain && - pci_dev->bus == pci_addr.bus && - pci_dev->devid == pci_addr.devid && - ((pci_dev->function == 0 && - pci_dev->function + owner == pci_addr.function) || - (pci_dev->function == owner && - pci_addr.function == owner))) - pf = info.port_name; /* Get ifindex. */ snprintf(tmp_str, sizeof(tmp_str), "/sys/class/net/%s/ifindex", ifname); @@ -1994,6 +2023,30 @@ mlx5_device_bond_pci_match(const char *ibdev_name, bond_info->ports[info.port_name].pci_addr = pci_addr; bond_info->ports[info.port_name].ifindex = ifindex; bond_info->n_port++; + /* + * Under socket direct mode, bonding will use + * system_image_guid as identification. + * After OFED 5.4, guid is readable (ret >= 0) under sysfs. + * All bonding members should have the same guid even if driver + * is using PCIe BDF. + */ + ret = mlx5_get_device_guid(&pci_addr, guid, sizeof(guid)); + if (ret < 0) + break; + else if (ret > 0) { + if (!memcmp(guid, cur_guid, sizeof(guid)) && + owner == info.port_name && + (owner != 0 || (owner == 0 && + !rte_pci_addr_cmp(pci_dev, &pci_addr)))) + pf = info.port_name; + } else if (pci_dev->domain == pci_addr.domain && + pci_dev->bus == pci_addr.bus && + pci_dev->devid == pci_addr.devid && + ((pci_dev->function == 0 && + pci_dev->function + owner == pci_addr.function) || + (pci_dev->function == owner && + pci_addr.function == owner))) + pf = info.port_name; } if (pf >= 0) { /* Get bond interface info */ @@ -2006,6 +2059,11 @@ mlx5_device_bond_pci_match(const char *ibdev_name, DRV_LOG(INFO, "PF device %u, bond device %u(%s)", ifindex, bond_info->ifindex, bond_info->ifname); } + if (owner == 0 && pf != 0) { + DRV_LOG(INFO, "PCIe instance %04x:%02x:%02x.%x isn't bonding owner", + pci_dev->domain, pci_dev->bus, pci_dev->devid, + pci_dev->function); + } return pf; } @@ -2027,6 +2085,8 @@ mlx5_os_config_default(struct mlx5_dev_config *config) config->decap_en = 1; config->log_hp_size = MLX5_ARG_UNSET; config->allow_duplicate_pattern = 1; + config->std_delay_drop = 0; + config->hp_delay_drop = 0; } /** @@ -2240,7 +2300,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, /* * Force standalone bonding * device for ROCE LAG - * confgiurations. + * configurations. */ list[ns].info.master = 0; list[ns].info.representor = 0; @@ -2458,11 +2518,9 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, * Representor interrupts handle is released in mlx5_dev_stop(). */ if (list[i].info.representor) { - struct rte_intr_handle *intr_handle; - intr_handle = mlx5_malloc(MLX5_MEM_SYS | MLX5_MEM_ZERO, - sizeof(*intr_handle), 0, - SOCKET_ID_ANY); - if (!intr_handle) { + struct rte_intr_handle *intr_handle = + rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED); + if (intr_handle == NULL) { DRV_LOG(ERR, "port %u failed to allocate memory for interrupt handler " "Rx interrupts will not be supported", @@ -2579,7 +2637,7 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev) } if (ret) { DRV_LOG(ERR, "Probe of PCI device " PCI_PRI_FMT " " - "aborted due to proding failure of PF %u", + "aborted due to prodding failure of PF %u", pci_dev->addr.domain, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function, eth_da.ports[p]); @@ -2626,7 +2684,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev) if (eth_dev == NULL) return -rte_errno; /* Post create. */ - eth_dev->intr_handle = &adev->intr_handle; + eth_dev->intr_handle = adev->intr_handle; if (rte_eal_process_type() == RTE_PROC_PRIMARY) { eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV; @@ -2690,24 +2748,38 @@ mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh) int flags; struct ibv_context *ctx = sh->cdev->ctx; - sh->intr_handle.fd = -1; + sh->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED); + if (sh->intr_handle == NULL) { + DRV_LOG(ERR, "Fail to allocate intr_handle"); + rte_errno = ENOMEM; + return; + } + rte_intr_fd_set(sh->intr_handle, -1); + flags = fcntl(ctx->async_fd, F_GETFL); ret = fcntl(ctx->async_fd, F_SETFL, flags | O_NONBLOCK); if (ret) { DRV_LOG(INFO, "failed to change file descriptor async event" " queue"); } else { - sh->intr_handle.fd = ctx->async_fd; - sh->intr_handle.type = RTE_INTR_HANDLE_EXT; - if (rte_intr_callback_register(&sh->intr_handle, + rte_intr_fd_set(sh->intr_handle, ctx->async_fd); + rte_intr_type_set(sh->intr_handle, RTE_INTR_HANDLE_EXT); + if (rte_intr_callback_register(sh->intr_handle, mlx5_dev_interrupt_handler, sh)) { DRV_LOG(INFO, "Fail to install the shared interrupt."); - sh->intr_handle.fd = -1; + rte_intr_fd_set(sh->intr_handle, -1); } } if (sh->devx) { #ifdef HAVE_IBV_DEVX_ASYNC - sh->intr_handle_devx.fd = -1; + sh->intr_handle_devx = + rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED); + if (!sh->intr_handle_devx) { + DRV_LOG(ERR, "Fail to allocate intr_handle"); + rte_errno = ENOMEM; + return; + } + rte_intr_fd_set(sh->intr_handle_devx, -1); sh->devx_comp = (void *)mlx5_glue->devx_create_cmd_comp(ctx); struct mlx5dv_devx_cmd_comp *devx_comp = sh->devx_comp; if (!devx_comp) { @@ -2721,13 +2793,14 @@ mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh) " devx comp"); return; } - sh->intr_handle_devx.fd = devx_comp->fd; - sh->intr_handle_devx.type = RTE_INTR_HANDLE_EXT; - if (rte_intr_callback_register(&sh->intr_handle_devx, + rte_intr_fd_set(sh->intr_handle_devx, devx_comp->fd); + rte_intr_type_set(sh->intr_handle_devx, + RTE_INTR_HANDLE_EXT); + if (rte_intr_callback_register(sh->intr_handle_devx, mlx5_dev_interrupt_handler_devx, sh)) { DRV_LOG(INFO, "Fail to install the devx shared" " interrupt."); - sh->intr_handle_devx.fd = -1; + rte_intr_fd_set(sh->intr_handle_devx, -1); } #endif /* HAVE_IBV_DEVX_ASYNC */ } @@ -2744,13 +2817,15 @@ mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh) void mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh) { - if (sh->intr_handle.fd >= 0) - mlx5_intr_callback_unregister(&sh->intr_handle, + if (rte_intr_fd_get(sh->intr_handle) >= 0) + mlx5_intr_callback_unregister(sh->intr_handle, mlx5_dev_interrupt_handler, sh); + rte_intr_instance_free(sh->intr_handle); #ifdef HAVE_IBV_DEVX_ASYNC - if (sh->intr_handle_devx.fd >= 0) - rte_intr_callback_unregister(&sh->intr_handle_devx, + if (rte_intr_fd_get(sh->intr_handle_devx) >= 0) + rte_intr_callback_unregister(sh->intr_handle_devx, mlx5_dev_interrupt_handler_devx, sh); + rte_intr_instance_free(sh->intr_handle_devx); if (sh->devx_comp) mlx5_glue->devx_destroy_cmd_comp(sh->devx_comp); #endif