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

Linux动态频率调节系统CPUFreq之定义一个governor

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
Linux动态频率调节系统CPUFreq之定义一个governor1 q8 w7 G8 a3 ?4 D

7 C& Y1 z  f/ S  A" W2 T

4 p, a2 b/ q, f* y5 h# }要实现一个governor,首先要定义一个cpufreq_governor结构,对于ondeman来说,它的定义如下:
) Z! F1 ~- O$ a3 o+ B* [
7 ?, U' H# b: d" r
# u- }# T; D" }* `3 Q
  • struct cpufreq_governor cpufreq_gov_ondemand = {
  •         .name                   = "ondemand",
  •         .governor               = od_cpufreq_governor_dbs,
  •         .max_transition_latency = TRANSITION_LATENCY_LIMIT,
  •         .owner                  = THIS_MODULE,
  • };5 M# c+ O! {7 R0 n
8 ^" ?' t# H8 i) Y/ {/ b: @1 a
2 l, J+ ]3 C* F+ k
: ]$ E9 J: m& v  H
8 Q. z5 w1 {4 h& g5 C4 J. y! u- F
: C) y, a) ~6 e% S7 y
其中,governor是这个结构的核心字段,cpufreq_governor注册后,cpufreq的核心层通过该字段操纵这个governor的行为,包括:初始化、启动、退出等工作。现在,该字段被设置为od_cpufreq_governor_dbs,我们看看它的实现:
* G7 ]. J6 Z; ~, G/ S
  p7 P  E- Z# e( d5 r0 _5 ~

( r" T- ?' \: ^; ?
  • static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy,
  •                 unsigned int event)
  • {
  •         return cpufreq_governor_dbs(policy, &od_dbs_cdata, event);
  • }
    1 F! Z' |5 Z3 H  q: G( y

$ [* I/ k/ m5 P9 I/ p7 v0 v* e0 S# B* R4 q- D7 q6 D
6 ?5 r% _2 W7 Y1 g) w2 o
% @9 t( Z$ o( u9 L

, n  }% ]5 M& u1 @5 p4 A" @$ E& A只是简单地调用了governor的公共层提供的API:cpufreq_governor_dbs,关于这个API,我们在后面会逐一进行展开,这里我们注意到参数:&od_dbs_cdata,正是我们前面讨论过得common_dbs_data结构,作为和governor公共层的接口,在这里它的定义如下:
, D0 @; u: ]$ h% A" m2 ?* L) O; E' F) E& b$ M7 v6 i9 N" a( J% R9 p5 v
) B$ [! k# Q1 E
  • static struct common_dbs_data od_dbs_cdata = {
  •         .governor = GOV_ONDEMAND,
  •         .attr_group_gov_sys = &od_attr_group_gov_sys,
  •         .attr_group_gov_pol = &od_attr_group_gov_pol,
  •         .get_cpu_cdbs = get_cpu_cdbs,
  •         .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
  •         .gov_dbs_timer = od_dbs_timer,
  •         .gov_check_cpu = od_check_cpu,
  •         .gov_ops = &od_ops,
  •         .init = od_init,
  •         .exit = od_exit,
  • };
    , a0 u3 g% H8 i
  |, V/ D+ g. }' [' Z- t

; J. a& h. U. a  r, v$ c4 f
; i' `2 a  S& N; s) m* Z7 _" A

8 b' |( h' n2 o  g

# ]0 Y' C  A, R# L. y0 D这里先介绍一下get_cpu_cdbs和get_cpu_dbs_info_s这两个回调,前面介绍cpu_dbs_common_info_s结构的时候已经说过,各个governor需要定义一个cpu_dbs_common_info_s结构的派生结构,对于ondemand来说,这个派生结构是:od_cpu_dbs_info_s。两个回调函数分别用来获得基类和派生类这两个结构的指针。我们先看看od_cpu_dbs_info_s是如何定义的:5 U1 k8 F& X' c! U' {* Z
( ]. V) C5 @6 j

8 T' x2 x4 o2 z, H% N" y% @
  • static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
    ) l  C- u2 _) i7 |6 i4 g

( M( A% P7 N: A6 |0 l% Z% o. j+ c) j2 K5 R2 k" ^' A

  u  m- U3 |8 Z9 K# W" J0 v. B2 W0 m% t& a6 B0 A

8 {# Q/ W* D% y2 A2 z7 i没错,它被定义为了一个per_cpu变量,也就是说,每个cpu拥有各自独立的od_cpu_dbs_info_s,这很正常,因为每个cpu需要的实时负载是不一样的,需要独立的上下文变量来进行负载的统计。前面也已经列出了od_cpu_dbs_info_s的声明,他的第一个字段cdbs就是一个cpu_dbs_common_info_s结构。内核为我们提供了一个辅助宏来帮助我们定义get_cpu_cdbs和get_cpu_dbs_info_s这两个回调函数:
% G: Y; E" u2 W& u& R9 M$ B& z6 o8 i4 b* e1 C% D

# l* V9 O- b" d6 {
  • #define define_get_cpu_dbs_routines(_dbs_info)                          \
  • static struct cpu_dbs_common_info *get_cpu_cdbs(int cpu)                \
  • {                                                                       \
  •         return &per_cpu(_dbs_info, cpu).cdbs;                           \
  • }                                                                       \
  •                                                                         \
  • static void *get_cpu_dbs_info_s(int cpu)                                \
  • {                                                                       \
  •         return &per_cpu(_dbs_info, cpu);                                \
  • }      
    : I# J; J/ ^0 h( {( R& J
8 B3 X. j4 X; T( [, j

3 u, i. w( I+ ]3 b3 e7 O

' I; Q6 \: R( q1 p8 q& T3 E2 C& c9 o, z2 @0 {( h

) b% q8 Z! a( W. U9 c% ~8 _: @7 O" Z所以,在cpufreq_ondemand.c中,我们只要简单地使用上述的宏即可定义这两个回调:& V* K  D$ ]7 V" C4 }7 J

* G, E6 |/ g+ Q" e
& a5 u$ U; o' N5 p
  • define_get_cpu_dbs_routines(od_cpu_dbs_info);/ R) Z* j; c0 Q, |3 C5 l, [
! i# y; ~1 [7 T2 L  [* X6 z3 ], K

  f  d, i, U+ r# x5 p. e

1 A  J; U- K) D) y% A
% E& q$ v& J3 N+ u4 n5 v
5 W9 |$ Z( C0 V( c$ x; V
经过上述这一系列的定义以后,governor的公共层即可通过这两个回调获取各个cpu所对应的cpu_dbs_common_info_s和od_cpu_dbs_info_s的结构指针,用来记录本次统计周期的一些上下文参数(idle时间和运行时间等等)。) L# I% a: Q: r+ y; x( Q4 h

2 e  g$ y' g$ A/ m
& d* e: l! v0 C; x6 m. I( y0 `' p
5 A6 P% M- ?$ f, d
) P# X) Z; X9 c) Y/ a

6 v- c& c- m9 T4 h: q' f
9 o, l. N" I. q! W

2 V/ a5 C& W$ K' V8 ~" s5 _* p7 n( ^8 ^' Y2 k* s# k

# X. V( H/ z' `  a9 e. ?6 N. o6 |) X
: g# ^" n. d4 }  h* h1 `! Y
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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