X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_ethdev.c;h=9629cfb333b3ab8cec612817efc4a1182e940e55;hb=8d0715f054b44750c2e1553d6af29487bcea25d8;hp=eeefe4df3cd4813eab844f9018bbf438dbdce8d6;hpb=cb1d2cce9539f1131a01585888903ab3546d51d9;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index eeefe4df3c..9629cfb333 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -225,10 +225,7 @@ mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]) assert(priv); assert(priv->sh); - ifindex = priv->nl_socket_rdma >= 0 ? - mlx5_nl_ifindex(priv->nl_socket_rdma, - priv->sh->ibdev_name, - priv->ibv_port) : 0; + ifindex = mlx5_ifindex(dev); if (!ifindex) { if (!priv->representor) return mlx5_get_master_ifname(priv->sh->ibdev_path, @@ -242,51 +239,6 @@ mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]) return -rte_errno; } -/** - * Get interface name for the specified device, uses the extra base - * device resources to perform Netlink requests. - * - * This is a port representor-aware version of mlx5_get_master_ifname(). - * - * @param[in] base - * Pointer to Ethernet device to use Netlink socket from - * to perfrom requests. - * @param[in] dev - * Pointer to Ethernet device. - * @param[out] ifname - * Interface name output buffer. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_get_ifname_base(const struct rte_eth_dev *base, - const struct rte_eth_dev *dev, - char (*ifname)[IF_NAMESIZE]) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_priv *priv_base = base->data->dev_private; - unsigned int ifindex; - - assert(priv); - assert(priv->sh); - assert(priv_base); - ifindex = priv_base->nl_socket_rdma >= 0 ? - mlx5_nl_ifindex(priv_base->nl_socket_rdma, - priv->sh->ibdev_name, - priv->ibv_port) : 0; - if (!ifindex) { - if (!priv->representor) - return mlx5_get_master_ifname(priv->sh->ibdev_path, - ifname); - rte_errno = ENXIO; - return -rte_errno; - } - if (if_indextoname(ifindex, &(*ifname)[0])) - return 0; - rte_errno = errno; - return -rte_errno; -} /** * Get the interface index from device name. * @@ -299,14 +251,14 @@ mlx5_get_ifname_base(const struct rte_eth_dev *base, unsigned int mlx5_ifindex(const struct rte_eth_dev *dev) { - char ifname[IF_NAMESIZE]; + struct mlx5_priv *priv = dev->data->dev_private; unsigned int ifindex; - if (mlx5_get_ifname(dev, &ifname)) - return 0; - ifindex = if_nametoindex(ifname); + assert(priv); + assert(priv->if_index); + ifindex = priv->if_index; if (!ifindex) - rte_errno = errno; + rte_errno = ENXIO; return ifindex; } @@ -348,51 +300,6 @@ error: return -rte_errno; } -/** - * Perform ifreq ioctl() on specified Ethernet device, - * ifindex, name and other attributes are requested - * on the base device to avoid specified device Netlink - * socket sharing (this is not thread-safe). - * - * @param[in] base - * Pointer to Ethernet device to get dev attributes. - * @param[in] dev - * Pointer to Ethernet device to perform ioctl. - * @param req - * Request number to pass to ioctl(). - * @param[out] ifr - * Interface request structure output buffer. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_ifreq_base(const struct rte_eth_dev *base, - const struct rte_eth_dev *dev, - int req, struct ifreq *ifr) -{ - int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - int ret = 0; - - if (sock == -1) { - rte_errno = errno; - return -rte_errno; - } - ret = mlx5_get_ifname_base(base, dev, &ifr->ifr_name); - if (ret) - goto error; - ret = ioctl(sock, req, ifr); - if (ret == -1) { - rte_errno = errno; - goto error; - } - close(sock); - return 0; -error: - close(sock); - return -rte_errno; -} - /** * Get device MTU. * @@ -591,6 +498,42 @@ mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) } } +/** + * Sets tx mbuf limiting parameters. + * + * @param dev + * Pointer to Ethernet device. + * @param[out] info + * Info structure output buffer. + */ +static void +mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_config *config = &priv->config; + unsigned int inlen; + uint16_t nb_max; + + inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ? + MLX5_SEND_DEF_INLINE_LEN : + (unsigned int)config->txq_inline_max; + assert(config->txq_inline_min >= 0); + inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min); + inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX + + MLX5_ESEG_MIN_INLINE_SIZE - + MLX5_WQE_CSEG_SIZE - + MLX5_WQE_ESEG_SIZE - + MLX5_WQE_DSEG_SIZE * 2); + nb_max = (MLX5_WQE_SIZE_MAX + + MLX5_ESEG_MIN_INLINE_SIZE - + MLX5_WQE_CSEG_SIZE - + MLX5_WQE_ESEG_SIZE - + MLX5_WQE_DSEG_SIZE - + inlen) / MLX5_WSEG_SIZE; + info->tx_desc_lim.nb_seg_max = nb_max; + info->tx_desc_lim.nb_mtu_seg_max = nb_max; +} + /** * DPDK callback to get information about the device. * @@ -605,7 +548,6 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_dev_config *config = &priv->config; unsigned int max; - char ifname[IF_NAMESIZE]; /* FIXME: we should ask the device for these values. */ info->min_rx_bufsize = 32; @@ -626,14 +568,14 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) info->rx_offload_capa = (mlx5_get_rx_port_offloads() | info->rx_queue_offload_capa); info->tx_offload_capa = mlx5_get_tx_port_offloads(dev); - if (mlx5_get_ifname(dev, &ifname) == 0) - info->if_index = if_nametoindex(ifname); + info->if_index = mlx5_ifindex(dev); info->reta_size = priv->reta_idx_n ? priv->reta_idx_n : config->ind_table_max_size; info->hash_key_size = MLX5_RSS_HASH_KEY_LEN; info->speed_capa = priv->link_speed_capa; info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK; mlx5_set_default_params(dev, info); + mlx5_set_txlimit_params(dev, info); info->switch_info.name = dev->data->name; info->switch_info.domain_id = priv->domain_id; info->switch_info.port_id = priv->representor_id; @@ -840,15 +782,7 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev, ifr = (struct ifreq) { .ifr_data = (void *)&edata, }; - /* - * Use special version of mlx5_ifreq() - * to get master device name with local - * device Netlink socket. Using master - * device Netlink socket is not thread - * safe. - */ - ret = mlx5_ifreq_base(dev, master, - SIOCETHTOOL, &ifr); + ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr); } } if (ret) { @@ -945,12 +879,7 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, ifr = (struct ifreq) { .ifr_data = (void *)&gcmd, }; - /* - * Avoid using master Netlink socket. - * This is not thread-safe. - */ - ret = mlx5_ifreq_base(dev, master, - SIOCETHTOOL, &ifr); + ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr); } } if (ret) { @@ -971,7 +900,7 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, *ecmd = gcmd; ifr.ifr_data = (void *)ecmd; - ret = mlx5_ifreq_base(dev, master ? master : dev, SIOCETHTOOL, &ifr); + ret = mlx5_ifreq(master ? master : dev, SIOCETHTOOL, &ifr); if (ret) { DRV_LOG(DEBUG, "port %u ioctl(SIOCETHTOOL," @@ -1432,6 +1361,38 @@ mlx5_intr_callback_unregister(const struct rte_intr_handle *handle, } while (true); } +/** + * Handle DEVX interrupts from the NIC. + * This function is probably called from the DPDK host thread. + * + * @param cb_arg + * Callback argument. + */ +void +mlx5_dev_interrupt_handler_devx(void *cb_arg) +{ +#ifndef HAVE_IBV_DEVX_ASYNC + (void)cb_arg; + return; +#else + struct mlx5_ibv_shared *sh = cb_arg; + union { + struct mlx5dv_devx_async_cmd_hdr cmd_resp; + uint8_t buf[MLX5_ST_SZ_BYTES(query_flow_counter_out) + + MLX5_ST_SZ_BYTES(traffic_counter) + + sizeof(struct mlx5dv_devx_async_cmd_hdr)]; + } out; + uint8_t *buf = out.buf + sizeof(out.cmd_resp); + + while (!mlx5_glue->devx_get_async_cmd_comp(sh->devx_comp, + &out.cmd_resp, + sizeof(out.buf))) + mlx5_flow_async_pool_query_handle + (sh, (uint64_t)out.cmd_resp.wr_id, + mlx5_devx_get_out_command_status(buf)); +#endif /* HAVE_IBV_DEVX_ASYNC */ +} + /** * Uninstall shared asynchronous device events handler. * This function is implemented to support event sharing @@ -1464,6 +1425,17 @@ mlx5_dev_shared_handler_uninstall(struct rte_eth_dev *dev) mlx5_dev_interrupt_handler, sh); sh->intr_handle.fd = 0; sh->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + if (sh->intr_handle_devx.fd) { + rte_intr_callback_unregister(&sh->intr_handle_devx, + mlx5_dev_interrupt_handler_devx, + sh); + sh->intr_handle_devx.fd = 0; + sh->intr_handle_devx.type = RTE_INTR_HANDLE_UNKNOWN; + } + if (sh->devx_comp) { + mlx5_glue->devx_destroy_cmd_comp(sh->devx_comp); + sh->devx_comp = NULL; + } exit: pthread_mutex_unlock(&sh->intr_mutex); } @@ -1507,17 +1479,50 @@ mlx5_dev_shared_handler_install(struct rte_eth_dev *dev) if (ret) { DRV_LOG(INFO, "failed to change file descriptor" " async event queue"); - /* Indicate there will be no interrupts. */ - dev->data->dev_conf.intr_conf.lsc = 0; - dev->data->dev_conf.intr_conf.rmv = 0; - sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS; - goto exit; + goto error; } sh->intr_handle.fd = sh->ctx->async_fd; sh->intr_handle.type = RTE_INTR_HANDLE_EXT; rte_intr_callback_register(&sh->intr_handle, mlx5_dev_interrupt_handler, sh); + if (priv->config.devx) { +#ifndef HAVE_IBV_DEVX_ASYNC + goto error_unregister; +#else + sh->devx_comp = mlx5_glue->devx_create_cmd_comp(sh->ctx); + if (sh->devx_comp) { + flags = fcntl(sh->devx_comp->fd, F_GETFL); + ret = fcntl(sh->devx_comp->fd, F_SETFL, + flags | O_NONBLOCK); + if (ret) { + DRV_LOG(INFO, "failed to change file descriptor" + " devx async event queue"); + goto error_unregister; + } + sh->intr_handle_devx.fd = sh->devx_comp->fd; + sh->intr_handle_devx.type = RTE_INTR_HANDLE_EXT; + rte_intr_callback_register + (&sh->intr_handle_devx, + mlx5_dev_interrupt_handler_devx, sh); + } else { + DRV_LOG(INFO, "failed to create devx async command " + "completion"); + goto error_unregister; + } +#endif /* HAVE_IBV_DEVX_ASYNC */ + } sh->intr_cnt++; + goto exit; +error_unregister: + rte_intr_callback_unregister(&sh->intr_handle, + mlx5_dev_interrupt_handler, sh); +error: + /* Indicate there will be no interrupts. */ + dev->data->dev_conf.intr_conf.lsc = 0; + dev->data->dev_conf.intr_conf.rmv = 0; + sh->intr_handle.fd = 0; + sh->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS; exit: pthread_mutex_unlock(&sh->intr_mutex); } @@ -1576,64 +1581,6 @@ mlx5_set_link_up(struct rte_eth_dev *dev) return mlx5_set_flags(dev, ~IFF_UP, IFF_UP); } -/** - * Configure the TX function to use. - * - * @param dev - * Pointer to private data structure. - * - * @return - * Pointer to selected Tx burst function. - */ -eth_tx_burst_t -mlx5_select_tx_function(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - eth_tx_burst_t tx_pkt_burst = mlx5_tx_burst; - struct mlx5_dev_config *config = &priv->config; - uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads; - int tso = !!(tx_offloads & (DEV_TX_OFFLOAD_TCP_TSO | - DEV_TX_OFFLOAD_VXLAN_TNL_TSO | - DEV_TX_OFFLOAD_GRE_TNL_TSO | - DEV_TX_OFFLOAD_IP_TNL_TSO | - DEV_TX_OFFLOAD_UDP_TNL_TSO)); - int swp = !!(tx_offloads & (DEV_TX_OFFLOAD_IP_TNL_TSO | - DEV_TX_OFFLOAD_UDP_TNL_TSO | - DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)); - int vlan_insert = !!(tx_offloads & DEV_TX_OFFLOAD_VLAN_INSERT); - - assert(priv != NULL); - /* Select appropriate TX function. */ - if (vlan_insert || tso || swp) - return tx_pkt_burst; - if (config->mps == MLX5_MPW_ENHANCED) { - if (mlx5_check_vec_tx_support(dev) > 0) { - if (mlx5_check_raw_vec_tx_support(dev) > 0) - tx_pkt_burst = mlx5_tx_burst_raw_vec; - else - tx_pkt_burst = mlx5_tx_burst_vec; - DRV_LOG(DEBUG, - "port %u selected enhanced MPW Tx vectorized" - " function", - dev->data->port_id); - } else { - tx_pkt_burst = mlx5_tx_burst_empw; - DRV_LOG(DEBUG, - "port %u selected enhanced MPW Tx function", - dev->data->port_id); - } - } else if (config->mps && (config->txq_inline > 0)) { - tx_pkt_burst = mlx5_tx_burst_mpw_inline; - DRV_LOG(DEBUG, "port %u selected MPW inline Tx function", - dev->data->port_id); - } else if (config->mps) { - tx_pkt_burst = mlx5_tx_burst_mpw; - DRV_LOG(DEBUG, "port %u selected MPW Tx function", - dev->data->port_id); - } - return tx_pkt_burst; -} - /** * Configure the RX function to use. *