首页 理论教育 Linux驱动开发实例:通知链和其四种类型简介

Linux驱动开发实例:通知链和其四种类型简介

时间:2023-10-19 理论教育 版权反馈
【摘要】:当某个子系统中的某个状态发生变化时,有时候需要通知其他子系统做出相应的处理。为满足这种需求,内核出现了通知链机制。notifier_block结构描述一个通知单元:通知链有四种类型,分别是原子通知链、可阻塞通知链、原始通知链、SRCU通知链:原子通知链的回调函数在中断或原子上下文中运行,不允许阻塞。原始通知链不限制回调运行环境,保护措施由调用者自己维护。SRCU通知链是可阻塞通知链的变种,它使用可睡眠的RCU机制而不是rw-semaphores来保护通知链。

Linux驱动开发实例:通知链和其四种类型简介

Linux内核分为多个子系统,但这些子系统之间并非相互独立。当某个子系统中的某个状态发生变化时,有时候需要通知其他子系统做出相应的处理。为满足这种需求,内核出现了通知链(Notifier Chain)机制。notifier_block结构描述一个通知单元

通知链有四种类型,分别是原子通知链、可阻塞通知链、原始通知链、SRCU通知链:

原子通知链的回调函数在中断或原子上下文中运行,不允许阻塞。可阻塞通知链的回调函数在进程上下文中运行,允许阻塞。原始通知链不限制回调运行环境,保护措施由调用者自己维护。SRCU通知链是可阻塞通知链的变种,它使用可睡眠的RCU机制(Sleepable Read-Copy Update)而不是rw-semaphores来保护通知链。这四种通知链对应的通知单元注册函数如下

int atomic_notifier_chain_register(struct atomic_notifier_head*nh,struct notifier_block*nb);

int blocking_notifier_chain_register(struct blocking_notifier_head*nh,struct notifier_block*nb);

int raw_notifier_chain_register(struct raw_notifier_head*nh,struct notifier_block*nb);

int srcu_notifier_chain_register(struct srcu_notifier_head*nh,struct notifier_block*nb);

下面以内核自带的网络设备通知链来说明通知链的用法。首先定义一个通知链:

static RAW_NOTIFIER_HEAD(netdev_chain);

其次提供一个网络设备通知链注册接口以及一个状态变化通知接口:

需要接收通知的模块要在网络设备通知链上注册通知单元,如ARP模块的通知单元注册代码如下:

需要发送网络设备通知的模块会调用call_netdevice_notifiers,在网络设备通知链上注册过的通知单元的回调函数都会被调用。例如网卡MAC地址变更函数:

Linux内核另一个重要的通知链就是CPU频率通知链,CPU频率通知链有两种类型,即转变通知链和策略通知链:

#define CPUFREQ_TRANSITION_NOTIFIER (0)

#define CPUFREQ_POLICY_NOTIFIER (1)(www.xing528.com)

/*转变通知链*/

#define CPUFREQ_PRECHANGE (0)

#define CPUFREQ_POSTCHANGE (1)

/*策略通知链*/

#define CPUFREQ_ADJUST (0)

#define CPUFREQ_NOTIFY (1)

#define CPUFREQ_START (2)

#define CPUFREQ_CREATE_POLICY (3)

#define CPUFREQ_REMOVE_POLICY (4)

static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);

static struct srcu_notifier_head cpufreq_transition_notifier_list;

注册CPU频率通知链的函数为:

int cpufreq_register_notifier(struct notifier_block*nb,unsigned int list);

list参数就是CPU频率通知链类型。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