^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/kdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Notifier list for kernel code which wants to be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * at shutdown. This is used to stop any idling DMA operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * and the like.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Notifier chain core routines. The exported routines below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * are layered on top of these, with appropriate locking added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int notifier_chain_register(struct notifier_block **nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) while ((*nl) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (unlikely((*nl) == n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) WARN(1, "double register detected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (n->priority > (*nl)->priority)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) nl = &((*nl)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) n->next = *nl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) rcu_assign_pointer(*nl, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int notifier_chain_unregister(struct notifier_block **nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) while ((*nl) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if ((*nl) == n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) rcu_assign_pointer(*nl, n->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) nl = &((*nl)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * notifier_call_chain - Informs the registered notifiers about an event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @nl: Pointer to head of the blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @val: Value passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @v: Pointer passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @nr_to_call: Number of notifier functions to be called. Don't care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * value of this parameter is -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @nr_calls: Records the number of notifications sent. Don't care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * value of this field is NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @returns: notifier_call_chain returns the value returned by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * last notifier function called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int notifier_call_chain(struct notifier_block **nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long val, void *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int nr_to_call, int *nr_calls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int ret = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct notifier_block *nb, *next_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) nb = rcu_dereference_raw(*nl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) while (nb && nr_to_call) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) next_nb = rcu_dereference_raw(nb->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #ifdef CONFIG_DEBUG_NOTIFIERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) WARN(1, "Invalid notifier called!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) nb = next_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ret = nb->notifier_call(nb, val, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (nr_calls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) (*nr_calls)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (ret & NOTIFY_STOP_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) nb = next_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) nr_to_call--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) NOKPROBE_SYMBOL(notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * notifier_call_chain_robust - Inform the registered notifiers about an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * and rollback on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @nl: Pointer to head of the blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @val_up: Value passed unmodified to the notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @val_down: Value passed unmodified to the notifier function when recovering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * from an error on @val_up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @v Pointer passed unmodified to the notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * NOTE: It is important the @nl chain doesn't change between the two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * invocations of notifier_call_chain() such that we visit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * exact same notifier callbacks; this rules out any RCU usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Returns: the return value of the @val_up call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int notifier_call_chain_robust(struct notifier_block **nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned long val_up, unsigned long val_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int ret, nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ret = notifier_call_chain(nl, val_up, v, -1, &nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (ret & NOTIFY_STOP_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) notifier_call_chain(nl, val_down, v, nr-1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Atomic notifier chain routines. Registration and unregistration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * use a spinlock, and call_chain is synchronized by RCU (no locks).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * atomic_notifier_chain_register - Add notifier to an atomic notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @nh: Pointer to head of the atomic notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @n: New entry in notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Adds a notifier to an atomic notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Currently always returns zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) spin_lock_irqsave(&nh->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ret = notifier_chain_register(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spin_unlock_irqrestore(&nh->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @nh: Pointer to head of the atomic notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @n: Entry to remove from notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Removes a notifier from an atomic notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Returns zero on success or %-ENOENT on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) spin_lock_irqsave(&nh->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = notifier_chain_unregister(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) spin_unlock_irqrestore(&nh->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int atomic_notifier_call_chain_robust(struct atomic_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned long val_up, unsigned long val_down, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * Musn't use RCU; because then the notifier list can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * change between the up and down traversal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) spin_lock_irqsave(&nh->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = notifier_call_chain_robust(&nh->head, val_up, val_down, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) spin_unlock_irqrestore(&nh->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EXPORT_SYMBOL_GPL(atomic_notifier_call_chain_robust);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) NOKPROBE_SYMBOL(atomic_notifier_call_chain_robust);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * atomic_notifier_call_chain - Call functions in an atomic notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @nh: Pointer to head of the atomic notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @val: Value passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @v: Pointer passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Calls each function in a notifier chain in turn. The functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * run in an atomic context, so they must not block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * This routine uses RCU to synchronize with changes to the chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * If the return value of the notifier can be and'ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * will return immediately, with the return value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * the notifier function which halted execution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * Otherwise the return value is the return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * of the last notifier function called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned long val, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) NOKPROBE_SYMBOL(atomic_notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Blocking notifier chain routines. All access to the chain is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * synchronized by an rwsem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * blocking_notifier_chain_register - Add notifier to a blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @nh: Pointer to head of the blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @n: New entry in notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Adds a notifier to a blocking notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Must be called in process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Currently always returns zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * This code gets used during boot-up, when task switching is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * not yet working and interrupts must remain disabled. At
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * such times we must not call down_write().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (unlikely(system_state == SYSTEM_BOOTING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return notifier_chain_register(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) down_write(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = notifier_chain_register(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) up_write(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * @nh: Pointer to head of the blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * @n: Entry to remove from notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Removes a notifier from a blocking notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * Must be called from process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * Returns zero on success or %-ENOENT on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * This code gets used during boot-up, when task switching is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * not yet working and interrupts must remain disabled. At
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * such times we must not call down_write().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (unlikely(system_state == SYSTEM_BOOTING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return notifier_chain_unregister(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) down_write(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = notifier_chain_unregister(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) up_write(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned long val_up, unsigned long val_down, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int ret = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * We check the head outside the lock, but if this access is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * racy then it does not matter what the result of the test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * is, we re-check the list after having taken the lock anyway:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (rcu_access_pointer(nh->head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) down_read(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = notifier_call_chain_robust(&nh->head, val_up, val_down, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) up_read(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) EXPORT_SYMBOL_GPL(blocking_notifier_call_chain_robust);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * blocking_notifier_call_chain - Call functions in a blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * @nh: Pointer to head of the blocking notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @val: Value passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * @v: Pointer passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Calls each function in a notifier chain in turn. The functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * run in a process context, so they are allowed to block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * If the return value of the notifier can be and'ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * will return immediately, with the return value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * the notifier function which halted execution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Otherwise the return value is the return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * of the last notifier function called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unsigned long val, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int ret = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * We check the head outside the lock, but if this access is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * racy then it does not matter what the result of the test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * is, we re-check the list after having taken the lock anyway:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (rcu_access_pointer(nh->head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) down_read(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) up_read(&nh->rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Raw notifier chain routines. There is no protection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * the caller must provide it. Use at your own risk!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * raw_notifier_chain_register - Add notifier to a raw notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * @nh: Pointer to head of the raw notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * @n: New entry in notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * Adds a notifier to a raw notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * All locking must be provided by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * Currently always returns zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int raw_notifier_chain_register(struct raw_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return notifier_chain_register(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @nh: Pointer to head of the raw notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * @n: Entry to remove from notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * Removes a notifier from a raw notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * All locking must be provided by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * Returns zero on success or %-ENOENT on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return notifier_chain_unregister(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) unsigned long val_up, unsigned long val_down, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return notifier_call_chain_robust(&nh->head, val_up, val_down, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) EXPORT_SYMBOL_GPL(raw_notifier_call_chain_robust);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * raw_notifier_call_chain - Call functions in a raw notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * @nh: Pointer to head of the raw notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * @val: Value passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * @v: Pointer passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Calls each function in a notifier chain in turn. The functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * run in an undefined context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * All locking must be provided by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * If the return value of the notifier can be and'ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * will return immediately, with the return value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * the notifier function which halted execution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * Otherwise the return value is the return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * of the last notifier function called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int raw_notifier_call_chain(struct raw_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned long val, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return notifier_call_chain(&nh->head, val, v, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) #ifdef CONFIG_SRCU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * SRCU notifier chain routines. Registration and unregistration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * use a mutex, and call_chain is synchronized by SRCU (no locks).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * @nh: Pointer to head of the SRCU notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * @n: New entry in notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * Adds a notifier to an SRCU notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * Must be called in process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * Currently always returns zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * This code gets used during boot-up, when task switching is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * not yet working and interrupts must remain disabled. At
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * such times we must not call mutex_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (unlikely(system_state == SYSTEM_BOOTING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return notifier_chain_register(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) mutex_lock(&nh->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = notifier_chain_register(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mutex_unlock(&nh->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @nh: Pointer to head of the SRCU notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * @n: Entry to remove from notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * Removes a notifier from an SRCU notifier chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * Must be called from process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Returns zero on success or %-ENOENT on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct notifier_block *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * This code gets used during boot-up, when task switching is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * not yet working and interrupts must remain disabled. At
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * such times we must not call mutex_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (unlikely(system_state == SYSTEM_BOOTING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return notifier_chain_unregister(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) mutex_lock(&nh->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = notifier_chain_unregister(&nh->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mutex_unlock(&nh->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) synchronize_srcu(&nh->srcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * srcu_notifier_call_chain - Call functions in an SRCU notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * @nh: Pointer to head of the SRCU notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * @val: Value passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * @v: Pointer passed unmodified to notifier function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * Calls each function in a notifier chain in turn. The functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * run in a process context, so they are allowed to block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * If the return value of the notifier can be and'ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * will return immediately, with the return value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * the notifier function which halted execution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * Otherwise the return value is the return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * of the last notifier function called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) unsigned long val, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) idx = srcu_read_lock(&nh->srcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) srcu_read_unlock(&nh->srcu, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * srcu_init_notifier_head - Initialize an SRCU notifier head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * @nh: Pointer to head of the srcu notifier chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * Unlike other sorts of notifier heads, SRCU notifier heads require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * dynamic initialization. Be sure to call this routine before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * calling any of the other SRCU notifier routines for this head.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * If an SRCU notifier head is deallocated, it must first be cleaned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * up by calling srcu_cleanup_notifier_head(). Otherwise the head's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * per-cpu data (used by the SRCU mechanism) will leak.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) void srcu_init_notifier_head(struct srcu_notifier_head *nh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mutex_init(&nh->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (init_srcu_struct(&nh->srcu) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) nh->head = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #endif /* CONFIG_SRCU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static ATOMIC_NOTIFIER_HEAD(die_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int notrace notify_die(enum die_val val, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct pt_regs *regs, long err, int trap, int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct die_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .regs = regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .str = str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .err = err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .trapnr = trap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .signr = sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) RCU_LOCKDEP_WARN(!rcu_is_watching(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) "notify_die called but RCU thinks we're quiescent");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return atomic_notifier_call_chain(&die_chain, val, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) NOKPROBE_SYMBOL(notify_die);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int register_die_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return atomic_notifier_chain_register(&die_chain, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) EXPORT_SYMBOL_GPL(register_die_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int unregister_die_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return atomic_notifier_chain_unregister(&die_chain, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) EXPORT_SYMBOL_GPL(unregister_die_notifier);