|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Linux动态频率调节系统CPUFreq之governor的初始化! ]( s- t7 m8 G( x! e. q
8 ^0 G* b2 l- c9 r& o3 @4 B( @当一个governor被policy选定后,核心层会通过__cpufreq_set_policy函数对该cpu的policy进行设定。如果policy认为这是一个新的governor(和原来使用的旧的governor不相同),policy会通过__cpufreq_governor函数,并传递CPUFREQ_GOV_POLICY_INIT参数,而__cpufreq_governor函数实际上是调用cpufreq_governor结构中的governor回调函数,在第2节中我们已经知道,这个回调最后会进入governor公共API:cpufreq_governor_dbs,下面是它收到CPUFREQ_GOV_POLICY_INIT参数时,经过简化后的代码片段:9 I4 q/ w8 H& f7 `5 i
% p- v8 d. r- i. G: ]- case CPUFREQ_GOV_POLICY_INIT:
- ......
1 I4 V7 c2 w( G8 e, Q- dbs_data = kzalloc(sizeof(*dbs_data), GFP_KERNEL);
- ......
- # \3 q( E" d1 p/ I. e
- dbs_data->cdata = cdata;
- dbs_data->usage_count = 1;
- rc = cdata->init(dbs_data);
- ......
& p) P4 Y& \- ^! t- rc = sysfs_create_group(get_governor_parent_kobj(policy),
- get_sysfs_attr(dbs_data));
- ......
/ ~: @7 y5 ~& |- policy->governor_data = dbs_data;
- 0 }# d: _4 {2 O* N, h' G
- ......
- /* Bring kernel and HW constraints together */
- dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate,
- MIN_LATENCY_MULTIPLIER * latency);
- set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
- latency * LATENCY_MULTIPLIER));
- if ((cdata->governor == GOV_CONSERVATIVE) &&
- (!policy->governor->initialized)) {
- struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
2 b' A% x t/ n5 J( h3 G8 b- cpufreq_register_notifier(cs_ops->notifier_block,
- CPUFREQ_TRANSITION_NOTIFIER);
- }
- ' n8 Q% W6 A. j3 N- Q. G
- if (!have_governor_per_policy())
- cdata->gdbs_data = dbs_data;
5 @! |) b1 f$ M; |" e- return 0;+ C. _2 T$ x' w* w
/ Q- ^% W" c# j R& \" E
, |& D$ o2 w s! b首先,它会给这个policy分配一个dbs_data实例,然后把通过参数cdata传入的common_dbs_data指针,赋值给它的cdata字段,这样,policy就可以通过该字段获得governor的操作接口(通过cdata的一系列回调函数)。然后,调用cdata的init回调函数,对这个governor做进一步的初始化工作,对于ondemand来说,init回调的实际执行函数是:od_init,主要是完成和governor相关的一些调节参数的初始化,然后把初始化好的od_dbs_tuners结构指针赋值到dbs_data的tuners字段中,它的详细代码这里就不贴出了。接着,通过sysfs_create_group函数,建立该governor在sysfs中的节点,以后我们就可以通过这些节点对该governor的算法逻辑进行微调,ondemand在我的电脑中,建立了以下这些节点(sys/devices/system/cpu/cpufreq/ondemand):% `! D* ~! g& e, y. P/ z
. L* \* h# L1 S, y' Z
sampling_rate;6 _$ Q6 L$ `+ [
io_is_busy;, X6 e! f: g6 r0 ] I- J
up_threshold;1 ~2 m `* {% E. E2 g7 p% O+ h
sampling_down_factor;- ~* J& G4 x5 h; s8 f( J- G/ x+ c
ignore_nice;
* j$ P. ]( f5 ^ g* @% Cpowersave_bias;
! t% T9 @' e6 l4 Xsampling_rate_min;
2 N. C9 H6 P% x# r0 W7 b9 |
) a$ V& w7 J+ v) S; y" d, p1 I
$ x0 {& @/ C1 R& I继续,把初始化好的dbs_data结构赋值给policy的governor_data字段,以方便以后的访问。最后是通过set_sampling_rate设置governor的采样周期,如果还有设置have_governor_per_policy,把dbs_data结构指针赋值给cdata结构的gdbs_data字段,至此,governor的初始化工作完成,下面是整个过程的序列图:
. o( Y5 R, r; I
7 a* T* ~( t" n, N- D: l
1 s; z Y* W: m! T4 [3 `( E$ A# j 图 3.1 governor的初始化
0 ?/ i$ r8 ~- t* Y" _0 _7 Y
! R, H0 \, w/ M: q6 E0 c4 [: b7 Z/ V% n8 X/ n% c# G* Z
|
|