1. 电源管理概述:Linux电源管理子系统架构

各位同学,咱们今天聊聊Linux电源管理。说实话,这话题我讲了快十年,每次都有新感悟。电源管理这东西,说白了就是让系统在性能和功耗之间找到平衡点。你想想看,手机没电了啥也干不了,服务器电费超标老板找你谈话——这就是电源管理的重要性。

1.1 为什么电源管理这么重要?

我刚开始做嵌入式开发那会儿,有个项目让我印象特别深。一块电池供电的工业采集设备,理论续航72小时,结果实际跑起来不到24小时就趴窝了。后来一查,CPU一直在全速跑,外设也没关——这就是典型的电源管理没做好。

电源管理的核心价值,我总结为三点:

  • 延长续航:移动设备、IoT终端,电池容量就那么大,省一点是一点
  • 降低发热:功耗降下来,散热成本也跟着降,产品更稳定
  • 节能减排:数据中心一年电费几千万,省10%就是几百万

核心观点:电源管理不是"能省则省",而是"该省的时候省,该跑的时候跑"。这个度怎么把握,就是我们这门课要解决的问题。

1.2 Linux电源管理子系统架构

Linux的电源管理,其实是一个分层架构。从底层硬件到上层应用,每一层都有自己的职责。我习惯把它画成三层:

层次 组件 职责
应用层 用户空间工具、策略管理器 制定电源策略、用户交互
内核层 PM Core、PM QOS、Runtime PM、Suspend/Resume 策略执行、设备管理、状态转换
硬件层 CPU、外设、电源管理IC 电压调节、时钟门控、电源门控

嗯,这里要注意,内核层是咱们的重点。它负责把应用层的"我想省电"翻译成硬件能懂的"把电压降下来"。

1.3 三大核心框架介绍

1.3.1 PM QOS — 性能与功耗的"谈判桌"

PM QOS,全称是Power Management Quality of Service。说白了,它就是个协调机制。各个模块说"我需要多少性能",PM QOS负责"砍价"。

举个例子:

  • GPU说:我要CPU频率不低于1.2GHz,不然画面卡顿
  • 网卡说:我只要800MHz就够了
  • PM QOS说:好,取最大值,CPU跑1.2GHz

我在项目中遇到过一个问题:某个外设驱动注册了PM QOS约束,要求CPU最低频率500MHz。结果系统待机时CPU降不下去,功耗比预期高了30%。查了半天,发现是驱动在初始化时注册了约束,但退出时忘了注销。嗯,这种坑踩过一次就记住了。

经验之谈:PM QOS的约束一定要"用完即删"。我建议在驱动的probe函数里注册,remove函数里注销,这样最保险。

1.3.2 Runtime PM — 设备级的"即用即走"

Runtime PM,运行时电源管理。它解决的是"设备不用的时候自动关,用的时候自动开"的问题。

你想想看,一个USB鼠标,你不动它的时候,它其实不需要一直供电。Runtime PM就是干这个的——检测到设备空闲,自动挂起;检测到有操作,自动唤醒。

核心API就这几个:

// 启用Runtime PM
pm_runtime_enable(dev);

// 设置设备为"活跃"状态
pm_runtime_get_sync(dev);

// 设置设备为"空闲"状态
pm_runtime_put(dev);

// 强制挂起
pm_runtime_suspend(dev);

我记得有个项目,摄像头驱动用了Runtime PM。平时不录像时,摄像头功耗从200mW降到5mW。但有个坑:唤醒延迟。从挂起到恢复,大概需要50ms。如果应用层要求30ms内响应,那就得调整策略了。

注意:Runtime PM的唤醒延迟是硬伤。如果你的设备对响应时间有严格要求,建议用PM QOS设置一个"不允许挂起"的约束。

1.3.3 Suspend/Resume — 系统级的"睡眠与苏醒"

Suspend/Resume,就是整个系统的休眠和唤醒。手机按一下电源键息屏,就是一次Suspend;再按一下亮屏,就是Resume。

Linux支持几种休眠状态:

状态 名称 功耗 唤醒延迟
Suspend-to-Idle 浅度睡眠 中等 毫秒级
Suspend-to-RAM (STR) 深度睡眠 秒级
Suspend-to-Disk (STD) 休眠 极低 十秒级

我曾经调试过一个平板电脑的Suspend/Resume问题。每次休眠后唤醒,WiFi就断连。查了三天,发现是WiFi驱动的suspend回调里没有保存固件状态,resume后固件需要重新加载,但加载流程又和网络栈有冲突。最后加了个延迟加载的workqueue才搞定。

1.4 电源管理的调试手段

做电源管理,调试工具很重要。我常用的有这几个:

  • powertop:查看系统功耗分布,哪个进程在"偷电"一目了然
  • ftrace:跟踪电源管理事件,比如suspend/resume的耗时
  • /sys/kernel/debug/pm_qos:查看PM QOS约束情况
  • /sys/power/state:手动触发系统休眠

调试技巧:我习惯先用powertop跑一遍,看看整体功耗分布。然后针对异常高的模块,用ftrace跟踪它的电源状态切换。这样定位问题最快。

1.5 本章小结

这一章咱们把Linux电源管理的"骨架"搭起来了。PM QOS负责协调性能需求,Runtime PM负责设备级的按需供电,Suspend/Resume负责系统级的睡眠管理。三者配合,才能实现"该省省该用用"的理想状态。

下一章,咱们深入PM QOS的源码实现,看看它到底是怎么"砍价"的。到时候我会带大家读一段实际的内核代码,嗯,保证比看文档有意思。