当前位置:网站首页>一点点读懂cpufreq(二)
一点点读懂cpufreq(二)
2022-08-04 22:50:00 【szembed】
目录
4.1 对cpufreq_transition_notifier_list的处理
4.2 对cpufreq_policy_notifier_list的处理
本章节主要介绍cpufreq中的通知链实现,在调频策略以及频率变化时来通知对该事件敏感的模块,各个模块可以通过注册和去注册接口来加入到通知链中。
1、注册接口:
-
/**
-
-
* cpufreq_register_notifier - Register a notifier with cpufreq.
-
-
* @nb: notifier function to register.
-
-
* @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER.
-
-
* Add a notifier to one of two lists: either a list of notifiers that run on
-
-
* clock rate changes (once before and once after every transition), or a list
-
-
* of notifiers that ron on cpufreq policy changes.
-
-
* This function may sleep and it has the same return values as
-
-
* blocking_notifier_chain_register().
-
-
*/
-
-
int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
-
-
{
-
-
int ret;
-
-
if (
cpufreq_disabled())
-
-
return -EINVAL;
-
-
switch (list) {
-
-
case CPUFREQ_TRANSITION_NOTIFIER:
-
-
mutex_lock(&cpufreq_fast_switch_lock);
-
-
if (cpufreq_fast_switch_count >
0) {
-
-
mutex_unlock(&cpufreq_fast_switch_lock);
-
-
return -EBUSY;
-
-
}
-
-
ret =
srcu_notifier_chain_register(
-
-
&cpufreq_transition_notifier_list, nb);
-
-
if (!ret)
-
-
cpufreq_fast_switch_count--;
-
-
mutex_unlock(&cpufreq_fast_switch_lock);
-
-
break;
-
-
case CPUFREQ_POLICY_NOTIFIER:
-
-
ret =
blocking_notifier_chain_register(
-
-
&cpufreq_policy_notifier_list, nb);
-
-
break;
-
-
default:
-
-
ret = -EINVAL;
-
-
}
-
-
return ret;
-
-
}
-
-
EXPORT_SYMBOL(cpufreq_register_notifier);
-
-
-
CPUFREQ_TRANSITION_NOTIFIER:对频率变化敏感,注册进来的模块添加到cpufreq_transition_notifier_list链表中进行维护及后续操作,模块在回调中进行处理时,可以通过CPUFREQ_PRECHANGE和CPUFREQ_POSTCHANGE来区分是在频率变化前做动作还是在变化后做动作。
CPUFREQ_POLICY_NOTIFIER:对策略变化敏感,注册进来的模块,添加到cpufreq_policy_notifier_list链表中进行维护及后续操作,模块在回调中进行处理时,可以通过CPUFREQ_CREATE_POLICY和CPUFREQ_REMOVE_POLICY来区分是在策略变化前做动作还是在变化后做动作。
2、去注册接口:
-
/**
-
-
* cpufreq_unregister_notifier - Unregister a notifier from cpufreq.
-
-
* @nb: notifier block to be unregistered.
-
-
* @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER.
-
-
* Remove a notifier from one of the cpufreq notifier lists.
-
-
* This function may sleep and it has the same return values as
-
-
* blocking_notifier_chain_unregister().
-
-
*/
-
-
int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
-
-
{
-
-
int ret;
-
-
if (
cpufreq_disabled())
-
-
return -EINVAL;
-
-
switch (list) {
-
-
case CPUFREQ_TRANSITION_NOTIFIER:
-
-
mutex_lock(&cpufreq_fast_switch_lock);
-
-
ret =
srcu_notifier_chain_unregister(
-
-
&cpufreq_transition_notifier_list, nb);
-
-
if (!ret && !
WARN_ON(cpufreq_fast_switch_count >=
0))
-
-
cpufreq_fast_switch_count++;
-
-
mutex_unlock(&cpufreq_fast_switch_lock);
-
-
break;
-
-
case CPUFREQ_POLICY_NOTIFIER:
-
-
ret =
blocking_notifier_chain_unregister(
-
-
&cpufreq_policy_notifier_list, nb);
-
-
break;
-
-
default:
-
-
ret = -EINVAL;
-
-
}
-
-
return ret;
-
-
}
-
-
EXPORT_SYMBOL(cpufreq_unregister_notifier);
去注册接口为注册接口的逆向操作,不再做过多解析。
3、使用样例
我们以loongson1-cpufreq.c作为样例
-
static int ls1x_cpufreq_notifier(struct notifier_block *nb,
-
unsigned
long val,
void *data)
-
{
-
if (val == CPUFREQ_POSTCHANGE)
-
current_cpu_data.udelay_val = loops_per_jiffy;
-
-
return NOTIFY_OK;
-
}
-
-
static
struct
notifier_block ls1x_cpufreq_notifier_block = {
-
.notifier_call = ls1x_cpufreq_notifier
-
};
该模块需要感知到频率的变化,需要在频率变化后来做一些事务处理,于是该模块就在回调中通过判断阶段为CPUFREQ_POSTCHANGE时做对应动作,并在初始化时通过调用cpufreq_register_notifier来注册。
4、软件处理
4.1 对cpufreq_transition_notifier_list的处理
现在该注册的模块已经注册进来了,那么cpufreq.c是如何回调注册的回调函数呢?cpufreq对cpufreq_transition_notifier_list链表的处理,统一封装到了函数cpufreq_notify_transition中来实现。
实际代码以cppc_cpufreq.c为例:
其中核心函数cpufreq_notify_transition的实现也是正常的逻辑实现,根据入参的不同分别处理
cpufreq_notify_transition函数会分别被cpufreq_freq_transition_begin和cpufreq_freq_transition_end来调用,而这2个函数则分别嵌入在了频率调换前和调换后调用,如此以来用户注册的回调会被最终调用到。
4.2 对cpufreq_policy_notifier_list的处理
对cpufreq_policy_notifier_list的调用,分别在cpufreq_policy_free和cpufreq_online中调用,分别针对policy移除和生效
边栏推荐
- 轮播图动态渲染
- 单片机原理[一] 学好单片机必会的五张图
- Community Sharing|Tencent Overseas Games builds game security operation capabilities based on JumpServer
- 【TCP/IP 五 ICMP】
- If you can't get your heart, use "distributed lock" to lock your people
- 湖仓一体电商项目(五):内网穿透工具-网云穿
- 【游戏建模模型制作全流程】ZBrush蜥蜴模型雕刻教程
- [Paper Notes KDD2021] MixGCF: An Improved Training Method for Graph Neural Network-based Recommender Systems
- SQL Server calls WebService
- enumerate()函数
猜你喜欢
随机推荐
直播带货为农产品开拓销售渠道
Rt-thread [二] 系统初始化流程
【游戏建模模型制作全流程】在ZBrush中雕刻恶魔城男性角色模型
正则表达式绕过
各行各业都受到重创,游戏行业却如火如荼,如何加入游戏模型师职业
BUG | 接口返回异常数据
The Controller layer code is written like this, concise and elegant!
PID控制器改进笔记之七:改进PID控制器之防超调设定
MQTT[一]基础知识介绍
得不到你的心,就用“分布式锁”锁住你的人
The Record of Reminding myself
文献阅读十——Detect Rumors on Twitter by Promoting Information Campaigns with Generative Adversarial Learn
Will we still need browsers in the future?(feat. Maple words Maple language)
FinClip崁入式搭建生态平台,降低合作门槛
使用代理对象执行实现类目标方法异常
Based on the results of the facts
地面高度检测/平面提取与检测(Fast Plane Extraction in Organized Point Clouds Using Agglomerative Hierarchical Clu)
社区分享|腾讯海外游戏基于JumpServer构建游戏安全运营能力
MySQL的JSON 数据类型1
Shell编程之循环语句与函数的使用