📄 notifier.c
字号:
* of the last notifier function called. */int __blocking_notifier_call_chain(struct blocking_notifier_head *nh, unsigned long val, void *v, int nr_to_call, int *nr_calls){ int ret = NOTIFY_DONE; /* * We check the head outside the lock, but if this access is * racy then it does not matter what the result of the test * is, we re-check the list after having taken the lock anyway: */ if (rcu_dereference(nh->head)) { down_read(&nh->rwsem); ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); up_read(&nh->rwsem); } return ret;}EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);int blocking_notifier_call_chain(struct blocking_notifier_head *nh, unsigned long val, void *v){ return __blocking_notifier_call_chain(nh, val, v, -1, NULL);}EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);/* * Raw notifier chain routines. There is no protection; * the caller must provide it. Use at your own risk! *//** * raw_notifier_chain_register - Add notifier to a raw notifier chain * @nh: Pointer to head of the raw notifier chain * @n: New entry in notifier chain * * Adds a notifier to a raw notifier chain. * All locking must be provided by the caller. * * Currently always returns zero. */int raw_notifier_chain_register(struct raw_notifier_head *nh, struct notifier_block *n){ return notifier_chain_register(&nh->head, n);}EXPORT_SYMBOL_GPL(raw_notifier_chain_register);/** * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain * @nh: Pointer to head of the raw notifier chain * @n: Entry to remove from notifier chain * * Removes a notifier from a raw notifier chain. * All locking must be provided by the caller. * * Returns zero on success or %-ENOENT on failure. */int raw_notifier_chain_unregister(struct raw_notifier_head *nh, struct notifier_block *n){ return notifier_chain_unregister(&nh->head, n);}EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);/** * __raw_notifier_call_chain - Call functions in a raw notifier chain * @nh: Pointer to head of the raw notifier chain * @val: Value passed unmodified to notifier function * @v: Pointer passed unmodified to notifier function * @nr_to_call: See comment for notifier_call_chain. * @nr_calls: See comment for notifier_call_chain * * Calls each function in a notifier chain in turn. The functions * run in an undefined context. * All locking must be provided by the caller. * * If the return value of the notifier can be and'ed * with %NOTIFY_STOP_MASK then raw_notifier_call_chain() * will return immediately, with the return value of * the notifier function which halted execution. * Otherwise the return value is the return value * of the last notifier function called. */int __raw_notifier_call_chain(struct raw_notifier_head *nh, unsigned long val, void *v, int nr_to_call, int *nr_calls){ return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);}EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);int raw_notifier_call_chain(struct raw_notifier_head *nh, unsigned long val, void *v){ return __raw_notifier_call_chain(nh, val, v, -1, NULL);}EXPORT_SYMBOL_GPL(raw_notifier_call_chain);/* * SRCU notifier chain routines. Registration and unregistration * use a mutex, and call_chain is synchronized by SRCU (no locks). *//** * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain * @nh: Pointer to head of the SRCU notifier chain * @n: New entry in notifier chain * * Adds a notifier to an SRCU notifier chain. * Must be called in process context. * * Currently always returns zero. */int srcu_notifier_chain_register(struct srcu_notifier_head *nh, struct notifier_block *n){ int ret; /* * This code gets used during boot-up, when task switching is * not yet working and interrupts must remain disabled. At * such times we must not call mutex_lock(). */ if (unlikely(system_state == SYSTEM_BOOTING)) return notifier_chain_register(&nh->head, n); mutex_lock(&nh->mutex); ret = notifier_chain_register(&nh->head, n); mutex_unlock(&nh->mutex); return ret;}EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);/** * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain * @nh: Pointer to head of the SRCU notifier chain * @n: Entry to remove from notifier chain * * Removes a notifier from an SRCU notifier chain. * Must be called from process context. * * Returns zero on success or %-ENOENT on failure. */int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh, struct notifier_block *n){ int ret; /* * This code gets used during boot-up, when task switching is * not yet working and interrupts must remain disabled. At * such times we must not call mutex_lock(). */ if (unlikely(system_state == SYSTEM_BOOTING)) return notifier_chain_unregister(&nh->head, n); mutex_lock(&nh->mutex); ret = notifier_chain_unregister(&nh->head, n); mutex_unlock(&nh->mutex); synchronize_srcu(&nh->srcu); return ret;}EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);/** * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain * @nh: Pointer to head of the SRCU notifier chain * @val: Value passed unmodified to notifier function * @v: Pointer passed unmodified to notifier function * @nr_to_call: See comment for notifier_call_chain. * @nr_calls: See comment for notifier_call_chain * * Calls each function in a notifier chain in turn. The functions * run in a process context, so they are allowed to block. * * If the return value of the notifier can be and'ed * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain() * will return immediately, with the return value of * the notifier function which halted execution. * Otherwise the return value is the return value * of the last notifier function called. */int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, unsigned long val, void *v, int nr_to_call, int *nr_calls){ int ret; int idx; idx = srcu_read_lock(&nh->srcu); ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); srcu_read_unlock(&nh->srcu, idx); return ret;}EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);int srcu_notifier_call_chain(struct srcu_notifier_head *nh, unsigned long val, void *v){ return __srcu_notifier_call_chain(nh, val, v, -1, NULL);}EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);/** * srcu_init_notifier_head - Initialize an SRCU notifier head * @nh: Pointer to head of the srcu notifier chain * * Unlike other sorts of notifier heads, SRCU notifier heads require * dynamic initialization. Be sure to call this routine before * calling any of the other SRCU notifier routines for this head. * * If an SRCU notifier head is deallocated, it must first be cleaned * up by calling srcu_cleanup_notifier_head(). Otherwise the head's * per-cpu data (used by the SRCU mechanism) will leak. */void srcu_init_notifier_head(struct srcu_notifier_head *nh){ mutex_init(&nh->mutex); if (init_srcu_struct(&nh->srcu) < 0) BUG(); nh->head = NULL;}EXPORT_SYMBOL_GPL(srcu_init_notifier_head);/** * register_reboot_notifier - Register function to be called at reboot time * @nb: Info about notifier function to be called * * Registers a function with the list of functions * to be called at reboot time. * * Currently always returns zero, as blocking_notifier_chain_register() * always returns zero. */int register_reboot_notifier(struct notifier_block *nb){ return blocking_notifier_chain_register(&reboot_notifier_list, nb);}EXPORT_SYMBOL(register_reboot_notifier);/** * unregister_reboot_notifier - Unregister previously registered reboot notifier * @nb: Hook to be unregistered * * Unregisters a previously registered reboot * notifier function. * * Returns zero on success, or %-ENOENT on failure. */int unregister_reboot_notifier(struct notifier_block *nb){ return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);}EXPORT_SYMBOL(unregister_reboot_notifier);static ATOMIC_NOTIFIER_HEAD(die_chain);int notify_die(enum die_val val, const char *str, struct pt_regs *regs, long err, int trap, int sig){ struct die_args args = { .regs = regs, .str = str, .err = err, .trapnr = trap, .signr = sig, }; return atomic_notifier_call_chain(&die_chain, val, &args);}int register_die_notifier(struct notifier_block *nb){ vmalloc_sync_all(); return atomic_notifier_chain_register(&die_chain, nb);}EXPORT_SYMBOL_GPL(register_die_notifier);int unregister_die_notifier(struct notifier_block *nb){ return atomic_notifier_chain_unregister(&die_chain, nb);}EXPORT_SYMBOL_GPL(unregister_die_notifier);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -