Linux电源管理(5)_Hibernate和Sleep功能介绍

原文:Linux电源管理(5)_Hibernate和Sleep功能介绍

1. 前言

Hibernate和Sleep两个功能是Linux PM的核心功能,它们的目的是类似的:暂停使用——>保存上下文——>关闭系统以节电········>恢复系统——>恢复上下文——>继续使用。

本文以内核向用户空间提供的接口为突破口,从整体上对这两个功能进行介绍,并会在后续的文章中,分析它们的实现逻辑和执行动作。

2. Hibernate和Sleep相关的术语梳理

▆ Hibernate(冬眠)和Sleep(睡眠)

是Linux电源管理在用户角度的抽象,是用户可以看到的实实在在的东西。它们的共同点,是保存系统运行的上下文后挂起(suspend)系统,并在系统恢复后接着运行,就像什么事情都没有发生一样。它们的不同点,是上下文保存的位置、系统恢复的触发方式以及具体的实现机制。

▆ Suspend

有两个层次的含义。一是Hibernate和Sleep功能在底层实现上的统称,都是指挂起(Suspend)系统,根据上下文的保存位置,可以分为Suspend to Disk(STD,即Hibernate,上下文保存在硬盘/磁盘中)和Suspend to RAM(STR,为Sleep的一种,上下文保存在RAM中);二是Sleep功能在代码级的实现,表现为“kernel/power/suspend.c”文件。

▆ Standby,是Sleep功能的一个特例,可以翻译为“打盹”。

正常的Sleep(STR),会在处理完上下文后,由arch-dependent代码将CPU置为低功耗状态(通常为Sleep)。而现实中,根据对功耗和睡眠唤醒时间的不同需求,CPU可能会提供多种低功耗状态,如除Sleep之外,会提供Standby状态,该状态下,CPU处于浅睡眠模式,有任何的风吹草动,就会立即醒来。

▆ Wakeup

这是我们第一次正式的提出Wakeup的概念。我们多次提到恢复系统,其实在内核中称为Wakeup。表面上,wakeup很简单,无论是冬眠、睡眠还是打盹,总得有一个刺激让我们回到正常状态。但复杂的就是,什么样的刺激才能让我们醒来?

动物界,温度回升可能是唯一可以让动物从冬眠状态醒来的刺激。而踢一脚、闹钟响等刺激,则可以让我们从睡眠状态唤醒。对于打盹来说,则任何的风吹草动,都可以唤醒。

而在计算机界,冬眠(Hibernate)时,会关闭整个系统的供电,因此想醒来,唯有Power按钮可用。而睡眠时,为了缩短Wakeup时间,并不会关闭所有的供电,另外,为了较好的用户体验,通常会保留某些重要设备的供电(如键盘),那样这些设备就可以唤醒系统。

这些刻意保留下来的、可以唤醒系统的设备,统称为唤醒源(Wakeup source)。而Wakeup source的选择,则是PM设计工作(特别是Sleep、Standby等功能)的重点。

3. 软件架构及模块汇整

3.1 软件架构

内核中该部分的软件架构大概可以分为三个层次,如下图:

0

1)API Layer,描述用户空间API的一个抽象层。

这里的API有两类,一类涉及Hibernate和Sleep两个功能(global APIs),包括实际功能、测试用功能、Debug用功能等,通过sysfs和debugfs两种形式提供;另一类是Hibernate特有的(STD APIs),通过sysfs和字符设备两种形式提供。

2)PM Core,电源管理的核心逻辑层,位于kernel/power/目录下,包括主功能(main)、STD、STR&Standby以及辅助功能(assistant)等多个子模块。

主功能,主要负责实现global APIs相关的逻辑,为用户空间提供相应的API;

STD,包括hibernate、snapshot、swap、block_io等子模块,负责实现STD功能和硬件无关的逻辑;

STR&Stanby,包括suspend和suspend_test两个子模块,负责实现STR、Standby等功能和硬件无关的逻辑。

3)PM Driver,电源管理驱动层,涉及体系结构无关驱动、体系结构有关驱动、设备模型以及各个设备驱动等多个软件模块。

3.2 用户空间接口

3.2.1 /sys/power/state

state是sysfs中一个文件,为PM的核心接口,在“kernel/power/main.c”中实现,用于将系统置于指定的Power State(供电模式,如Hibernate、Sleep、Standby等)。不同的电源管理功能,在底层的实现,就是在不同Power State之间切换。

读取该文件,返回当前系统支持的Power State,形式为字符串。在内核中,有两种类型的Power State,一种是Hibernate相关的,名称为“disk”,除“disk”之外,内核在"kernel/power/suspend.c"中通过数组的形式定义了另外3个state,如下:

