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:
parent
da09be6328
commit
a5650a4b4a
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue