notifier chain有4种类型的实现:atomic,blocking,raw,rcu。但是
实际上的实体是3个函数:
extern int notifier_chain_register (struct notifier_block **list, struct notifier_block *n ); extern int notifier_chain_unregister (struct notifier_block **nl, struct notifier_block *n );
static int __kprobes notifier_call_chain(struct notifier_block **nl,
unsigned long val, void *v,
int nr_to_call, int *nr_calls)
notifier_chain_ register是将n注册到list中间,notifier_chain_ unregister是将n从list中间去掉,
struct notifier_block {
int (*notifier_call)(struct notifier_block *, unsigned long, void *);
struct notifier_block *next;
int priority;
};
而call chain 的nl为list header,unsigned long val , void *v 是代入到 上面notifier_block 结构中notifier_call_chain 中的函数参数,int nr_to_call, int *nr_calls 这两个参数 。基本没有作用,但是
在notifier_call_chain中是有用,但是从上层传入的参数值没有效的。
priority的值大小表示在list中的位置,优先级大的靠在list头。
atomic是用spin_lock_irqsave对notify list做保护。
int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
121 struct notifier_block *n)
122 {
123 unsigned long flags;
124 int ret;
125
126 spin_lock_irqsave(&nh->lock, flags);
127 ret = notifier_chain_register(&nh->head, n);
128 spin_unlock_irqrestore(&nh->lock, flags);
129 return ret;
130 }
blocking 是用write_up/write_down,raw就是不保护,srcu是用mutex_lock.
srcu比blocking更加轻量级。