1: const char *const pm_states[PM_SUSPEND_MAX] = {   2:         [PM_SUSPEND_FREEZE]     = "freeze",   3:         [PM_SUSPEND_STANDBY]    = "standby",   4:         [PM_SUSPEND_MEM]        = "mem",   5: };

这些Power State的解释如下:

▆ freeze

这种Power State,并不涉及具体的Hardware或Driver,只是冻结所有的进程,包括用户空间进程及内核线程。和我们熟知的“冬眠”和“睡眠”相比,就称为“闭目养神”吧(可想而知,能节省的能量是有限的)。

【注:我们在之前的描述中,并没有特别描述该State,因为它在较早的内核中,只是Sleep、Hibernate等功能的一部分,只是在近期才独立出来。另外一个原因是,该state的省电效果不是很理想,所以其引用场景也是有限的。】

▆ standby,即第2章所描述的Standby状态。

▆ mem,即通常所讲的Sleep功能,也是第2章所描述的STR,Suspend to RAM。

▆ disk,即Hibernate功能,也是第2章所描述的STD,Suspend to Disk。

写入特定的Power State字符串,将会把系统置为该模式。

3.2.2 /sys/power/pm_trace

PM Trace用于提供电源管理过程中的Trace记录,由“CONFIG_PM_TRACE”宏定义(kernel/power/Kconfig)控制是否编译进内核,并由“/sys/power/pm_trace”文件在运行时控制是否使能该功能。

3.2.3 /sys/power/pm_test

PM test用于对电源管理功能的测试,由“CONFIG_PM_DEBUG”宏定义(kernel/power/Kconfig)控制是否编译进内核。其核心思想是:

▆ 将电源管理过程按照先后顺序,划分为多个步骤,如core、platform、devices等。这些步骤称作PM Test Level。

▆ 系统通过一个全局变量(pm_test_level),保存系统当前的PM Test Level。该变量的值可以通过”/sys/power/pm_test“文件获取及修改。

▆ 在每一个电源管理步骤结束后,插入PM test代码,该代码以当前执行步骤为参数,会判断当前的PM Test Level和执行步骤是否一致,如果一致,则说明该步骤执行成功。出于Test考量,执行成功后,系统会打印Test信息,并在等待一段时间后,退出PM过程。

▆ 开发人员可以通过修改全局的Test Level,有目的测试所关心的步骤是否执行成功。

上面已经讲了,该文件用于获取及修改PM Test Level,具体的Level信息在“kernel/power/main.c”中定义,格式如下(具体的意义,比较简单,对着相关的代码看,非常清晰,这里就不啰嗦了):

1: static const char * const pm_tests[__TEST_AFTER_LAST] = {   2:         [TEST_NONE] = "none",   3:         [TEST_CORE] = "core",   4:         [TEST_CPUS] = "processors",   5:         [TEST_PLATFORM] = "platform",   6:         [TEST_DEVICES] = "devices",   7:         [TEST_FREEZER] = "freezer",   8: };

3.2.4 /sys/power/wakeup_count

该接口只和Sleep功能有关,因此由“CONFIG_PM_SLEEP”宏定义(kernel/power/Kconfig)控制。它的存在,是为了解决Sleep和Wakeup之间的同步问题。

我们知道,系统睡眠后,可以通过保留的Wakeup source唤醒系统。而在当今的CPU体系中,唤醒系统就是唤醒CPU,而唤醒CPU的唯一途径,就是Wakeup source产生中断(内核称作Wakeup event)。而内核要保证在多种状态下,Sleep/Wakeup的行为都能正常,如下:

▆ 系统处于sleep状态时,产生了Wakeup event。此时应该直接唤醒系统。这一点没有问题。

▆ 系统在进入sleep的过程中,产生了Wakeup event。此时应该放弃进入sleep。

这一点就不那么容易做到了。例如,当Wakeup event发生在“/sys/power/state”被写之后、内核执行freeze操作之前。此时用户空间程序依旧可以处理Wakeup event,或者只是部分处理。而内核却以为该Event已经被处理,因此并不会放弃此次sleep动作。

这就会造成,Wakeup event发生后,用户空间程序已经后悔了,不想睡了,但最终还是睡下去了。直到下一个Wakeup event到来。

为了解决上面的问题,内核提供wkaeup_count机制,配合“/sys/power/state”,以实现Sleep过程中的同步。该机制的操作行为如下:

▆ wakeup_count是内核用来保存当前wakeup event发生的计数。

▆  用户空间程序在写入state切换状态之前,应先读取wakeup_count并把获得的count写回给wakeup_count。

