当前位置:网站首页>一点点读懂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移除和生效
边栏推荐
猜你喜欢
随机推荐
Will we still need browsers in the future?(feat. Maple words Maple language)
Pytest学习-Fixture
ANT1.7下载以及配置方法
360市值四年蒸发3900亿,政企安全能救命吗?
亿流量大考(3):不加机器,如何抗住每天百亿级高并发流量?
【3D建模制作技巧分享】ZBrush模型如何添加不同材质
【字符串函数内功修炼】strlen + strstr + strtok + strerror(三)
the warmest home
【组成原理 六 存储器类型】
Detailed usage of LocalDateTime
特征工程资料汇总
The Record of Reminding myself
MySQL的JSON 数据类型1
线上虚拟展馆展示具有哪些优势
2022/8/4 树上差分+线段树
panic: reflect: reflect.Value.SetString using value obtained using unexported field
Using ngrok to optimize web pages on raspberry pi (2)
论文解读(PPNP)《Predict then Propagate: Graph Neural Networks meet Personalized PageRank》
单片机原理[一] 学好单片机必会的五张图
各行各业都受到重创,游戏行业却如火如荼,如何加入游戏模型师职业










