net/mlx5: support list of representor PF
authorXueming Li <xuemingl@nvidia.com>
Sun, 28 Mar 2021 13:48:11 +0000 (13:48 +0000)
committerRaslan Darawsheh <rasland@nvidia.com>
Wed, 31 Mar 2021 07:16:30 +0000 (09:16 +0200)
To probe representors from different kernel bonding PFs, had to specify
2 separate devargs like this:
    -a 03:00.0,representor=pf0vf[0-3] -a 03:00.0,representor=pf1vf[0-3]

This patch supports range or list of PF section in devargs, so the
alternative short devargs of above is:
    -a 03:00.0,representor=pf[0-1]vf[0-3]

Signed-off-by: Xueming Li <xuemingl@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
doc/guides/nics/mlx5.rst
drivers/net/mlx5/linux/mlx5_os.c

index 92fe7c1..b39bc47 100644 (file)
@@ -944,6 +944,10 @@ Driver options
 
     <PCI_BDF>,representor=sf[0-2]
 
+  To probe VF port representors 0 through 2 on both PFs of bonding device::
+
+    <Primary_PCI_BDF>,representor=pf[0,1]vf[0-2]
+
 - ``max_dump_files_num`` parameter [int]
 
   The maximum number of files per PMD entity that may be created for debug information.
index 40ad9b7..46e04f6 100644 (file)
@@ -1839,21 +1839,25 @@ mlx5_device_bond_pci_match(const struct ibv_device *ibv_dev,
 }
 
 /**
- * DPDK callback to register a PCI device.
+ * Register a PCI device within bonding.
  *
- * This function spawns Ethernet devices out of a given PCI device.
+ * This function spawns Ethernet devices out of a given PCI device and
+ * bonding owner PF index.
  *
- * @param[in] pci_drv
- *   PCI driver structure (mlx5_driver).
  * @param[in] pci_dev
  *   PCI device information.
+ * @param[in] req_eth_da
+ *   Requested ethdev device argument.
+ * @param[in] owner_id
+ *   Requested owner PF port ID within bonding device, default to 0.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-int
-mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
-                 struct rte_pci_device *pci_dev)
+static int
+mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev,
+                    struct rte_eth_devargs *req_eth_da,
+                    uint16_t owner_id)
 {
        struct ibv_device **ibv_list;
        /*
@@ -1883,7 +1887,7 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        struct mlx5_dev_spawn_data *list = NULL;
        struct mlx5_dev_config dev_config;
        unsigned int dev_config_vf;
-       struct rte_eth_devargs eth_da = { .type = RTE_ETH_REPRESENTOR_NONE };
+       struct rte_eth_devargs eth_da = *req_eth_da;
        struct rte_pci_addr owner_pci = pci_dev->addr; /* Owner PF. */
        int ret = -1;
 
@@ -1895,27 +1899,6 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        strerror(rte_errno));
                return -rte_errno;
        }
-       if (pci_dev->device.devargs) {
-               /* Parse representor information from device argument. */
-               if (pci_dev->device.devargs->cls_str)
-                       ret = rte_eth_devargs_parse
-                               (pci_dev->device.devargs->cls_str, &eth_da);
-               if (ret) {
-                       DRV_LOG(ERR, "failed to parse device arguments: %s",
-                               pci_dev->device.devargs->cls_str);
-                       return -rte_errno;
-               }
-               if (eth_da.type == RTE_ETH_REPRESENTOR_NONE) {
-                       /* Support legacy device argument */
-                       ret = rte_eth_devargs_parse
-                               (pci_dev->device.devargs->args, &eth_da);
-                       if (ret) {
-                               DRV_LOG(ERR, "failed to parse device arguments: %s",
-                                       pci_dev->device.devargs->args);
-                               return -rte_errno;
-                       }
-               }
-       }
        errno = 0;
        ibv_list = mlx5_glue->get_device_list(&ret);
        if (!ibv_list) {
@@ -1937,8 +1920,7 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
                DRV_LOG(DEBUG, "checking device \"%s\"", ibv_list[ret]->name);
                bd = mlx5_device_bond_pci_match
-                               (ibv_list[ret], &owner_pci, nl_rdma,
-                                eth_da.ports[0]);
+                               (ibv_list[ret], &owner_pci, nl_rdma, owner_id);
                if (bd >= 0) {
                        /*
                         * Bonding device detected. Only one match is allowed,
@@ -1957,7 +1939,7 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        }
                        /* Amend owner pci address if owner PF ID specified. */
                        if (eth_da.nb_representor_ports)
-                               owner_pci.function += eth_da.ports[0];
+                               owner_pci.function += owner_id;
                        DRV_LOG(INFO, "PCI information matches for"
                                      " slave %d bonding device \"%s\"",
                                      bd, ibv_list[ret]->name);
@@ -2345,6 +2327,60 @@ exit:
        return ret;
 }
 
+/**
+ * DPDK callback to register a PCI device.
+ *
+ * This function spawns Ethernet devices out of a given PCI device.
+ *
+ * @param[in] pci_drv
+ *   PCI driver structure (mlx5_driver).
+ * @param[in] pci_dev
+ *   PCI device information.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+                 struct rte_pci_device *pci_dev)
+{
+       struct rte_eth_devargs eth_da = { .type = RTE_ETH_REPRESENTOR_NONE };
+       int ret = 0;
+       uint16_t p;
+
+       if (pci_dev->device.devargs) {
+               /* Parse representor information from device argument. */
+               if (pci_dev->device.devargs->cls_str)
+                       ret = rte_eth_devargs_parse
+                               (pci_dev->device.devargs->cls_str, &eth_da);
+               if (ret) {
+                       DRV_LOG(ERR, "failed to parse device arguments: %s",
+                               pci_dev->device.devargs->cls_str);
+                       return -rte_errno;
+               }
+               if (eth_da.type == RTE_ETH_REPRESENTOR_NONE) {
+                       /* Support legacy device argument */
+                       ret = rte_eth_devargs_parse
+                               (pci_dev->device.devargs->args, &eth_da);
+                       if (ret) {
+                               DRV_LOG(ERR, "failed to parse device arguments: %s",
+                                       pci_dev->device.devargs->args);
+                               return -rte_errno;
+                       }
+               }
+       }
+
+       if (eth_da.nb_ports > 0) {
+               /* Iterate all port if devargs pf is range: "pf[0-1]vf[...]". */
+               for (p = 0; p < eth_da.nb_ports; p++)
+                       ret = mlx5_os_pci_probe_pf(pci_dev, &eth_da,
+                                                  eth_da.ports[p]);
+       } else {
+               ret = mlx5_os_pci_probe_pf(pci_dev, &eth_da, 0);
+       }
+       return ret;
+}
+
 static int
 mlx5_config_doorbell_mapping_env(const struct mlx5_dev_config *config)
 {