▆ 内核会比对写回的count和当前的count是否一致,如果不一致,说明在读取/写回操作之间,产生了新的的wakeup event,内核就会返回错误。

▆ 用户空间程序检测到写入错误之后,不能继续后的动作,需要处理响应的event并伺机再次读取/写回wakeup_count。

▆ 如果内核比对一致,会记录write wakeup_count成功时的event快照,后面继续suspend动作时,会检查是否和快照相符,如果不符,会终止suspend。

▆ 用户空间程序检测到写入正确后,可以继续对state的写入,以便发起一次状态切换。而此时是安全的。

3.2.6 /sys/power/image_size

该接口也是STD特有的。我们知道,STD的原理是将当前的运行上下文保存在系统的disk(如NAND Flash,如硬盘),然后选择合适的方式关闭或重启系统。保存上下文是需要存储空间的,不光是disk中的存储空间,也包括位于内存的用于交换或缓冲的空间。

而该接口,就是设置或者获取当前内存中需要分配多少空间,用于缓冲需要写入到disk的数据。单位为byte。

3.2.7 /sys/power/reserverd_size

reserverd_size用于指示预留多少内存空间,用于在->freeze() 和 ->freeze_noirq()过程中保存设备驱动分配的空间。以免在STD的过程中丢失。

3.2.8 /sys/power/resume

该接口也是STD特有的。正常情况下,在重新开机后,内核会在后期的初始化过程中,读取保存在disk中的image,并恢复系统。而该接口,提供了一种在用户空间手动的读取image并恢复系统的方法。

通常情况下,该操作出现在系统正常运行的过程中,需要加载并执行另外的image。

3.2.9 debugfs/suspend_status

该接口是以debugfs的形式,向用户空间提供suspend过程的统计信息,包括:成功的次数、失败的次数、freeze失败的次数等等。

3.2.10 /dev/snapshot

该接口也是STD特有的。它通过字符设备的形式,向用户空间提供software的STD操作。我们会在后续的文章中详细描述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring 命名空间注入:p、c 与 .util 的深度解析

在 Spring 框架的开发过程中,XML 配置是一种常见且强大的方式来管理 Bean。为了让配置更加简洁、易读,Spring 提供了多种命名空间注入的方法,其中 p 命名空间注入、c 命名空间注入和 .util 命名空间尤为重要。本文将详细介绍这三种命名空间的…

RUST变量学习笔记

1,作用域概念 捕获环境 2,所有权概念 Rust则是通过所有权和借用来保证内存安全。很多人不理解为啥说Rust是内存安全的,其实就是在默认情况下,你是写不出内存不安全的代码的。 Rust的所有权并不难理解,它有且只有如下…

探索 Spring AI 的 ChatClient API:构建智能对话应用的利器

探索 Spring AI 的 ChatClient API:构建智能对话应用的利器 前言 在当今人工智能蓬勃发展的时代,智能对话系统成为了众多应用的核心组成部分。无论是客服机器人、智能助手还是聊天应用,都离不开高效、灵活的对话处理能力。Spring AI 作为 S…

开源ERP系统对比:Dolibarr、ERPNext与Odoo

对于寻求开源ERP解决方案的企业而言,Dolibarr、ERPNext和Odoo是三个备受关注的选择。它们各自拥有独特的优势和特点,适用于不同规模和需求的组织。以下是对这三个系统的详细介绍和对比,以帮助您更好地理解它们的差异,并结合中文支…

【2025年】MySQL面试题总结

文章目录 1. MySQL 支持哪些存储引擎?默认使⽤哪个?2. MyISAM 和 InnoDB 有什么区别?3. 事务的四大特性?4. 并发事务带来了哪些问题?5. 不可重复读和幻读有什么区别?6. MySQL 事务隔离级别?默认是什么级别&#xff1…

Linux常用命令29——delgroup删除组

在使用Linux或macOS日常开发中,熟悉一些基本的命令有助于提高工作效率,delgroup 是用于删除用户组的一个命令。此命令通常由超级用户(root)运行,或者通过 sudo 提权来操作。本篇学习记录delgroup命令的基本使用。 下面…

字节暑期实习-网络运维工程师面经

岗位描述 这个是ByteIntern实习,是暑期实习岗位 岗位 一面 先自我介绍 抓项目技术(会进行确认是什么技术) TCP的三次握手和四次挥手 序列号和确认应答号的位置和大小 序列号是随机的吗? 序列号为什么是随机的? …

5.3刷题

P3370 【模板】字符串哈希 #include<bits/stdc.h> using namespace std; #define int long long typedef unsigned long long ull; int n; ull myhash(string s){ull code 0, x 131, y 140814840257324663;for(int i 0; i < s.size(); i){code (code * x (ull)…

