Linux CPUFreq Subsystem Overview
参考4.9,CPUFreq即CPU Frequency scaling或者CPU performance scaling,允许你运行时改变CPU clock speed.
文档路径: ./Documentation/cpu-freq/,先来看几个概念:
Some CPU frequency scaling-capable processor switch between various
frequencies and operating voltages “on the fly” without any kernel or
user involvement. This guarantees very fast switching to a frequency
which is high enough to serve the user’s needs, but low enough to save
power.2.1 Policy
On these systems, all you can do is select the lower and upper
frequency limit as well as whether you want more aggressive
power-saving or more instantly available processing power.
有些CPU不需要由kernel控制直接切换频率,这种切换快速但耗电。在这种系统中,用户就配个max/min freq即可,,可以看到被wrap到了policy中。在代码里就是->setpolicy
,后面在看。
2.2 Governor
On all other cpufreq implementations, these boundaries still need to
be set. Then, a “governor” must be selected. Such a “governor” decides
what speed the processor shall run within the boundaries. One such
“governor” is the “userspace” governor. This one allows the user - or
a yet-to-implement userspace program - to decide what specific speed
the processor shall run at.
而其他系统就是由kernel控制了,kernel要选择一个governor,由这个governor来控制,同时也要设置max/min频率。在代码里不需要用->setpolicy
了,取代的是->target
or ->target_index
。显然这个系统会save more power相比->setpolicy
。
这个governor应该分成2大类,一类主要静态调频成最大(performance) or 最小(powersave),其他都是给动态调频用,比如4.9内核高通手机平台用的schedutil,文档有个流程图很清晰:
CPU can be set to switch independently | CPU can only be set
within specific "limits" | to specific frequencies
"CPUfreq policy"
consists of frequency limits (policy->{min,max})
and CPUfreq governor to be used
/ \
/ \
/ the cpufreq governor decides
/ (dynamically or statically)
/ what target_freq to set within
/ the limits of policy->{min,max}
/ \
/ \
Using the ->setpolicy call, Using the ->target/target_index call,
the limits and the the frequency closest
"policy" is set. to target_freq is set.
It is assured that it
is within policy->{min,max}
另外,有些cpufreq sysfs经常用到,来看几个有疑问的:
cpuinfo_cur_freq : Current frequency of the CPU as obtained from
the hardware, in KHz. This is the frequency
the CPU actually runs at.
scaling_cur_freq : Current frequency of the CPU as determined by
the governor and cpufreq core, in KHz. This is
the frequency the kernel thinks the CPU runs
at.
可见cpuinfo_cur_freq
是从硬件读出来的,scaling_cur_freq
由governor决定。看下相关代码:
/** |
static unsigned int __cpufreq_get(struct cpufreq_policy *policy) |
比如QCOM:
static struct cpufreq_driver msm_cpufreq_driver = { |
ok,直接从cpu_clk
而来。再看下scaling_cur_freq:
static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf) |
竟然用了cpufreq_driver->get
,这个不是从硬件获取的么,可以直接看cpuinfo啊,原来是为了某些用户态工具?
commit c034b02e213d271b98c45c4a7b54af8f69aaac1e |
不过set_policy
driver也属于CPUFreq scaling,加上也合理。
来看两个max/min freq:
scaling_min_freq and
scaling_max_freq show the current "policy limits" (in
kHz). By echoing new values into these
files, you can change these limits.
NOTE: when setting a policy you need to
first set scaling_max_freq, then
scaling_min_freq.
cpuinfo_min_freq : this file shows the minimum operating
frequency the processor can run at(in kHz)
cpuinfo_max_freq : this file shows the maximum operating
frequency the processor can run at(in kHz)
看代码:
|
cpufreq_table_validate_and_show()
会detect这个cpuinfo_min/max_freq,同时设置scaling_min/max_freq成一样的值:
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, |
table一般从dt中配置,scaling_min/max_freq可以修改这个节点设置成新的policy:
store_one(scaling_min_freq, min); |
ok。 目前CPUFreq子系统分成3层:
+------------------+ |
高版本有变更描述,挪到Documentation/admin-guide/pm/cpufreq.rst:
CPU Performance Scaling in Linux
The Linux kernel supports CPU performance scaling by means of the
CPUFreq
(CPU Frequency scaling) subsystem that consists of three layers of code: the
core, scaling governors and scaling drivers.
Done.
版权声明:本站所有文章均采用 CC BY-NC-SA 4.0 CN 许可协议。转载请注明原文链接!