大部分内核模块都是独立的,但有时某个模块对其他模块的事件感兴趣或者需要通知其他模块时,就需要用到内核通知链。
内核通知链只能用在内核各模块之间,无法用在内核与用户通信。
从原理来说,内核通知链就是个函数链表,链表上的每个节点都注册一个对应函数,当事件发生时,对应链表上的每个节点函数将被调用。从结构来说,链表有个通知方和接收方,通知时执行函数由被通知方注册执行。
内核通知链主要有4种:原子通知链,可阻塞通知链,原始通知链及SRCU通知链。
结构分别如下:(Linux\include\notifier.h)
原子通知链:通知链的回调函数只能在中断上下文中使用,无法被阻塞
struct atomic_notifier_head
{
spinlock_t lock;
struct notifier_block __rcu *head;
}
ATOMIC_NOTIFIER_HEAD(name)
可阻塞通知链:通知链的回调函数可在进程上下文中使用,允许阻塞
struct blocking_notifier_head
{
struct rwsemaphore rwsem;
struct notifier_block __rcu *head;
}
BLOCKING_NOTIFIER_HEAD(name)
原始通知链:通知链的回调函数没有限制,保护机制有调用者维护
struct raw_notifier_head
{
struct notifier_block __rcu *head;
}
RAE_NOTIFIER_HEAD(name)
SRCU通知链:可阻塞通知链的一种变种
struct srcu_notifier_head
{
struct mutex mutex;
struct srcu_struct srcu;
struct notifier_block __rcu *head;
}
srcu_notifier_head必须要动态创建和清除
srcu_init_notifier_h