bus/pci: fix find device implementation
authorGaetan Rivet <gaetan.rivet@6wind.com>
Fri, 27 Apr 2018 14:13:05 +0000 (16:13 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Fri, 27 Apr 2018 14:31:44 +0000 (16:31 +0200)
If start is set, and a device before it matches the data
passed for comparison, then this first device is returned.

This induces potentially infinite loops.

Fixes: c7fe1eea8a74 ("bus: simplify finding starting point")
Cc: stable@dpdk.org
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
drivers/bus/pci/pci_common.c
drivers/bus/pci/rte_bus_pci.h

index 6bed0bc..7215aae 100644 (file)
@@ -455,17 +455,20 @@ static struct rte_device *
 pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
                const void *data)
 {
-       struct rte_pci_device *dev;
+       const struct rte_pci_device *pstart;
+       struct rte_pci_device *pdev;
 
-       FOREACH_DEVICE_ON_PCIBUS(dev) {
-               if (start && &dev->device == start) {
-                       start = NULL; /* starting point found */
-                       continue;
-               }
-               if (cmp(&dev->device, data) == 0)
-                       return &dev->device;
+       if (start != NULL) {
+               pstart = RTE_DEV_TO_PCI_CONST(start);
+               pdev = TAILQ_NEXT(pstart, next);
+       } else {
+               pdev = TAILQ_FIRST(&rte_pci_bus.device_list);
+       }
+       while (pdev != NULL) {
+               if (cmp(&pdev->device, data) == 0)
+                       return &pdev->device;
+               pdev = TAILQ_NEXT(pdev, next);
        }
-
        return NULL;
 }
 
index 357afb9..458e6d0 100644 (file)
@@ -74,6 +74,9 @@ struct rte_pci_device {
  */
 #define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
 
+#define RTE_DEV_TO_PCI_CONST(ptr) \
+       container_of(ptr, const struct rte_pci_device, device)
+
 #define RTE_ETH_DEV_TO_PCI(eth_dev)    RTE_DEV_TO_PCI((eth_dev)->device)
 
 /** Any PCI device identifier (vendor, device, ...) */