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

Reply via email to