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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
Linux动态频率调节系统CPUFreq之怎样为每个CPU建立频率调整策略(policy)) k/ w' Q  T' k. J- g7 A8 d/ {

5 J  k& m$ P; p+ e7 {0 S9 s/ N+ C8 X. G' H4 w2 Q+ d3 `. f
为每个cpu建立频率调整策略实在注册cpufreq_driver阶段的subsys_inteRFace_registe函数中完成的,上一节已经提到,该函数最终会调用cpufreq_add_dev回调函数,现在展开这个函数分析一下:
; F2 q5 }- x) o5 A4 F
; s* y+ t7 |( j因为subsys_interface_registe会枚举各个cpu设备,不管该cpu处于offline还是online状态,cpufreq_add_dev都会被调用,所以函数的一开始,判断如果cpu处于offline状态,直接返回。1 B$ I( T5 W- |/ \

8 k8 D; g/ ?8 S2 V! b6 W
  • static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
  • {
  •         ......

  • 0 M9 i) r( S# X
  •         if (cpu_is_offline(cpu))
  •                 return 0;
    0 X& o2 u. M  u- f% X

/ E2 ^* \3 C  T5 {. Q% S% n0 o如果是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期间一并建立的)。

7 a: B+ {5 ^$ s: X3 k
, z7 ^- X& s, X! a6 H& o
  •         policy = cpufreq_cpu_get(cpu);
  •         if (unlikely(policy)) {
  •                 cpufreq_cpu_put(policy);
  •                 return 0;
  •         }" C: S' ]) e$ n6 W7 E5 C
- [% r5 q  n5 u( o

* x. L6 `: P2 B* d* G因为cpu hot plug期间,cpufreq_add_dev也会被调用,下面的代码片段检测该cpu之前是否被hot-unpluged过,如果是,找到其中一个相关的cpu(这些相关的cpu都委托给同一个托管它cpu进行管理,调用cpufreq_add_policy_cpu函数,该函数只是简单地建立一个cpufreq链接,链接到管理cpu的cpufreq节点。
: |% L+ S2 Q6 f
4 b5 H( k7 l, I3 D6 \) g9 @5 b
  •        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);
  •                 }
  •         }
    7 J* D0 }/ C0 @2 j) G/ X% D

4 A% H" U, I+ F3 i
" C( J! W, r7 V* c当这是系统初始化阶段第一次调用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字段中:
) S3 t9 Z0 Y" I- O6 B/ t

( l  M' I, o( O+ D) Q& a- s
  •         policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
  •         if (!policy)
  •                 goto nomem_out;
  • " q3 A% k1 @8 N" Z! Q8 \" ~+ y# A" g
  •         if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
  •                 goto err_free_policy;

  • & J# @1 B, Z. T. s! f, R! S
  •         if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
  •                 goto err_free_cpumask;
  • " d4 p8 o/ }& r$ u8 P8 P
  •         policy->cpu = cpu;
  •         policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
  •         cpumask_copy(policy->cpus, cpumask_of(cpu));

  • / O0 H! C' r, u" Q& t7 L8 T* T2 `
  •         /* Initially set CPU itself as the policy_cpu */
  •         per_cpu(cpufreq_policy_cpu, cpu) = cpu;3 K' f, ?4 Q) e, B
   
8 ^. [5 U5 o* f$ B0 Y
4 e5 X5 ]! y) t2 F6 I
游客,如果您要查看本帖隐藏内容请回复

+ V7 [1 d1 D& Y
- H+ C( t* Q: Y' {  i" q$ ^
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-8-24 11:31 , Processed in 0.109375 second(s), 26 queries , Gzip On.

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

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

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