From: Viacheslav Ovsiienko Date: Fri, 5 Apr 2019 13:25:55 +0000 (+0000) Subject: net/mlx5: fix device probing for old kernel drivers X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=9c2bbd048856f50297b3c2d751dd2ada7952b7f0;p=dpdk.git net/mlx5: fix device probing for old kernel drivers Retrieving network interface index via Netlink fails in case of old ib_core kernel driver installed - mlx5_nl_ifindex() routine fails due to RDMA_NLDEV_ATTR_NDEV_INDEX attribute is not supported by the old driver. The patch allowing to retrieve the network interface index and name via Netlink [1]. So, the problem depends on ib_core module version - 4.16 supports getting ifindex via Netlink, 4.15 does not. This error was ignored in previous versions of MLX5 PMD probing routine. For single device ifindex was retrieved via sysfs and link control was not lost, so problem just was not noticed. In order to support MLX5 PMD functioning over old kernel driver this patch adds ifindex retrieving via sysfs into probing routine. It is worth to note this method works for master/standalone device only. [1] https://www.spinics.net/lists/linux-rdma/msg62948.html Linux tree: 5b2cc79d (Leon Romanovsky 2018-03-27 20:40:49 +0300 270) Fixes: ad74bc619504 ("net/mlx5: support multiport IB device during probing") Signed-off-by: Viacheslav Ovsiienko Acked-by: Shahaf Shuler --- diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 09f4a214ef..b7e62349db 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1888,12 +1888,40 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, list[ns].ifindex = mlx5_nl_ifindex (nl_rdma, list[ns].ibv_dev->name, 1); if (!list[ns].ifindex) { + char ifname[IF_NAMESIZE]; + /* - * No network interface index found for the - * specified device, it means there it is not - * a representor/master. + * Netlink failed, it may happen with old + * ib_core kernel driver (before 4.16). + * We can assume there is old driver because + * here we are processing single ports IB + * devices. Let's try sysfs to retrieve + * the ifindex. The method works for + * master device only. */ - continue; + if (nd > 1) { + /* + * Multiple devices found, assume + * representors, can not distinguish + * master/representor and retrieve + * ifindex via sysfs. + */ + continue; + } + ret = mlx5_get_master_ifname + (ibv_match[i]->ibdev_path, &ifname); + if (!ret) + list[ns].ifindex = + if_nametoindex(ifname); + if (!list[ns].ifindex) { + /* + * No network interface index found + * for the specified device, it means + * there it is neither representor + * nor master. + */ + continue; + } } ret = -1; if (nl_route >= 0) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index ef05d9f975..c9b2251bf2 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -364,6 +364,7 @@ int mlx5_getenv_int(const char *); /* mlx5_ethdev.c */ int mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]); +int mlx5_get_master_ifname(const char *ibdev_path, 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 mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu); diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 9ae9dddd3c..1e6fe192a6 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -127,21 +127,18 @@ struct ethtool_link_settings { * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ -static int -mlx5_get_master_ifname(const struct rte_eth_dev *dev, - char (*ifname)[IF_NAMESIZE]) +int +mlx5_get_master_ifname(const char *ibdev_path, char (*ifname)[IF_NAMESIZE]) { - struct mlx5_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] = ""; - assert(priv); - assert(priv->sh); + assert(ibdev_path); { - MKSTR(path, "%s/device/net", priv->sh->ibdev_path); + MKSTR(path, "%s/device/net", ibdev_path); dir = opendir(path); if (dir == NULL) { @@ -161,7 +158,7 @@ mlx5_get_master_ifname(const struct rte_eth_dev *dev, continue; MKSTR(path, "%s/device/net/%s/%s", - priv->sh->ibdev_path, name, + ibdev_path, name, (dev_type ? "dev_id" : "dev_port")); file = fopen(path, "rb"); @@ -222,15 +219,18 @@ int mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]) { struct mlx5_priv *priv = dev->data->dev_private; - unsigned int ifindex = - priv->nl_socket_rdma >= 0 ? - mlx5_nl_ifindex(priv->nl_socket_rdma, - priv->sh->ibdev_name, - priv->ibv_port) : 0; + unsigned int ifindex; + 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; if (!ifindex) { if (!priv->representor) - return mlx5_get_master_ifname(dev, ifname); + return mlx5_get_master_ifname(priv->sh->ibdev_path, + ifname); rte_errno = ENXIO; return -rte_errno; }