linux内核休眠、唤醒流程分析之挂起:pm.suspend_noirq(七)

Linux内核休眠机制解析:挂起流程与设备管理
本文深入分析Linux内核挂起流程,详细讲解了通过dpm_suspend_noirq函数实现设备的suspend_noirq操作,包括状态复制、设备遍历、错误处理及链表迁移。此外,还探讨了如何判断并执行设备的电源管理操作,以及后续的CPU关闭、中断禁用、系统核心模块停用和进入休眠的步骤。

在这里插入图片描述

 // kernel\power\suspend.c
 
/**
 * suspend_enter - Make the system enter the given sleep state.
 * @state: System sleep state to enter.
 * @wakeup: Returns information that the sleep state should not be re-entered.
 *
 * This function should be called after devices have been suspended.
 */
static int suspend_enter(suspend_state_t state, bool *wakeup)
{
   
   
	int error;

	error = platform_suspend_prepare(state);
	if (error)
		goto Platform_finish;

	error = dpm_suspend_late(PMSG_SUSPEND);
	if (error) {
   
   
		pr_err("late suspend of devices failed\n");
		goto Platform_finish;
	}
	error = platform_suspend_prepare_late(state);
	if (error)
		goto Devices_early_resume;

	error = dpm_suspend_noirq(PMSG_SUSPEND);
	if (error) {
   
   
		pr_err("noirq suspend of devices failed\n");
		goto Platform_early_resume;
	}
	error = platform_suspend_prepare_noirq(state);
	if (error)
		goto Platform_wake;

	if (suspend_test(TEST_PLATFORM))
		goto Platform_wake;

	if (state == PM_SUSPEND_TO_IDLE) {
   
   
		s2idle_loop();
		goto Platform_wake;
	}

	error = suspend_disable_secondary_cpus();
	if (error || suspend_test(TEST_CPUS))
		goto Enable_cpus;

	arch_suspend_disable_irqs();
	BUG_ON(!irqs_disabled());

	system_state = SYSTEM_SUSPEND;

	error = syscore_suspend();
	if (!error) {
   
   
		*wakeup = pm_wakeup_pending();
		if (!(suspend_test(TEST_CORE) || *wakeup)) {
   
   
			trace_suspend_resume(TPS("machine_suspend"),
				state, true);
			error = suspend_ops->enter(state);
			trace_suspend_resume(TPS("machine_suspend"),
				state, false);
		} else if (*wakeup) {
   
   
			error = -EBUSY;
		}
		syscore_resume(
Linux 内核中提供了多种电源管理状态,其中 `suspend_to_disk`(休眠)和 `suspend_to_ram`(挂起到内存)是两种常见的低功耗状态,它们在实现机制、功耗、恢复速度和适用场景上有显著区别。 ### 3.1 `suspend_to_ram`(挂起到内存) `PM_SUSPEND_MEM` 模式下,系统将所有运行状态(包括内存内容)保留在 RAM 中,而关闭除 RAM 控制器以外的其他硬件设备。此时,系统仅维持 RAM 的自刷新状态以保存数据,功耗较低。一旦有唤醒事件触发(如按键、定时器、网络唤醒等),系统可以快速恢复执行,通常在几秒内完成。 该状态对应 ACPI 的 S3 状态,适用于需要快速恢复且功耗较低的场景,例如笔记本电脑在短暂不使用时进入挂起状态。 ```c #define PM_SUSPEND_MEM ((__force suspend_state_t) 3) ``` 此模式不依赖磁盘 I/O,因此恢复速度快,但依赖 RAM 的持续供电,若电源完全断开,数据将丢失[^1]。 ### 3.2 `suspend_to_disk`(休眠) `PM_SUSPEND_DISK` 模式下,系统将内存内容写入磁盘(通常是交换分区或指定的休眠镜像文件),然后关闭所有硬件设备,包括 RAM。此时系统几乎不消耗电力,适用于长时间不使用设备的情况。恢复时,系统从磁盘读取内存镜像并恢复执行状态,恢复时间较长,通常在几十秒到一分钟不等。 该状态对应 ACPI 的 S4 状态,也被称为 Hibernate。它不依赖持续供电,即使断电也不会丢失数据,适合用于需要长时间保存系统状态的场景[^1]。 ### 3.3 主要区别总结 | 特性 | `suspend_to_ram` (S3) | `suspend_to_disk` (S4) | |------|------------------------|-------------------------| | 内存状态保存方式 | 保留在 RAM 中 | 写入磁盘 | | 功耗 | 低(维持 RAM 自刷新) | 极低(无供电需求) | | 恢复速度 | 快(几秒) | 慢(需从磁盘读取) | | 依赖磁盘 | 否 | 是 | | 唤醒源 | 键盘、定时器、网络等 | 电源按钮、外部中断 | | 断电影响 | 数据丢失 | 数据保留 | ### 3.4 实现机制差异 - **`suspend_to_ram`**:仅需将设备置于低功耗状态,保留内存内容即可,不涉及磁盘 I/O 操作。 - **`suspend_to_disk`**:需在挂起前将内存内容序列化并写入磁盘,在恢复时从磁盘读取并重建内存状态,涉及较多的 I/O 操作和错误处理机制。 ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值