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>
Reviewed-on: http://review.coreboot.org/1188
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-by: Sven Schnelle <svens@stackframe.org>
This commit is contained in:
Kyösti Mälkki 2012-07-07 17:15:51 +03:00 committed by Stefan Reinauer
parent da09be6328
commit a5650a4b4a
2 changed files with 27 additions and 19 deletions

View File

@ -66,12 +66,10 @@ DECLARE_SPIN_LOCK(dev_lock)
* *
* @see device_path * @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; device_t dev, child;
spin_lock(&dev_lock);
/* Find the last child of our parent. */ /* Find the last child of our parent. */
for (child = parent->children; child && child->sibling; /* */ ) for (child = parent->children; child && child->sibling; /* */ )
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->next = dev;
last_dev = 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); spin_unlock(&dev_lock);
return dev; 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. * Round a number up to an alignment.
* *

View File

@ -47,22 +47,6 @@ device_t find_dev_path(struct bus *parent, struct device_path *path)
return child; 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. * Given a PCI bus and a devfn number, find the device structure.
* *