On Mon, 7 Mar 2005, Dmitry Torokhov wrote: > > A more concrete question is: Should mutual exclusion between probe/remove > > and suspend/resume be handled by the bus rwsem, by a semaphore in struct > > device, or by individual bus drivers? Offhand I don't see any reason why > > the rwsem wouldn't be enough. > > > > I think the most flexible way would be having a per-device semaphore > (managed by driver core). This way operations WRT one device are > serialized but you not getting into deadlocks if you need to add or > drop some devices. That's how the USB subsystem works internally, except that the semaphores are managed by the USB core rather than the driver-model core. The scheme has a weakness though. When the per-device semaphore was added, we decided that whenever both the device semaphore and the bus rwsem were held, the device semaphore would always be acquired first (so as to avoid deadlocks). This ordering was necessary because there's no other way to hold both locks while registering a new device -- the driver-model core acquires the bus rwsem during device_add(). (Ditto for device_del().) The problem arises when drivers are registered or unregistered. The driver-model core will try to match a new driver to all unbound devices and call the bus's probe routine, all while holding the rwsem. Likewise it will call the bus's release routine to unbind an old driver from each of its devices, again while holding the rwsem. Thus there's no way for the bus driver to lock devices' semaphores while they are being probed for a newly-registered driver or released for a newly-unregistered driver. I ended up solving this problem by adding a second layer of locking. It's an awkward solution but unavoidable. If the scheme became more general and was moved into the driver-model core, it could become a bit simpler. To avoid changing all the bus drivers, the per-device semaphore should be acquired by the driver-model core during device_add() and device_del(). To resolve the ordering problem, the core should lock the bus rwsem _before_ locking the device. The potential disadvantage would be that a bus driver couldn't maintain the device lock across calls to device_add() and device_del() -- I don't think that will matter very much. (Especially since USB is the only place such locks get used right now.) Anyway, the decision about how to handle all this is up to Greg. I'm curious to hear what he thinks... ? Alan Stern