linux cpufreq framework(1)_概述
作者:wowo 发布于:2015-6-13 22:20
分类:电源管理子系统
1. 前言
linux kernel主要通过三类机制实现SMP系统CPU core的电源管理功能: 1)cpu hotplug。根据应用场景,enable/disable CPU core,具体可参考“Linux CPU core的电源管理(4)_cpu control”。
2) cpuidle framework。在没有进程调度的时候,让CPU core进入idle状态,具体可参考“cpuidle framework系列文章”。
3) cpufreq framework。根据使用场景和系统负荷,调整CPU core的电压(voltage)和频率(frequency),具体可参考本文以及后续cpufreq相关的。
对CPU core来说,功耗和性能是一对不可调和的矛盾,通过调整CPU的电压和频率,可以在功耗和性能之间找一个平衡点。由于调整是在系统运行的过程中,因此cpufreq framework的功能也称作动态电压/频率调整(Dynamic Voltage/Frequency Scaling,DVFS)。
本文主要从功能说明和软件架构两个角度介绍cpufreq framework。
2. 功能说明
cpufreq framework的核心功能,是通过调整CPU core的电压和频率,兼顾系统的性能和功耗。在不需要高性能时,降低电压和频率,以降低功耗;在需要高性能时,提高电压和频率,以提高性能。要达到此目的,有两个关键点: 1)如果控制CPU core的电压和频率。
2)何时改变CPU core的电压和频率。
针对这两个关键点,CPU core有两种实现。
实现1:CPU core根据自身的负荷,自动调整电压和频率,不需要OS级别的软件参与。 这种实现,软件复杂度非常低,通常情况下,只需要告诉CPU core电压和频率的调整范围(通过频率表示,scaling_min_freq和scaling_max_freq,也称作policy),CPU core即可自行调整。因此:
关键点1,由CPU core自行处理;
关键点2,OS需要根据大致的应用场景(例如,是高性能场景,还是低性能场景),设定一个频率范围,改变时机,由CPU core自行决定。
注1:由于软件参与度小,该实现的省电效率可能较低。
实现2:CPU core不参与任何的逻辑动作,由OS软件根据系统运行情况,调整电压和频率。 这种实现,几乎完全由软件掌控DVFS行为:
关键点2,根据应用场景,手动(用户发起,例如省电模式)或者自动(软件自动调整,例如HMP)的调整。
注2:对关键点2来说,如果调整比较频繁,则需要CPU core在不同频率之间转换的速度足够快,后面会详细介绍。
为了实现上述功能需求,cpufreq framework抽象出cpufreq driver、cpufreq policy(策略)、cpufreq governor等多个软件实体,具体请参考下面的说明。
3. 软件架构
cpufreq framework的软件架构如下面图片所示:
对下,cpufreq framework基于cpu subsystem driver、OPP、clock framework、regulator framework等模块,提供对CPU core频率和电压的控制。这一部分主要由cpufreq driver实现。
对上,cpufreq framework会通过cpufreq core、cpufreq governors、cpufreq stats等模块,以sysfs的形式,向用户空间提供cpu frequency的查询、控制等接口。同时,在频率改变的时候,通过notifier通知关心的driver。
内部,cpufreq framework包括cpufreq core、cpufreq driver、cpufreq governors、cpufreq stats等模块,具体功能会在下一章详细分析。
注3:cpufreq driver中有,有一个特别的driver----arm big·little driver,用于实现ARM平台big·little的切换逻辑。虽然arm bit·little和cpufreq不是同一个概念,但它们的目的和逻辑非常类似,因此就放到这里了。后续会有专门的文章介绍该功能,因此分析cpufreq framework其它内容时,会直接把它忽略不表。
4. 软件模块的功能及API描述
4.1 cpufreq core
cpufreq core是cpufreq framework的核心模块,和kernel其它framework类似,它主要实现三类功能: 对上,以sysfs的形式向用户空间提供统一的接口,以notifier的形式向其它driver提供频率变化的通知;
对下,提供CPU core频率和电压控制的驱动框架,方便底层driver的开发;同时,提供governor框架,用于实现不同的频率调整机制;
内部,封装各种逻辑,实现所需功能。这些逻辑主要围绕struct cpufreq_driver、struct cpufreq_policy和struct cpufreq_governor三个数据结构进行,下面会详细分析。
1)struct cpufreq_driver
struct cpufreq_driver用于抽象cpufreq驱动,是平台驱动工程师关注最多的结构,其定义如下:
1: /* include/linux/cpufreq.h */
2: struct cpufreq_driver {
3: char name[CPUFREQ_NAME_LEN];
4: u8 flags;
5: void *driver_data;
6:
7: /* needed by all drivers */
8: int (*init) (