Messages in this thread | | | Date | Fri, 20 Apr 2007 11:57:27 -0400 | From | "Dmitry Torokhov" <> | Subject | Re: [PATCH RFD] alternative kobject release wait mechanism |
| |
On 4/20/07, Alan Stern <stern@rowland.harvard.edu> 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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |