If (subsystem_X_enabled) {
do_something_1
}
if (subsystem_Y_enabled) {
do_something_2
}
If (subsystem_Z_enabled) {
do_something_3
}
... ... ...
//通知块
struct notifier_block
{
int (*notifier_call)(struct notifier_block *self, unsigned long, void *);//回调函数
struct notifier_block *next; //
int priority; //注册的优先级,用户自行指定,优先级越高回调函数就越早执行
};//原子通知表链
struct atomic_notifier_head {
spinlock_t lock;
struct notifier_block __rcu *head;
};
//可阻塞通知表链
struct blocking_notifier_head {
struct rw_semaphore rwsem;
struct notifier_block __rcu *head;
};
//原始通知表链
struct raw_notifier_head {
struct notifier_block __rcu *head;
};
//可阻塞通知表链的变体
struct srcu_notifier_head {
struct mutex mutex;
struct srcu_struct srcu;
struct notifier_block __rcu *head;
};
static RAW_NOTIFIER_HEAD(netdev_chain);
#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)
#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 }
/* srcu_notifier_heads cannot be initialized statically */int notifier_chain_register(struct notifier_block **list, struct notifier_block *n) int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
int register_netdevice_notifier(struct notifier_block *nb)
{
raw_notifier_chain_register(&netdev_chain, nb);
}
int raw_notifier_chain_register(struct raw_notifier_head *nh,
struct notifier_block *n)
{
return notifier_chain_register(&nh->head, n);
} 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;
}深入理解Linux网络技术内幕——Notification内核通知表链
原文地址:http://blog.csdn.net/windeal3203/article/details/43270847