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频率通知链类型。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。