Linux
内核使用通知链的机制在内核各子系统之间进行事件通知(注:无法用于内核态和用户态之间的事件通知)。
一、通知链介绍
在文件include/linux/notifier.h
中,可以查看Linux
内核定义的四种通知链类型:
通知链类型 | 初始化 | 注册函数 | 通知函数 |
---|---|---|---|
Atomic notifier chains(原子通知链) | ATOMIC_NOTIFIER_HEAD() | atomic_notifier_chain_register()/ atomic_notifier_chain_unregister() |
atomic_notifier_call_chain() |
Blocking notifier chains(可阻塞通知链) | BLOCKING_NOTIFIER_HEAD() | blocking_notifier_chain_register()/ blocking_notifier_chain_unregister |
blocking_notifier_call_chain() |
Raw notifier chains(原始通知链) | RAW_NOTIFIER_HEAD() | raw_notifier_chain_register()/<br />raw_notifier_chain_unregister() | raw_notifier_call_chain() |
SRCU notifier chains(SRCU通知链) | srcu_init_notifier_head() | srcu_notifier_chain_register()/<br />srcu_notifier_chain_unregister | srcu_notifier_call_chain() |
说明:
1、原子通知链:通知链的回调函数在中断或原子上下文中运行,不允许阻塞。
2、可阻塞通知链:通知链的回调函数在进程上下文中运行,允许堵塞。
3、原始通知链:对通知链的回调函数没有限制,调用者维护锁和保护。
4、SRCU通知链:阻塞通知链的一个变体。
二、通知链应用
以系统睡眠唤醒为例,介绍可阻塞通知链的使用。
## kernel/power/main.c
## 1.初始化通知链pm_chain_head
static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
## kernel/power/wakeup_reason.c
## 2.注册通知链
## 2.1通知链回调函数实现
static int wakeup_reason_pm_event(struct notifier_block *notifier,
unsigned long pm_event, void *unused)
{
switch (pm_event) {
case PM_SUSPEND_PREPARE:
...
}
}
static struct notifier_block wakeup_reason_pm_notifier_block = {
.notifier_call = wakeup_reason_pm_event,
};
## 2.2注册通知链
int __init wakeup_reason_init(void)
{
...
retval = register_pm_notifier(&wakeup_reason_pm_notifier_block);
....
}
int register_pm_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&pm_chain_head, nb);
}
## kernel/power/suspend.c
## 3.通知
static int suspend_prepare(suspend_state_t state)
{
...
## 3.1 发送PM_SUSPEND_PREPARE通知时,调用.notifier_call()对应的wakeup_reason_pm_event()函数处理。
error = __pm_notifier_call_chain(PM_SUSPEND_PREPARE, -1, &nr_calls);
...
}
int __pm_notifier_call_chain(unsigned long val, int nr_to_call, int *nr_calls)
{
...
ret = __blocking_notifier_call_chain(&pm_chain_head, val, NULL,
nr_to_call, nr_calls);
...
}
网友评论