swsusp doesn't suspend devices
Subsystems (2)
It would seem that swsusp doesn't properly suspend devices, or more precisely it wakes them up again before suspending the machine.
The problem is in swsusp_suspend(). It is designed as if swsusp_arch_suspend() would suspend the hardware, when in fact all it does is prepare for a suspend. The effect is that devices are brought back up because swsusp_suspend() believes it is resuming.
Below is a patch that uses the same system as kernel/power/disk.c to determine if it's suspending or resuming. The patch brings up a new problem though, disk writes generate a huge amount of "scheduling while atomic".
---
kernel/power/swsusp.c (working copy) renamed from kernel/power/swsusp.c (revision 165) +11 -6
@@ -84,6 +84,8 @@ /* Local variables that should not be affected by save */ static unsigned int nr_copy_pages __nosavedata = 0; +static int in_suspend __nosavedata = 0; + /* Suspend pagedir is allocated before final copy, therefore it must be freed after resume
@@ -897,15 +899,18 @@ return error; } + in_suspend = 1; save_processor_state(); if ((error = swsusp_arch_suspend())) printk("Error %d suspending\n", error); - /* Restore control flow magically appears here */ - restore_processor_state(); - BUG_ON (nr_copy_pages_check != nr_copy_pages); - restore_highmem(); - device_power_up(); - local_irq_enable(); + if (!in_suspend || error) { + /* Restore control flow magically appears here */ + restore_processor_state(); + BUG_ON (nr_copy_pages_check != nr_copy_pages); + restore_highmem(); + device_power_up(); + local_irq_enable(); + } return error; }
Quoted 2 lines · Pierre Ossman
It would seem that swsusp doesn't properly suspend devices, or more precisely it wakes them up again before suspending the machine.
Yes, it does. By design.
Greetings,
Rafael
Signature · 3 lines
- Would you tell me, please, which way I ought to go from here? - That depends a good deal on where you want to get to. -- Lewis Carroll "Alice's Adventures in Wonderland"
Quoted 12 lines · Rafael J. Wysocki
Quoted 4 lines · Pierre Ossman
It would seem that swsusp doesn't properly suspend devices, or more precisely it wakes them up again before suspending the machine.
Yes, it does. By design.
That seems counter-productive, so I'm obviously missing something.
Quoted 10 lines · Pierre Ossman
Quoted 8 lines · Rafael J. Wysocki
Quoted 4 lines · Pierre Ossman
It would seem that swsusp doesn't properly suspend devices, or more precisely it wakes them up again before suspending the machine.
Quoted 6 lines
Quoted 4 lines
Yes, it does. By design.
That seems counter-productive, so I'm obviously missing something.
In swsusp, the suspend consists of freezing processes, suspending devices, turning off interrupts, and creating a memory snapshot (the image) in that state (ie of the "frozen" system). Afterwards the image is in memory and it has to be written to a swap partition. For this purpose we need to resume some devices, in particular the disk that contains this swap partition, but it always relies on some other devices that have to be resumed as well. In principle we could check what devices have to be resumed, but currently we just resume them all. An additional upside of this approach is that the suspend and resume code is (almost) identical.
Greetings,
Rafael
Signature · 3 lines
- Would you tell me, please, which way I ought to go from here? - That depends a good deal on where you want to get to. -- Lewis Carroll "Alice's Adventures in Wonderland"
Hi!
Quoted 2 lines
It would seem that swsusp doesn't properly suspend devices, or more precisely it wakes them up again before suspending the machine.
Yes, and that's okay.
What happens to devices during swsusp? They seem to be resumed
during system suspend?
A: That's correct. We need to resume them if we want to write image to disk. Whole sequence goes like
Suspend part
~~~~~~~~~~~~
running system, user asks for suspend-to-disk
user processes are stopped
suspend(PMSG_FREEZE): devices are frozen so that they don't
interfere
with state snapshot
state snapshot: copy of whole used memory is taken with
interrupts disabled
resume(): devices are woken up so that we can write image to
swap
write image to swap
suspend(PMSG_SUSPEND): suspend devices so that we can power off
turn the power off
Resume part
~~~~~~~~~~~
(is actually pretty similar)
running system, user asks for suspend-to-disk
user processes are stopped (in common case there are none, but
with resume-from-initrd, noone k\nows)
read image from disk
suspend(PMSG_FREEZE): devices are frozen so that they don't
interfere
with image restoration
image restoration: rewrite memory with image
resume(): devices are woken up so that system can continue
thaw all user processes
Signature · 1 line
if you have sharp zaurus hardware you don't need... you know my address