Kettle下载安装教程

## 什么是Kettle Kettle&#xff08;现在也称为Pentaho Data Integration&#xff0c;简称PDI&#xff09;是一款开源的ETL&#xff08;Extract-Transform-Load&#xff09;工具&#xff0c;用于数据抽取、转换和加载。它允许用户通过图形化界面设计和执行数据集成流程&#xf…

FreeRtos实战从入门到精通--任务创建和删除(动态方法)--事了拂衣去,深藏功与名

FreeRtos是之前的一些聪明的工程师写的免费且开源的嵌入式实时操作系统代码&#xff0c;由于我们实际工作中不需要再去写rtos&#xff0c;我们只需要用就行了&#xff0c;所以博主这里只分享项目工程实战相关的内容&#xff0c;具体rtos源码&#xff0c;可以无需理会&#xff0…

Java通用Mapper自定义方法

目录 一、定义通用 Mapper 接口二、继承通用 Mapper 实现自定义方法三、注册自定义 Mapper 接口四、在实体类对应的 Mapper 接口中使用自定义方法五、实现自定义方法的 SQL 逻辑注解方式XML 映射文件方式六、使用自定义方法七、注意事项在 Java 持久层开发中,MyBatis 的通用 M…

Android WebRTC回声消除

文章目录 安卓可用的回声消除手段各种回声消除技术优缺点WebRTC回声消除WebRTC回声消除回声消除处理流程WebRTC AECM APP 安卓可用的回声消除手段 硬件回声消除 使用 AudioRecord 的 VOICE_COMMUNICATION 模式&#xff1a;通过 AudioRecord 的 VOICE_COMMUNICATION 音频源可以…

基于 SAFM 超分辨率上采样模块的 YOLOv12 改进方法—模糊场景目标检测精度提升研究

在复杂视觉环境中,如低光照、雾天或远距离拍摄等场景下,图像质量下降导致目标模糊,使得传统目标检测模型难以实现高精度识别。YOLO系列作为主流单阶段检测框架,在速度和精度方面表现出色,但在模糊和小目标场景中仍存在性能瓶颈。本文提出一种面向 YOLOv12 的创新性改进方法…

Spring 事务的底层原理常见陷阱

一、Spring 事务的底层原理 1. 核心机制 动态代理&#xff08;AOP&#xff09;&#xff1a; Spring 通过动态代理&#xff08;JDK 或 CGLIB&#xff09;生成代理对象&#xff0c;拦截被 Transactional 注解标记的方法。事务拦截器&#xff1a; TransactionInterceptor 负责管…

Java SE(6)——类和对象(一)

1.初始面向对象 1.1 什么是面向对象 Java是一门纯面向对象的编程语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交换来完成一件事情 1.2 面向过程…

cpp细碎知识点

1 重写 (Override): 派生类中定义一个与基类虚函数具有相同函数签名&#xff08;函数名、参数列表、返回类型&#xff09;的函数&#xff0c;这被称为重写。 重写意味着派生类提供了基类虚函数的一个特定于派生类的实现。 重写是实现多态的关键 2 虚基类 (Virtual Base Class…

若依 FastAPI + Vue3 项目 Docker 部署笔记( 启动器打包教程)

本文记录了将 start.bat 打包成 .exe 启动器的详细教程&#xff0c;适合项目交付或导师演示用。 &#x1f9ed; 一、如何将 start.bat 打包为启动器 .exe&#xff08;含图标 自动打开浏览器&#xff09; ✅ 1. 创建三大功能脚本 start.bat → 启动项目&#xff08;docke…

基于springboot的金院银行厅预约系统的设计及实现(源码+lw+部署文档+讲解),源码可白嫖!

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;信息管理系统的实施在技术上已逐步成熟。信息管理系统是一个不断发展的新型学科&#xff0c;任何一个单位要生存要发展&#xff0c;要高效率地把内部活动有机地组织起来&#xff0c;就必须建立与自身特点相适应的…

创意控制台:下雨动画特效(ASCII 雨滴下落)

在编程的世界里&#xff0c;控制台不仅仅是输出文本信息的工具&#xff0c;通过巧妙的代码设计&#xff0c;我们还能在其中创造出充满趣味的动态画面。本文将带领大家使用 C 语言打造一个创意控制台下雨动画特效&#xff0c;利用 ASCII 字符模拟雨滴下落的过程&#xff0c;为单…

MySQL--索引入门

MySQL官方对索引的定义为&#xff1a;索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。 Mysql在存储数据之外&#xff0c;数据库系统各种还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种引用&#xff08;指向&#xff09;表中的数据…