In order to return the network interface index (ifindex) associated with a device, mlx5_ifindex() uses if_nametoindex() to convert the result of mlx5_get_ifname(). This is inefficient because the latter first retrieves ifindex on its own to pass it through if_indextoname().
Since indices are much more reliable than names (less prone to change) and involved in flow rule management where performance matters, this patch moves ifindex-getting code directly into mlx5_ifindex() and replaces remaining mlx5_get_ifname() calls with if_indextoname(). Similarly, the new function mlx5_master_ifindex() replaces mlx5_get_master_ifname() while getting rid of irrelevant compatibility code for unsupported Linux and MLNX_OFED versions. Signed-off-by: Adrien Mazarguil <adrien.mazarg...@6wind.com> --- drivers/net/mlx5/mlx5.c | 15 +-- drivers/net/mlx5/mlx5.h | 3 - drivers/net/mlx5/mlx5_ethdev.c | 184 ++++++++++++++---------------------- 3 files changed, 74 insertions(+), 128 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 55b73a03b..1414ce0c5 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -734,7 +734,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, struct ibv_counter_set_description cs_desc = { .counter_type = 0 }; #endif struct ether_addr mac; - char name[RTE_ETH_NAME_MAX_LEN]; + char name[RTE_MAX(IF_NAMESIZE, RTE_ETH_NAME_MAX_LEN)]; int own_domain_id = 0; struct rte_flow_error flow_error; unsigned int i; @@ -1116,16 +1116,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, mac.addr_bytes[2], mac.addr_bytes[3], mac.addr_bytes[4], mac.addr_bytes[5]); #ifndef NDEBUG - { - char ifname[IF_NAMESIZE]; - - if (mlx5_get_ifname(eth_dev, &ifname) == 0) - DRV_LOG(DEBUG, "port %u ifname is \"%s\"", - eth_dev->data->port_id, ifname); - else - DRV_LOG(DEBUG, "port %u ifname is unknown", - eth_dev->data->port_id); - } + DRV_LOG(DEBUG, "port %u ifname is \"%s\"", + eth_dev->data->port_id, + if_indextoname(priv->ifindex, name) ? name : ""); #endif /* Get actual MTU if possible. */ err = mlx5_get_mtu(eth_dev, &priv->mtu); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 4c2dec644..0807cf689 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -241,9 +241,6 @@ int mlx5_getenv_int(const char *); /* mlx5_ethdev.c */ -int mlx5_get_master_ifname(const struct rte_eth_dev *dev, - char (*ifname)[IF_NAMESIZE]); -int mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]); unsigned int mlx5_ifindex(const struct rte_eth_dev *dev); int mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr, int master); diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index cf0b415b2..67149b7b3 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -119,149 +119,104 @@ struct ethtool_link_settings { #endif /** - * Get master interface name from private structure. + * Get network interface index associated with master device. + * + * Result differs from mlx5_ifindex() when the current device is a port + * representor. * * @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. + * Nonzero interface index on success, zero otherwise and rte_errno is set. */ -int -mlx5_get_master_ifname(const struct rte_eth_dev *dev, - char (*ifname)[IF_NAMESIZE]) +static unsigned int +mlx5_master_ifindex(const struct rte_eth_dev *dev) { struct priv *priv = dev->data->dev_private; - DIR *dir; - struct dirent *dent; - unsigned int dev_type = 0; - unsigned int dev_port_prev = ~0u; - char match[IF_NAMESIZE] = ""; - - { - MKSTR(path, "%s/device/net", priv->ibdev_path); - - dir = opendir(path); - if (dir == NULL) { - rte_errno = errno; - return -rte_errno; - } - } - while ((dent = readdir(dir)) != NULL) { - char *name = dent->d_name; - FILE *file; - unsigned int dev_port; - int r; - - if ((name[0] == '.') && - ((name[1] == '\0') || - ((name[1] == '.') && (name[2] == '\0')))) - continue; + DIR *dir = NULL; + struct dirent *dent = NULL; + size_t size = 0; + unsigned int ifindex = 0; - MKSTR(path, "%s/device/net/%s/%s", - priv->ibdev_path, name, - (dev_type ? "dev_id" : "dev_port")); + while (1) { + char path[size]; + FILE *file; + int ret; - file = fopen(path, "rb"); - if (file == NULL) { - if (errno != ENOENT) - continue; - /* - * Switch to dev_id when dev_port does not exist as - * is the case with Linux kernel versions < 3.15. - */ -try_dev_id: - match[0] = '\0'; - if (dev_type) - break; - dev_type = 1; - dev_port_prev = ~0u; - rewinddir(dir); + ret = snprintf(path, size, "%s/device/net/%s%s", + priv->ibdev_path, + dent ? dent->d_name : "", + dent ? "/ifindex" : ""); + if (ret == -1) + goto error; + if (!size) { + size = ret + 1; continue; } - r = fscanf(file, (dev_type ? "%x" : "%u"), &dev_port); - fclose(file); - if (r != 1) - continue; - /* - * Switch to dev_id when dev_port returns the same value for - * all ports. May happen when using a MOFED release older than - * 3.0 with a Linux kernel >= 3.15. - */ - if (dev_port == dev_port_prev) - goto try_dev_id; - dev_port_prev = dev_port; - if (dev_port == 0) - strlcpy(match, name, sizeof(match)); - } + if (!dir) { + dir = opendir(path); + if (!dir) + goto error; + } + file = dent ? fopen(path, "rb") : NULL; + if (file) { + /* Only one ifindex is expected in there. */ + ret = !!ifindex; + if (fscanf(file, "%u", &ifindex) != 1) + ret = 0; + fclose(file); + if (ret) { + errno = ENOTSUP; + goto error; + } + } + do { + dent = readdir(dir); + } while (dent && + (!strcmp(dent->d_name, ".") || + !strcmp(dent->d_name, ".."))); + if (!dent) + break; + size = 0; + }; closedir(dir); - if (match[0] == '\0') { - rte_errno = ENOENT; - return -rte_errno; - } - strncpy(*ifname, match, sizeof(*ifname)); + if (!ifindex) + rte_errno = ENXIO; + return ifindex; +error: + rte_errno = errno; + if (dir) + closedir(dir); return 0; } /** - * Get interface name from private structure. - * - * This is a port representor-aware version of mlx5_get_master_ifname(). + * Get network interface index associated with device. * * @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. + * Nonzero interface index on success, zero otherwise and rte_errno is set. */ -int -mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]) +unsigned int +mlx5_ifindex(const struct rte_eth_dev *dev) { struct priv *priv = dev->data->dev_private; unsigned int ifindex = priv->nl_socket_rdma >= 0 ? mlx5_nl_ifindex(priv->nl_socket_rdma, priv->ibdev_name) : 0; - if (!ifindex) { - if (!priv->representor) - return mlx5_get_master_ifname(dev, ifname); - rte_errno = ENXIO; - return -rte_errno; - } - if (if_indextoname(ifindex, &(*ifname)[0])) - return 0; - rte_errno = errno; + if (ifindex) + return ifindex; + if (!priv->representor) + return mlx5_master_ifindex(dev); + rte_errno = ENXIO; return -rte_errno; } /** - * Get the interface index from device name. - * - * @param[in] dev - * Pointer to Ethernet device. - * - * @return - * Nonzero interface index on success, zero otherwise and rte_errno is set. - */ -unsigned int -mlx5_ifindex(const struct rte_eth_dev *dev) -{ - char ifname[IF_NAMESIZE]; - unsigned int ifindex; - - if (mlx5_get_ifname(dev, &ifname)) - return 0; - ifindex = if_nametoindex(ifname); - if (!ifindex) - rte_errno = errno; - return ifindex; -} - -/** * Perform ifreq ioctl() on associated Ethernet device. * * @param[in] dev @@ -282,17 +237,18 @@ mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr, int master) { int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - int ret = 0; + unsigned int ifindex; + int ret; if (sock == -1) { rte_errno = errno; return -rte_errno; } if (master) - ret = mlx5_get_master_ifname(dev, &ifr->ifr_name); + ifindex = mlx5_master_ifindex(dev); else - ret = mlx5_get_ifname(dev, &ifr->ifr_name); - if (ret) + ifindex = mlx5_ifindex(dev); + if (!ifindex || !if_indextoname(ifindex, ifr->ifr_name)) goto error; ret = ioctl(sock, req, ifr); if (ret == -1) { -- 2.11.0