找回密码
 注册
关于网站域名变更的通知
查看: 500|回复: 1
打印 上一主题 下一主题

Linux动态频率调节系统CPUFreq之怎样为每个CPU建立频率调整策略(policy)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-11-1 18:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
Linux动态频率调节系统CPUFreq之怎样为每个CPU建立频率调整策略(policy)2 B" F  g! b( a3 m& }: p: \

. l& y1 P* ^/ e5 H5 o
& b% B. R" m+ T为每个cpu建立频率调整策略实在注册cpufreq_driver阶段的subsys_inteRFace_registe函数中完成的,上一节已经提到,该函数最终会调用cpufreq_add_dev回调函数,现在展开这个函数分析一下:0 l7 H; I' o) N' f3 J/ b7 w

, v6 ?1 M4 n$ A! f因为subsys_interface_registe会枚举各个cpu设备,不管该cpu处于offline还是online状态,cpufreq_add_dev都会被调用,所以函数的一开始,判断如果cpu处于offline状态,直接返回。
: I  L6 D& {  z' f, G9 D/ J  t) W3 V9 z6 i9 g7 o+ V" ~
  • static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
  • {
  •         ......
  • * m& [) o, _; ]  F$ f; A2 ^8 F
  •         if (cpu_is_offline(cpu))
  •                 return 0;+ F( ?" x6 f' o  ~* g
- r4 c* O& U6 L9 G0 G
如果是smp系统,本cpu的policy可能和其他cpu共同使用同一个policy,并委托另一个叫做管理cpu的cpu进行管理,下面的代码判断这种情况,如果已经委托别的cpu管理,则直接返回,核心层定义了另一个per_cpu变量:cpufreq_cpu_data,用来保存各个cpu所使用的cpufreq_policy结构的指针,cpufreq_cpu_get函数实际上就是通过这个per_cpu变量,获取该指针,如果该指针非0,代表该cpu已经建立好了它自身的policy(可能是在他之前的管理cpu建立policy期间一并建立的)。

: {9 O* P# f" s* y) ]1 e
$ z, r2 B; Y; ?/ w% `. ~
  •         policy = cpufreq_cpu_get(cpu);
  •         if (unlikely(policy)) {
  •                 cpufreq_cpu_put(policy);
  •                 return 0;
  •         }( w6 l8 b3 ?: ~. J1 u

: y: {( ~1 R; `. W0 G% l
" b6 T' B9 K3 Y" _$ c, O2 d/ p因为cpu hot plug期间,cpufreq_add_dev也会被调用,下面的代码片段检测该cpu之前是否被hot-unpluged过,如果是,找到其中一个相关的cpu(这些相关的cpu都委托给同一个托管它cpu进行管理,调用cpufreq_add_policy_cpu函数,该函数只是简单地建立一个cpufreq链接,链接到管理cpu的cpufreq节点。
3 x! h/ \( f8 R* ]6 Q

" o0 e3 s% m% V" u$ ^
  •        for_each_online_cpu(sibling) {
  •                 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
  •                 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
  •                         read_unlock_irqrestore(&cpufreq_driver_lock, flags);
  •                         return cpufreq_add_policy_cpu(cpu, sibling, dev);
  •                 }
  •         }
    8 V/ [! [. k+ q7 D; w

3 [) R$ o8 i- ^# g9 [0 w- d3 m, S8 z& `1 _1 c" H# `
当这是系统初始化阶段第一次调用cpufreq_add_dev时(subsys_interface_register枚举到的第一个cpu,通常就是cpu0),cpufreq_cpu_data应该为NULL,所以我们要为这样的cpu分配一个cpufreq_policy结构,并初始化该policy所管理的cpu,包括online的cpus字段和online+offline的cpu_related字段,并把自己设置为这个policy的管理cpu,使用默认governor初始化policy->governor字段,同时吧自己加入到online的cpus字段中:
1 s. p. E1 b( G: k* i7 X, ?; a

: @: \5 f# B5 t7 m% L) S; K5 f
  •         policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
  •         if (!policy)
  •                 goto nomem_out;
  • 1 l. F! t1 V+ R) l/ Z7 f
  •         if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
  •                 goto err_free_policy;

  • ! e* N* s% u3 _0 W( I2 N, D
  •         if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
  •                 goto err_free_cpumask;

  • % v$ T: r, V0 k# J1 n  n! d+ X% B) g
  •         policy->cpu = cpu;
  •         policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
  •         cpumask_copy(policy->cpus, cpumask_of(cpu));
  •   V$ L9 g. \# C4 _" b( {+ L
  •         /* Initially set CPU itself as the policy_cpu */
  •         per_cpu(cpufreq_policy_cpu, cpu) = cpu;' C+ ]' A' y9 ~% |. I* d1 _
   
% S3 {# {. m; M
  S  |" l3 P* O) p9 }2 j
游客,如果您要查看本帖隐藏内容请回复

7 b) L! r. }& J3 A1 L0 x# ~
3 A1 h6 e/ p% d
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-25 01:46 , Processed in 0.171875 second(s), 27 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表