|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Linux动态频率调节系统CPUFreq之governor的启动2 H2 h1 Z/ y2 C( {- @# T' |
) s3 ~ J$ H+ a T3 B
核心层会通过__cpufreq_set_policy函数,通过CPUFREQ_GOV_POLICY_INIT参数,在公共层的API:cpufreq_governor_dbs中,完成了对governor的初始化工作,紧接着,__cpufreq_set_policy会通过CPUFREQ_GOV_START参数,和初始化governor的流程一样,最终会到达cpufreq_governor_dbs函数中,我们看看它是如何启动一个governor的:
$ |4 Z) P y1 ? q
( h4 I! l# K! b1 G. ~7 O! ~- 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);
- }' c, ^9 t& p; S- W* ]
. `- n5 Q1 g% d7 r4 c, e) `
m. `8 q- [' V4 q
/ n( B! N( P* b2 M7 ?, d: a
首先,遍历使用该policy的所有的处于online状态的cpu,针对每一个cpu,做以下动作:; C/ G) h0 n& h) p% h' v
- 取出该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负载的统计工作。. r) H) N) H0 x; K: s: H/ O
: e' }( L; r5 x5 d
. }) ?) a& l8 b+ H+ t5 [0 v4 d
" a0 d' a3 S- a% j
; E- Z/ s k4 I" {# f% c# N然后,记录目前的时间戳,调度初始化好的工作队列在稍后某个时间点运行:# C/ U4 }, a! P5 O
+ r' s9 Y( p/ D2 `# C; @/ j
- /* Initiate timer time stamp */
- cpu_cdbs->time_stamp = ktime_get();
- gov_queue_work(dbs_data, policy,
- delay_for_sampling_rate(sampling_rate), true);
, `( H+ e2 F% Z: _ Q' x) H ; o C3 d O9 C1 O: r/ X& R/ v
, P1 b# h- Q0 l' h3 F3 R- D0 S
& A" e8 m- @1 X6 E* j2 O下图表达了启动一个governor的过程:+ W( W! _& d+ ?1 \- S
% ?4 i7 f# y8 O" A" B# P4 _* E/ T0 K8 Z8 w
4 S2 k2 @( l8 W, {9 j2 e
图 4.1 启动一个governor
* w4 ^3 n4 M% i- N/ u4 o" l& p1 e& v# ^ I& i$ ~' Y
+ Z9 ^: k9 \! x8 J: F$ z工作队列被调度执行后,会在工作队列的执行函数中进行cpu负载的统计工作,这个我们在下一节中讨论。、 N% c% V# n! D) }6 A& v/ d
& Q. D- x- A. ^ F: v* I) l- O4 l
/ b1 ]6 k% C1 m! x6 g8 t# n N/ `( l: m/ S& P2 v
+ r3 d) i5 h! g/ y/ A/ M0 a
4 E' y, |/ w1 r+ y
* v- [, m- W0 S
! K: M: M6 b& j: p6 x$ f* G |
|