bus/vdev: fix find device implementation
authorGaetan Rivet <gaetan.rivet@6wind.com>
Fri, 27 Apr 2018 14:13:06 +0000 (16:13 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Fri, 27 Apr 2018 14:31:49 +0000 (16:31 +0200)
If start is set and a device before it matches the data,
this 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/vdev/rte_bus_vdev.h
drivers/bus/vdev/vdev.c

index 646d6c0..f9b5eb5 100644 (file)
@@ -25,6 +25,9 @@ struct rte_vdev_device {
 #define RTE_DEV_TO_VDEV(ptr) \
        container_of(ptr, struct rte_vdev_device, device)
 
+#define RTE_DEV_TO_VDEV_CONST(ptr) \
+       container_of(ptr, const struct rte_vdev_device, device)
+
 static inline const char *
 rte_vdev_device_name(const struct rte_vdev_device *dev)
 {
index 84fa51f..9f576eb 100644 (file)
@@ -495,16 +495,20 @@ static struct rte_device *
 vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
                 const void *data)
 {
+       const struct rte_vdev_device *vstart;
        struct rte_vdev_device *dev;
 
        rte_spinlock_lock(&vdev_device_list_lock);
-       TAILQ_FOREACH(dev, &vdev_device_list, next) {
-               if (start && &dev->device == start) {
-                       start = NULL;
-                       continue;
-               }
+       if (start != NULL) {
+               vstart = RTE_DEV_TO_VDEV_CONST(start);
+               dev = TAILQ_NEXT(vstart, next);
+       } else {
+               dev = TAILQ_FIRST(&vdev_device_list);
+       }
+       while (dev != NULL) {
                if (cmp(&dev->device, data) == 0)
                        break;
+               dev = TAILQ_NEXT(dev, next);
        }
        rte_spinlock_unlock(&vdev_device_list_lock);