Reviewed-by: Xueming Li <xuemi...@mellanox.com>

One minor issue we should be able to ignore.

> -----Original Message-----
> From: dev <dev-boun...@dpdk.org> On Behalf Of Adrien Mazarguil
> Sent: Thursday, June 14, 2018 4:35 PM
> To: Shahaf Shuler <shah...@mellanox.com>
> Cc: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2 5/7] net/mlx5: add port representor awareness
> 
> The current PCI probing method is not aware of Verbs port representors, which 
> appear as standard Verbs
> devices bound to the same PCI address and cannot be distinguished.
> 
> Problem is that more often than not, the wrong Verbs device is used, 
> resulting in unexpected traffic.
> 
> This patch adds necessary heuristics to bind affected driver instances to the 
> intended (i.e. non-
> representor) device.
> 
> (Patch based on prior work from Yuanhan Liu)
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarg...@6wind.com>
> --
> v2 changes:
> 
> - Fixed digit detection in mlx5_cmp_ibv_name() so that "foo1" and "foo10"
>   are compared on the integer conversion of "1" against "10" instead of ""
>   and "0".
> ---
>  drivers/net/mlx5/mlx5.c | 66 ++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 61 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 
> c9815d721..498f80c89 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -3,6 +3,7 @@
>   * Copyright 2015 Mellanox Technologies, Ltd
>   */
> 
> +#include <ctype.h>
>  #include <stddef.h>
>  #include <unistd.h>
>  #include <string.h>
> @@ -1170,6 +1171,34 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,  }
> 
>  /**
> + * Comparison callback to sort Verbs device names.
> + *
> + * This is meant to be used with qsort().
> + *
> + * @param a[in]
> + *   Pointer to pointer to first Verbs device.
> + * @param b[in]
> + *   Pointer to pointer to second Verbs device.
> + *
> + * @return
> + *   0 if both names are equal, less than 0 if the first argument is less
> + *   than the second, greater than 0 otherwise.
> + */
> +static int
> +mlx5_cmp_ibv_name(const void *a, const void *b) {
> +     const char *name_a = (*(const struct ibv_device *const *)a)->name;
> +     const char *name_b = (*(const struct ibv_device *const *)b)->name;
> +     size_t i = 0;
> +
> +     while (name_a[i] && name_a[i] == name_b[i])
> +             ++i;
> +     while (i && isdigit(name_a[i - 1]) && isdigit(name_b[i - 1]))

name_a[i - 1] and name_b[i - 1] must be same here.

> +             --i;
> +     return atoi(name_a + i) - atoi(name_b + i); }
> +
> +/**
>   * DPDK callback to register a PCI device.
>   *
>   * This function creates an Ethernet device for each port of a given @@ 
> -1189,6 +1218,7 @@
> mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,  {
>       struct ibv_device **ibv_list;
>       struct rte_eth_dev **eth_list = NULL;
> +     int n = 0;
>       int vf;
>       int ret;
> 
> @@ -1210,6 +1240,9 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv 
> __rte_unused,
>               DRV_LOG(ERR, "cannot list devices, is ib_uverbs loaded?");
>               return -rte_errno;
>       }
> +
> +     struct ibv_device *ibv_match[ret + 1];
> +
>       while (ret-- > 0) {
>               struct rte_pci_addr pci_addr;
> 
> @@ -1221,14 +1254,37 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv 
> __rte_unused,
>                   pci_dev->addr.devid != pci_addr.devid ||
>                   pci_dev->addr.function != pci_addr.function)
>                       continue;
> -             DRV_LOG(INFO, "PCI information matches, using device \"%s\"",
> +             DRV_LOG(INFO, "PCI information matches for device \"%s\"",
>                       ibv_list[ret]->name);
> -             break;
> +             ibv_match[n++] = ibv_list[ret];
> +     }
> +     ibv_match[n] = NULL;
> +     if (n > 1) {
> +             /*
> +              * The existence of several matching entries means port
> +              * representors have been instantiated. No existing Verbs
> +              * call nor /sys entries can tell them apart at this point.
> +              *
> +              * While definitely hackish, assume their names are numbered
> +              * based on order of creation with master device first,
> +              * followed by first port representor, followed by the
> +              * second one and so on.
> +              */
> +             DRV_LOG(WARNING,
> +                     "probing device with port representors involves"
> +                     " heuristics with uncertain outcome");
> +             qsort(ibv_match, n, sizeof(*ibv_match), mlx5_cmp_ibv_name);
> +             DRV_LOG(WARNING, "assuming \"%s\" is the master device",
> +                     ibv_match[0]->name);
> +             for (ret = 1; ret < n; ++ret)
> +                     DRV_LOG(WARNING,
> +                             "assuming \"%s\" is port representor #%d",
> +                             ibv_match[ret]->name, ret - 1);
>       }
> -     if (ret >= 0)
> -             eth_list = mlx5_dev_spawn(&pci_dev->device, ibv_list[ret], vf);
> +     if (n)
> +             eth_list = mlx5_dev_spawn(&pci_dev->device, ibv_match[0], vf);
>       mlx5_glue->free_device_list(ibv_list);
> -     if (!ret) {
> +     if (!n) {
>               DRV_LOG(WARNING,
>                       "no Verbs device matches PCI device " PCI_PRI_FMT ","
>                       " are kernel drivers loaded?",
> --
> 2.11.0

Reply via email to