|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Linux动态频率调节系统CPUFreq之governor的启动$ p2 f! h9 P3 y- @
& v# u d" o0 E/ F
核心层会通过__cpufreq_set_policy函数,通过CPUFREQ_GOV_POLICY_INIT参数,在公共层的API:cpufreq_governor_dbs中,完成了对governor的初始化工作,紧接着,__cpufreq_set_policy会通过CPUFREQ_GOV_START参数,和初始化governor的流程一样,最终会到达cpufreq_governor_dbs函数中,我们看看它是如何启动一个governor的:
" M2 h! c" t2 a; p3 h. y& X4 Q# r# Q5 }( b5 \ N8 U
- case CPUFREQ_GOV_START:
- if (!policy->cur)
- return -EINVAL;
- mutex_lock(&dbs_data->mutex);
- for_each_cpu(j, policy->cpus) {
- struct cpu_dbs_common_info *j_cdbs =
- dbs_data->cdata->get_cpu_cdbs(j);
- j_cdbs->cpu = j;
- j_cdbs->cur_policy = policy;
- j_cdbs->prev_cpu_idle = get_cpu_idle_time(j,
- &j_cdbs->prev_cpu_wall, io_busy);
- if (ignore_nice)
- j_cdbs->prev_cpu_nice =
- kcpustat_cpu(j).cpustat[CPUTIME_NICE];
- mutex_init(&j_cdbs->timer_mutex);
- INIT_DEFERRABLE_WORK(&j_cdbs->work,
- dbs_data->cdata->gov_dbs_timer);
- }
) F& Z; W8 x. \. J7 z3 `8 ?# Y' `
2 B3 a+ P. e& L6 `: {; r, Y$ D Z9 F0 d; H/ Y3 o8 W
+ q; A" k, T$ K* n+ O/ I
首先,遍历使用该policy的所有的处于online状态的cpu,针对每一个cpu,做以下动作:: c4 z% D% h: Z" k( J
- 取出该cpu相关联的cpu_dbs_common_info结构指针,之前已经讨论过,governor定义了一个per_cpu变量来定义各个cpu所对应的cpu_dbs_common_info结构,通过common_dbs_data结构的回调函数可以获取该结构的指针。
- 初始化cpu_dbs_common_info结构的cpu,cur_policy,prev_cpu_idle,prev_cpu_wall,prev_cpu_nice字段,其中,prev_cpu_idle,prev_cpu_wall这两个字段会被以后的负载计算所使用。
- 为每个cpu初始化一个工作队列,工作队列的执行函数是common_dbs_data结构中的gov_dbs_timer字段所指向的回调函数,对于ondemand来说,该函数是:od_dbs_timer。这个工作队列会被按照设定好的采样率定期地被唤醒,进行cpu负载的统计工作。4 r2 z- u+ l$ n* G: k
4 C& Q& f$ h: ?. N3 a* y8 w: ]" q( j
! `4 N2 B: O4 f+ b7 F8 T; v) y) @+ F" e
/ b7 Z, w( e& x9 z8 _. H* l( _
然后,记录目前的时间戳,调度初始化好的工作队列在稍后某个时间点运行:* N& J: n1 v# u" q+ V
/ n/ b9 {! I8 A" c0 r, T- /* Initiate timer time stamp */
- cpu_cdbs->time_stamp = ktime_get();
- gov_queue_work(dbs_data, policy,
- delay_for_sampling_rate(sampling_rate), true);
, v- a6 D3 k% ]5 v/ E5 a b- T: \" \ - ~5 l$ p1 w3 e+ c5 J& H' B
9 p' x5 W0 G' i; q6 S
5 N1 n R' A0 T! ~& s' X# p下图表达了启动一个governor的过程:
/ {% t% k+ y8 |) H7 Q5 k8 o5 F- e: R6 z. T' h
8 o; L. o! J3 k/ t) N- F; d% O
+ Y8 `& o9 n4 z9 g% C* t图 4.1 启动一个governor
1 }& w4 Y- ~0 Q- M/ W9 O: [8 l8 i+ r9 b4 X# H% j
2 E6 r A8 ?" l4 C: h0 o
工作队列被调度执行后,会在工作队列的执行函数中进行cpu负载的统计工作,这个我们在下一节中讨论。、
: r2 p6 g8 a) P2 y) G/ x
2 r" J0 ]5 W) x2 L# V+ O
; U3 B6 S7 y! ~; ]/ `; m- B3 v, O; h& ^- O
% E3 G" n# f# o- ^% S3 u1 M+ A- e0 {) |3 S6 u; ~& b: L, R3 h) Q
/ K `& N W) H& ^
# W( c; o3 |- T& [9 B8 M4 | |
|