On Fri, 21 Mar 2008, Benjamin Herrenschmidt wrote: > > On Thu, 2008-03-20 at 14:26 -0400, Alan Stern wrote: > > > > One of the things we don't want to do is bind a new driver to a device > > after it has gone through the prepare() stage. Doing so would involve > > calling the driver's probe() routine, which is likely to want to > > register new children and who knows what else. The probe routine might > > even end up running after the device was suspended! Clearly this > > should be avoided. > > > > But the user can force a binding to occur by writing the device's path > > to the driver's "bind" attribute in sysfs. This means that > > driver_bind() in drivers/base/bus.c will need to know whether or not > > the device has gone through the prepare() stage, which means the device > > structure will need to have a flag set before prepare() is called (more > > precisely, the flag must be set before dev->sem is released following > > the call to prepare). > > > > Either that or else driver_bind() must always block whenever a system > > sleep is in progress. That would be easier -- but it's a lot like what > > the freezer would do. Which would you prefer? > > I don't fully understand what you are saying here. > > You say "bind a new driver to a device after it has gone through the > prepare() stage" > > So either there was already a driver bound to that device, which got a > prepare() callback, and in which case bind() doesn't mean much. Or there > was not, in which case there was no prepare() call involved. That's why I said "gone through the prepare() stage" instead of saying "after prepare() was called". Yes, if there's no driver bound then there's no method to call. But the PM core will still pass the device to a subroutine whose job is to call the corresponding method, if one exists. > I suppose if you prepare(), then unbind(), then something tries to > bind()... But wouldn't the core flag set after prepare() be plenty > enough to shield against that ? > > I fail to see the race you are talking about here. Let's say Task 0 is starting a sleep transition when Task 1 calls driver_bind(): Task 0 Task 1 ------ ------ down(&dev->sem) succeeds down(&dev->sem) blocks Sees that dev has no driver so there is no prepare method to call up(&dev->sem) down() succeeds Sees that dev->power.prepared flag isn't set Calls (drv->probe)(dev) Sets dev->power.prepared flag drv tries to register a child device and fails for no good reason One way to fix this is to set dev->power.prepared before releasing dev->sem. Another way to fix it is to have driver_bind() block (as though it were frozen) whenever a system sleep is underway. Which do you prefer? Alan Stern _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm