From a5650a4b4ac85722d772083761ffea32557774b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Sat, 7 Jul 2012 17:15:51 +0300 Subject: Use dev_lock for alloc_find_dev() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-on: http://review.coreboot.org/1188 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich Reviewed-by: Sven Schnelle --- 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 ebac1a073e..fafa59924e 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,10 +97,36 @@ 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. * diff --git a/src/devices/device_util.c b/src/devices/device_util.c index 5225938e19..ecc2c13659 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -47,22 +47,6 @@ device_t find_dev_path(struct bus *parent, struct device_path *path) return child; } -/** - * 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. * -- cgit v1.2.3