Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dt-for-linus' of git://git.secretlab.ca/git/linux

Pull driver core deferred probe fix from Grant Likely:
"Drivercore race condition fix (exposed by devicetree)

This branch fixes a bug where a device can get stuck in the deferred
list even though all its dependencies are met. The bug has existed
for a long time, but new platform conversions to device tree have
exposed it. This patch is needed to get those platforms working.

This was the pending bug fix I mentioned in my previous pull request.
Normally this would go through Greg's tree seeing that it is a
drivercore change, but devicetree exposes the problem. I've discussed
with Greg and he okayed me asking you to pull directly"

* tag 'dt-for-linus' of git://git.secretlab.ca/git/linux:
drivercore: deferral race condition fix

+17
+17
drivers/base/dd.c
··· 52 52 static LIST_HEAD(deferred_probe_pending_list); 53 53 static LIST_HEAD(deferred_probe_active_list); 54 54 static struct workqueue_struct *deferred_wq; 55 + static atomic_t deferred_trigger_count = ATOMIC_INIT(0); 55 56 56 57 /** 57 58 * deferred_probe_work_func() - Retry probing devices in the active list. ··· 136 135 * This functions moves all devices from the pending list to the active 137 136 * list and schedules the deferred probe workqueue to process them. It 138 137 * should be called anytime a driver is successfully bound to a device. 138 + * 139 + * Note, there is a race condition in multi-threaded probe. In the case where 140 + * more than one device is probing at the same time, it is possible for one 141 + * probe to complete successfully while another is about to defer. If the second 142 + * depends on the first, then it will get put on the pending list after the 143 + * trigger event has already occured and will be stuck there. 144 + * 145 + * The atomic 'deferred_trigger_count' is used to determine if a successful 146 + * trigger has occurred in the midst of probing a driver. If the trigger count 147 + * changes in the midst of a probe, then deferred processing should be triggered 148 + * again. 139 149 */ 140 150 static void driver_deferred_probe_trigger(void) 141 151 { ··· 159 147 * into the active list so they can be retried by the workqueue 160 148 */ 161 149 mutex_lock(&deferred_probe_mutex); 150 + atomic_inc(&deferred_trigger_count); 162 151 list_splice_tail_init(&deferred_probe_pending_list, 163 152 &deferred_probe_active_list); 164 153 mutex_unlock(&deferred_probe_mutex); ··· 278 265 static int really_probe(struct device *dev, struct device_driver *drv) 279 266 { 280 267 int ret = 0; 268 + int local_trigger_count = atomic_read(&deferred_trigger_count); 281 269 282 270 atomic_inc(&probe_count); 283 271 pr_debug("bus: '%s': %s: probing driver %s with device %s\n", ··· 324 310 /* Driver requested deferred probing */ 325 311 dev_info(dev, "Driver %s requests probe deferral\n", drv->name); 326 312 driver_deferred_probe_add(dev); 313 + /* Did a trigger occur while probing? Need to re-trigger if yes */ 314 + if (local_trigger_count != atomic_read(&deferred_trigger_count)) 315 + driver_deferred_probe_trigger(); 327 316 } else if (ret != -ENODEV && ret != -ENXIO) { 328 317 /* driver matched but the probe failed */ 329 318 printk(KERN_WARNING