Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1188
-gerrit
commit 5da88b005c2b1114d49ba345893f457f44353ff3 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Sat Jul 7 17:15:51 2012 +0300
Use dev_lock for alloc_find_dev()
If threads called alloc_find_dev() with same device_path simultaneously, two device nodes could be allocated. This bug is not triggered by current code.
Change-Id: Ifc87021c8d6f422901c5de5dd17392e3e2309afa Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/devices/device.c | 30 +++++++++++++++++++++++++++--- src/devices/device_util.c | 16 ---------------- 2 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/src/devices/device.c b/src/devices/device.c index ebac1a0..fafa599 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -66,12 +66,10 @@ DECLARE_SPIN_LOCK(dev_lock) * * @see device_path */ -device_t alloc_dev(struct bus *parent, struct device_path *path) +static device_t __alloc_dev(struct bus *parent, struct device_path *path) { device_t dev, child;
- spin_lock(&dev_lock); - /* Find the last child of our parent. */ for (child = parent->children; child && child->sibling; /* */ ) child = child->sibling; @@ -99,11 +97,37 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) last_dev->next = dev; last_dev = dev;
+ return dev; +} + +device_t alloc_dev(struct bus *parent, struct device_path *path) +{ + device_t dev; + spin_lock(&dev_lock); + dev = __alloc_dev(parent, path); spin_unlock(&dev_lock); return dev; }
/** + * See if a device structure already exists and if not allocate it. + * + * @param parent The bus to find the device on. + * @param path The relative path from the bus to the appropriate device. + * @return Pointer to a device structure for the device on bus at path. + */ +device_t alloc_find_dev(struct bus *parent, struct device_path *path) +{ + device_t child; + spin_lock(&dev_lock); + child = find_dev_path(parent, path); + if (!child) + child = __alloc_dev(parent, path); + spin_unlock(&dev_lock); + return child; +} + +/** * Round a number up to an alignment. * * @param val The starting value. diff --git a/src/devices/device_util.c b/src/devices/device_util.c index 5225938..ecc2c13 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -48,22 +48,6 @@ device_t find_dev_path(struct bus *parent, struct device_path *path) }
/** - * See if a device structure already exists and if not allocate it. - * - * @param parent The bus to find the device on. - * @param path The relative path from the bus to the appropriate device. - * @return Pointer to a device structure for the device on bus at path. - */ -device_t alloc_find_dev(struct bus *parent, struct device_path *path) -{ - device_t child; - child = find_dev_path(parent, path); - if (!child) - child = alloc_dev(parent, path); - return child; -} - -/** * Given a PCI bus and a devfn number, find the device structure. * * @param bus The bus number.