Deep Dive into System Suspend & Resume
System Suspend and Resume form the core of Android's aggressive power management strategy. Unlike traditional desktop operating systems that expect constant power, Android assumes the device should be asleep (in its lowest power state) unless explicit work needs to be done.
Linux Suspend-to-RAM
Android relies heavily on the standard Linux kernel power management framework, specifically Suspend-to-RAM (S2R). In this state, almost all system components are powered off, including the CPU cores, display, and peripherals. The only component retaining power is the RAM, ensuring that the system state is preserved for an instantaneous resume.
Android introduces a critical addition to the Linux model: Opportunistic Suspend. In standard Linux, a user explicitly requests a suspend. In Android, the kernel automatically initiates a suspend transition the moment there are no active Wakelocks preventing it.
The Suspend Flow
When the Android framework determines the device can sleep (no active wakelocks), the SuspendManager initiates the transition by writing mem to /sys/power/state. This triggers a complex sequence of events in the kernel.
1. Freeze Tasks
The first step is to halt all user-space processes and freezable kernel threads. This ensures that no tasks are actively executing or attempting to access hardware while the hardware is being powered down.
// kernel/power/process.c
int freeze_processes(void) {
// Iterate through task list and send fake signals to freeze them
// ...
pr_info("Freezing user space processes ... ");
error = try_to_freeze_tasks(true);
// ...
return error;
}
2. Suspend Devices
The kernel iterates through the device tree, invoking the suspend callbacks of all registered device drivers. Drivers must save their hardware state, disable interrupts, and put their hardware into a low-power mode. This phase is highly asynchronous and can be complex, as driver dependencies must be respected.
3. Suspend Syscore
The final phase involves shutting down the core system components (interrupt controllers, timers, and CPU cores). The system enters the actual Suspend-to-RAM state here. At this point, the system is fully asleep.
The Resume Flow
The resume process is essentially the reverse of the suspend flow, triggered by a hardware interrupt.
- Wakeup Interrupt: A pre-configured hardware component (e.g., power button, modem, RTC alarm) fires an interrupt.
- Syscore Resume: Core system components are powered back on.
- Device Resume: Device drivers are called via their
resumecallbacks to restore hardware state and re-enable interrupts. - Thaw Tasks: User-space processes and kernel threads are un-frozen, allowing the Android framework to resume execution.
Wakeup Sources
A Wakeup Source is a specific hardware event configured to pull the system out of suspend. Common wakeup sources include:
- The physical power button.
- Incoming calls or network data via the modem.
- Real-Time Clock (RTC) alarms (used by
AlarmManager). - Significant motion detected by the Sensor Hub.
When a wakeup interrupt fires, the corresponding driver must quickly acquire a kernel wakelock to prevent the system from immediately suspending again while the event is processed.
// Example: A driver handling a wakeup interrupt
irqreturn_t my_device_interrupt(int irq, void *dev_id) {
struct my_device *dev = dev_id;
// Prevent system from suspending immediately
pm_wakeup_event(&dev->dev, 1000); // Hold wakelock for 1 second
// Schedule work to process the event
schedule_work(&dev->work);
return IRQ_HANDLED;
}
Suspend and Resume Tracing
Debugging power issues often requires analyzing why a device failed to suspend or what woke it up. AOSP provides robust tracing mechanisms.
Using suspend_resume Tracing
The kernel's ftrace infrastructure includes specific tracepoints for power events.
# Enable tracing for suspend/resume events
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/suspend_resume/enable"
# View the trace output
adb shell cat /sys/kernel/debug/tracing/trace
The trace output will detail the exact timing of each phase (freezing tasks, suspending individual drivers). If a specific driver is causing a suspend failure, the trace will reveal exactly which driver's suspend callback returned an error, significantly accelerating debugging efforts.