History

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

Linus Torvalds committed 12 years ago

Commit e981e792 parents 54366a7 58b116b1 file · +17 −0Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t