linux 通知链,Linux内核通知链notifier

当有事件发生时,通知者调用 notifier_call_chain

函数通知事件的到达,这个函数会遍历n1指向的通知链中所有的元素,然后依次调用每一个的回调函数,完成通知动作。

static int __kprobes notifier_call_chain(struct notifier_block

**nl,

unsigned long val, void *v,

int nr_to_call,

int *nr_calls)

{

int ret = NOTIFY_DONE;

struct notifier_block *nb, *next_nb;

nb = rcu_dereference_raw(*nl);

while (nb && nr_to_call) {

next_nb = rcu_dereference_raw(nb->next);

#ifdef CONFIG_DEBUG_NOTIFIERS

if

(unlikely(!func_ptr_is_kernel_text(nb->notifier_call)))

{

WARN(1, "Invalid notifier called!");

nb = next_nb;

continue;

}

#endif

ret = nb->notifier_call(nb, val, v);

if (nr_calls)

(*nr_calls)++;

if ((ret & NOTIFY_STOP_MASK) ==

NOTIFY_STOP_MASK)

break;

nb = next_nb;

nr_to_call--;

}

return ret;

}

在kernel/notifier.c中内核根据通知链的类型分别包装了上面这个函数:

int atomic_notifier_call_chain(struct atomic_notifier_head

*nh,

unsigned long val, void *v)

int blocking_notifier_call_chain(struct blocking_notifier_head

*nh,

unsigned long val, void *v)

int raw_notifier_call_chain(struct raw_notifier_head *nh,

unsigned long val, void *v)

int srcu_notifier_call_chain(struct srcu_notifier_head *nh,

unsigned long val, void *v)

5.通知链四种类型

(5.1)原子通知链的链头:

通知链元素的回调函数(当事件发生时要执行的函数)只能在中断上下文中运行,不允许阻塞。

struct atomic_notifier_head {

spinlock_t lock;

struct notifier_block *head;

};

(5.2)可阻塞通知链:

通知链元素的回调函数在进程上下文中运行,允许阻塞。

struct blocking_notifier_head {

struct rw_semaphore rwsem;

struct notifier_block *head;

};

(5.3)原始通知链:

对通知链元素的回调函数没有任何限制,所有锁和保护机制都由调用者维护。

struct raw_notifier_head {

struct notifier_block *head;

};

(5.4)SRCU 通知链:

可阻塞通知链的变种。

struct srcu_notifier_head {

struct mutex mutex;

struct srcu_struct srcu;

struct notifier_block *head;

};

(6)定义一个通知链的头部结点并初始化:

在include/linux/Notifier.h中

初始化宏定义:

#define ATOMIC_NOTIFIER_INIT(name) {

\

.lock = __SPIN_LOCK_UNLOCKED(name.lock),

\

.head = NULL }

#define BLOCKING_NOTIFIER_INIT(name) {

\

.rwsem = __RWSEM_INITIALIZER((name).rwsem),

\

.head = NULL }

#define RAW_NOTIFIER_INIT(name)

{

\

.head = NULL }

定义通知链:

#define ATOMIC_NOTIFIER_HEAD(name)

\

struct atomic_notifier_head name =

\

ATOMIC_NOTIFIER_INIT(name)

#define BLOCKING_NOTIFIER_HEAD(name)

\

struct blocking_notifier_head name =

\

BLOCKING_NOTIFIER_INIT(name)

#define RAW_NOTIFIER_HEAD(name)

\

struct raw_notifier_head name =

\

RAW_NOTIFIER_INIT(name)

转自:http://blog.csdn.net/xiyu_1986/article/details/6641378

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值