大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣。为了满足这个需求,也即是让某个子系统在发生某个事件时通知其它的子系统,Linux内核提供了通知链的机制。通知链表只能够在内核的子系统之间使用,而不能够在内核与用户空间之间进行事件的通知。通知链表是一个函数链表,链表上的每一个节点都注册了一个函数。当某个事情发生时,链表上所有节点对应的函数就会被执行。所以对于通知链表来说有一个通知方与一个接收方。在通知这个事件时所运行的函数由被通知方决定,实际上也即是被通知方注册了某个函数,在发生某个事件时这些函数就得到执行。
通知链技术可以概括为:事件的接收者将事件发生时应该执行的操作通过函数指针方式保存在链表中,然后当事件发生时通知者依次执行链表中每一个元素的回调函数。
一、notifier chain 定义和接口
struct notifier_block {
int (*notifier_call)(struct notifier_block *, unsigned long, void *); // 回调函数接口
struct notifier_block *next; // 指向下一个通知结构
int priority; // 当前通知链的优先级
};
可以看到通知链的基础数据结构比较简单,有回调函数接口、下一节点指针、优先级三个成员,其中回调函数的三个参数分别为:指向当前结构的指针、事件类型、参数;内核提供了4种常用的通知链,分别为:
1、Atomic notifier chains
原子通知链:通知链元素的回调函数(当事件发生时要执行的函数)只能在中断上下文中运行,不允许阻塞
struct atomic_notifier_head {
spinlock_t lock;
struct notifier_block *head;
};
由宏 ATOMIC_NOTIFIER_HEAD(name) 初始化链表头,其注册、注销及通知接口分别为:
int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *n);
int atomic_notifier_chain_unregister(struct atomic_notifi