On Tue, 26 Feb 2008, Rafael J. Wysocki wrote:Yes. I've got some ideas on how to implement this. We can add a new field "suspend_called" to dev->power. It would be owned by the PM core (protect by dpm_list_mtx) and read-only to drivers. Normally it will contain 0, but when the suspend method is running we set it to SUSPEND_RUNNING and when the method returns successfully we set it to SUSPEND_DONE. Before calling the resume method we set it back to 0. Drivers can use this field as an easy way of checking that all the child devices have been suspended. When a new device is registered we check its parent's suspend_called value. If it is SUSPEND_DONE then the caller has a bug and we have to fail the registration. If it is SUSPEND_RUNNING then the registration is legal, but we remember what happened. Then when the currently-running suspend method returns and we reacquire the dpm_list_mtx, we will realize that a race was lost. If the method completed successfully (which it shouldn't) we can resume that device immediately without ever taking it off the dpm_active list; but either way we should continue the suspend loop. Now the new child will be at the end of the dpm_active_list, so it will be suspended before the parent is reached again. This way we can recover from drivers that are willing to suspend their device even though there are unsuspended children. The only drawback will be that for a short time the child will be active while its parent is suspended. We should not abort the entire sleep transition simply because we lost a race. With this scheme we won't even need the pm_sleep_rwsem; the dpm_list_mtx will provide all the necessary protection. This is more intricate than it should be. It would have been better to have had "disable_new_children" and "enable_new_children" methods from the beginning; then there wouldn't be any races at all. That's life... The one tricky thing to watch out for is when a suspend or resume method wants to unregister the device being suspended or resumed. Even that should be doable (set suspend_called to UNREGISTERED or something like that). Unregistration should always be allowed, and registration should be allowed whenever the parent isn't suspended. For devices with no parent, we can imagine there is a fictitious parent at the root of the device tree. Conceptually it gets suspended after every real device and resumed before. Maybe even before dpm_power_up(), meaning that devices with no parent could be registered by a resume_early method. When your lock-removal stuff gets into Greg's tree, I'll write all this. Sound good? Alan Stern --
| Sam Ravnborg | Are Section mismatches out of control? |
| Karl Meyer | PROBLEM: 2.6.23-rc "NETDEV WATCHDOG: eth0: transmit timed out" |
| Bart Van Assche | Re: Is gcc thread-unsafe? |
| Adrian Bunk | Re: [Bug #10493] mips BCM47XX compile error |
git: | |
| Junio C Hamano | Re: [RFC/PATCH] git-branch: default to --track |
| Linus Torvalds | cleaner/better zlib sources? |
| Peter Stahlir | Git as a filesystem |
| Yossi Leybovich | corrupt object on git-gc |
| Manuel Wildauer | Re: Editing C with... |
| Mark Thomas | [i386/Thinkpad T41]USB mouse + Xorg obsd 4.1 |
| Stijn | Re: libiconv problem |
| Daniel Ouellet | Re: Router performance on OpenBSD and OpenBGPD |
| Felix Radensky | RE: e1000e "Detected Tx Unit Hang" |
| Johann Baudy | Packet mmap: TX RING and zero copy |
| David Miller | Re: 2.6.26/tg3 ping roundtrip times > 2000 ms on local network |
| Dushan Tcholich | Re: ksoftirqd high cpu load on kernels 2.6.24 to 2.6.27-rc1-mm1 |
