Make sure that a complaint appears in the kernel log if the driver core locking assumptions are violated. Cc: Lee Duncan <lduncan@xxxxxxxx> Cc: Hannes Reinecke <hare@xxxxxxxx> Cc: Luis Chamberlain <mcgrof@xxxxxxxxxx> Cc: Johannes Thumshirn <jthumshirn@xxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/base/dd.c | 16 ++++++++++++++++ drivers/base/memory.c | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index b4212154a94b..033382421351 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -315,11 +315,15 @@ __exitcall(deferred_probe_exit); */ bool device_is_bound(struct device *dev) { + lockdep_assert_held(&dev->mutex); + return dev->p && klist_node_attached(&dev->p->knode_driver); } static void driver_bound(struct device *dev) { + lockdep_assert_held(&dev->mutex); + if (device_is_bound(dev)) { printk(KERN_WARNING "%s: device %s already bound\n", __func__, kobject_name(&dev->kobj)); @@ -363,6 +367,8 @@ static int driver_sysfs_add(struct device *dev) { int ret; + lockdep_assert_held(&dev->mutex); + if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_BIND_DRIVER, dev); @@ -421,6 +427,8 @@ int device_bind_driver(struct device *dev) { int ret; + lockdep_assert_held(&dev->mutex); + ret = driver_sysfs_add(dev); if (!ret) driver_bound(dev); @@ -450,6 +458,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) && !drv->suppress_bind_attrs; + lockdep_assert_held(&dev->mutex); + if (defer_all_probes) { /* * Value of defer_all_probes can be set only by @@ -589,6 +599,8 @@ static int really_probe_debug(struct device *dev, struct device_driver *drv) ktime_t calltime, delta, rettime; int ret; + lockdep_assert_held(&dev->mutex); + calltime = ktime_get(); ret = really_probe(dev, drv); rettime = ktime_get(); @@ -645,6 +657,8 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) { int ret = 0; + lockdep_assert_held(&dev->mutex); + /* * Several callers check the driver pointer without holding the * device mutex. Hence check the driver pointer again while holding @@ -932,6 +946,8 @@ static void __device_release_driver(struct device *dev, struct device *parent) { struct device_driver *drv; + lockdep_assert_held(&dev->mutex); + drv = dev->driver; if (drv) { if (driver_allows_async_probing(drv)) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index c8a1cb0b6136..41a8454dabb5 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -283,6 +283,8 @@ static int memory_subsys_online(struct device *dev) struct memory_block *mem = to_memory_block(dev); int ret; + lockdep_assert_held(&dev->mutex); + if (mem->state == MEM_ONLINE) return 0; @@ -307,6 +309,8 @@ static int memory_subsys_offline(struct device *dev) { struct memory_block *mem = to_memory_block(dev); + lockdep_assert_held(&dev->mutex); + if (mem->state == MEM_OFFLINE) return 0; -- 2.19.1.568.g152ad8e336-goog