On 4/20/07, Alan Stern <[email protected]> wrote:
Dmitry, in thinking things over some more I realized there's going to be a
problem with the autosuspend support in USB. It has to do with the way a
driver needs to prevent (or block) suspends from occurring while it is
actively using a device.
To understand this, you need to know that USB adds a pm_mutex to the
device structure. It gets used for synchronizing all suspend- or
resume-related activities. In particular, the driver's suspend() method
is called with usbdev->pm_mutex held.
The next idea is that a driver needs to synchronize its remove() method
with other methods such as read() -- we mustn't allow read() to try and
refer to the device after the driver has been unbound. Let's say the
driver has unbind_mutex embedded in its private data structure for this
purpose.
Now consider what read() has to do. It needs to block suspends from
occurring while it runs, and it needs to do an autoresume if the device
was already suspended. So read() will look like this:
mutex_lock(&private->unbind_mutex);
if (private->gone) {
ret = -ENODEV;
goto done;
}
if (private->suspended)
autoresume(private->usbdev);
...
done:
mutex_unlock(&private->unbind_mutex);
return ret;
Meanwhile, the suspend() method needs to block while read() is running.
So it will look like this:
private->suspended = 1;
mutex_lock(&private->unbind_mutex);
/* Now the driver has quiesced */
mutex_unlock(&private->unbind_mutex);
Here's the problem: The autoresume() call inside read() tries to acquire
usbdev->pm_mutex while holding private->unbind_mutex. The suspend()
method does the reverse, a locking-order violation.
So far I haven't figured out any way to make this work. Do you have a
suggestion? (Don't say read() should hold pm_mutex as well as
unbind_mutex; that's no good -- although the reason is rather obscure.)
First of all I think that I would merge pm and unbind mutex into one -
you also need to synchronize resume and suspend with bind and unbind
so you pretty much need to always acquire both of them.
Second (and I admit I have not followed USB autoresume discussions, my
usb-devle backlog is over 5000 messages ;( ) is I am not sure why
woudl a read block autoresume. I can see write doing that but passive
reads should not affect device state.
--
Dmitry
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]