|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Linux动态频率调节系统CPUFreq之governor的启动
2 g9 |# ^8 c5 T: _; m9 C
. r9 n- z) s6 p: T9 Q核心层会通过__cpufreq_set_policy函数,通过CPUFREQ_GOV_POLICY_INIT参数,在公共层的API:cpufreq_governor_dbs中,完成了对governor的初始化工作,紧接着,__cpufreq_set_policy会通过CPUFREQ_GOV_START参数,和初始化governor的流程一样,最终会到达cpufreq_governor_dbs函数中,我们看看它是如何启动一个governor的:8 M4 M1 T. I2 a; K6 Q }
4 Y. {. \5 T6 o/ f- l/ K7 L6 E- 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);
- }
* ~$ ? d" [3 }7 j2 u. r 1 f+ [" L: D) c$ S) Y1 z1 l% E
+ a4 L; h7 Z- R$ s
7 y, a ^. M6 K7 M) O. t6 _# L. @首先,遍历使用该policy的所有的处于online状态的cpu,针对每一个cpu,做以下动作:
% A5 J6 _3 P7 _, e: m- 取出该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负载的统计工作。
) d; D1 a! H. G- X0 ]2 B* s / N, Z$ s5 O5 v" h: I/ J
) \4 W: T+ Q, ^0 U
5 G4 A0 s* r" d% o$ {4 W' i- @4 X; D( y9 x
然后,记录目前的时间戳,调度初始化好的工作队列在稍后某个时间点运行:
$ a8 ]' T3 ?7 A/ w9 v- l- l" ?# u5 r/ O2 j' {& G, ]
- /* Initiate timer time stamp */
- cpu_cdbs->time_stamp = ktime_get();
- gov_queue_work(dbs_data, policy,
- delay_for_sampling_rate(sampling_rate), true);
) Z) F$ V+ D' |7 Q3 b" N / a$ H7 Q2 C0 A% m
; u" s- Y( g m+ w+ q4 Z
* i/ `" I M: f @& S& T% s9 Q/ L3 q下图表达了启动一个governor的过程:
+ B0 I% L, A" _) C9 ?. L: j
5 G( X% b! O2 S" R: w' D9 D0 ?
: Q4 v6 h; p2 ?3 g7 [! r d3 | {
' B3 ^' W1 |8 G2 w% V: K: g
图 4.1 启动一个governor
+ v5 @5 J. m* {: v" A. V- u9 b% f' r" s. J$ B: }( `; P
' G& C3 r; [$ N1 A
工作队列被调度执行后,会在工作队列的执行函数中进行cpu负载的统计工作,这个我们在下一节中讨论。、4 n7 C; _& d# t- `# T1 ]8 o9 n/ W
/ {& A A* k$ b+ U' m; l
h2 c) y4 r( U L
4 }0 [' i) f0 |' C. l1 m" }8 `( a9 `. s+ Z( k
3 i9 a# [7 [5 Y4 s, Y: q* Q# `
7 w% S" O! Q1 \1 S3 X
: ?5 Y& l* x6 p) W5 z( w8 \7 a+ `
|
|