[2/8] net/mlx5: clean up redundant interface name getters

Message ID 20180831092038.23051-3-adrien.mazarguil@6wind.com (mailing list archive)
State Superseded, archived
Headers
Series net/mlx5: add switch offload for VXLAN encap/decap |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Adrien Mazarguil Aug. 31, 2018, 9:57 a.m. UTC
  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.mazarguil@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(-)
  

Patch

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) {