Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */
2 : /*
3 : * Routines to manage notifier chains for passing status changes to any
4 : * interested routines. We need this instead of hard coded call lists so
5 : * that modules can poke their nose into the innards. The network devices
6 : * needed them so here they are for the rest of you.
7 : *
8 : * Alan Cox <Alan.Cox@linux.org>
9 : */
10 :
11 : #ifndef _LINUX_NOTIFIER_H
12 : #define _LINUX_NOTIFIER_H
13 : #include <linux/errno.h>
14 : #include <linux/mutex.h>
15 : #include <linux/rwsem.h>
16 : #include <linux/srcu.h>
17 :
18 : /*
19 : * Notifier chains are of four types:
20 : *
21 : * Atomic notifier chains: Chain callbacks run in interrupt/atomic
22 : * context. Callouts are not allowed to block.
23 : * Blocking notifier chains: Chain callbacks run in process context.
24 : * Callouts are allowed to block.
25 : * Raw notifier chains: There are no restrictions on callbacks,
26 : * registration, or unregistration. All locking and protection
27 : * must be provided by the caller.
28 : * SRCU notifier chains: A variant of blocking notifier chains, with
29 : * the same restrictions.
30 : *
31 : * atomic_notifier_chain_register() may be called from an atomic context,
32 : * but blocking_notifier_chain_register() and srcu_notifier_chain_register()
33 : * must be called from a process context. Ditto for the corresponding
34 : * _unregister() routines.
35 : *
36 : * atomic_notifier_chain_unregister(), blocking_notifier_chain_unregister(),
37 : * and srcu_notifier_chain_unregister() _must not_ be called from within
38 : * the call chain.
39 : *
40 : * SRCU notifier chains are an alternative form of blocking notifier chains.
41 : * They use SRCU (Sleepable Read-Copy Update) instead of rw-semaphores for
42 : * protection of the chain links. This means there is _very_ low overhead
43 : * in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
44 : * As compensation, srcu_notifier_chain_unregister() is rather expensive.
45 : * SRCU notifier chains should be used when the chain will be called very
46 : * often but notifier_blocks will seldom be removed.
47 : */
48 :
49 : struct notifier_block;
50 :
51 : typedef int (*notifier_fn_t)(struct notifier_block *nb,
52 : unsigned long action, void *data);
53 :
54 : struct notifier_block {
55 : notifier_fn_t notifier_call;
56 : struct notifier_block __rcu *next;
57 : int priority;
58 : };
59 :
60 : struct atomic_notifier_head {
61 : spinlock_t lock;
62 : struct notifier_block __rcu *head;
63 : };
64 :
65 : struct blocking_notifier_head {
66 : struct rw_semaphore rwsem;
67 : struct notifier_block __rcu *head;
68 : };
69 :
70 : struct raw_notifier_head {
71 : struct notifier_block __rcu *head;
72 : };
73 :
74 : struct srcu_notifier_head {
75 : struct mutex mutex;
76 : struct srcu_struct srcu;
77 : struct notifier_block __rcu *head;
78 : };
79 :
80 : #define ATOMIC_INIT_NOTIFIER_HEAD(name) do { \
81 : spin_lock_init(&(name)->lock); \
82 : (name)->head = NULL; \
83 : } while (0)
84 : #define BLOCKING_INIT_NOTIFIER_HEAD(name) do { \
85 : init_rwsem(&(name)->rwsem); \
86 : (name)->head = NULL; \
87 : } while (0)
88 : #define RAW_INIT_NOTIFIER_HEAD(name) do { \
89 : (name)->head = NULL; \
90 : } while (0)
91 :
92 : /* srcu_notifier_heads must be cleaned up dynamically */
93 : extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
94 : #define srcu_cleanup_notifier_head(name) \
95 : cleanup_srcu_struct(&(name)->srcu);
96 :
97 : #define ATOMIC_NOTIFIER_INIT(name) { \
98 : .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
99 : .head = NULL }
100 : #define BLOCKING_NOTIFIER_INIT(name) { \
101 : .rwsem = __RWSEM_INITIALIZER((name).rwsem), \
102 : .head = NULL }
103 : #define RAW_NOTIFIER_INIT(name) { \
104 : .head = NULL }
105 :
106 : #define SRCU_NOTIFIER_INIT(name, pcpu) \
107 : { \
108 : .mutex = __MUTEX_INITIALIZER(name.mutex), \
109 : .head = NULL, \
110 : .srcu = __SRCU_STRUCT_INIT(name.srcu, pcpu), \
111 : }
112 :
113 : #define ATOMIC_NOTIFIER_HEAD(name) \
114 : struct atomic_notifier_head name = \
115 : ATOMIC_NOTIFIER_INIT(name)
116 : #define BLOCKING_NOTIFIER_HEAD(name) \
117 : struct blocking_notifier_head name = \
118 : BLOCKING_NOTIFIER_INIT(name)
119 : #define RAW_NOTIFIER_HEAD(name) \
120 : struct raw_notifier_head name = \
121 : RAW_NOTIFIER_INIT(name)
122 :
123 : #ifdef CONFIG_TREE_SRCU
124 : #define _SRCU_NOTIFIER_HEAD(name, mod) \
125 : static DEFINE_PER_CPU(struct srcu_data, name##_head_srcu_data); \
126 : mod struct srcu_notifier_head name = \
127 : SRCU_NOTIFIER_INIT(name, name##_head_srcu_data)
128 :
129 : #else
130 : #define _SRCU_NOTIFIER_HEAD(name, mod) \
131 : mod struct srcu_notifier_head name = \
132 : SRCU_NOTIFIER_INIT(name, name)
133 :
134 : #endif
135 :
136 : #define SRCU_NOTIFIER_HEAD(name) \
137 : _SRCU_NOTIFIER_HEAD(name, /* not static */)
138 :
139 : #define SRCU_NOTIFIER_HEAD_STATIC(name) \
140 : _SRCU_NOTIFIER_HEAD(name, static)
141 :
142 : #ifdef __KERNEL__
143 :
144 : extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
145 : struct notifier_block *nb);
146 : extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
147 : struct notifier_block *nb);
148 : extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
149 : struct notifier_block *nb);
150 : extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
151 : struct notifier_block *nb);
152 :
153 : extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
154 : struct notifier_block *nb);
155 : extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
156 : struct notifier_block *nb);
157 : extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
158 : struct notifier_block *nb);
159 : extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
160 : struct notifier_block *nb);
161 :
162 : extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
163 : unsigned long val, void *v);
164 : extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
165 : unsigned long val, void *v);
166 : extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
167 : unsigned long val, void *v);
168 : extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
169 : unsigned long val, void *v);
170 :
171 : extern int atomic_notifier_call_chain_robust(struct atomic_notifier_head *nh,
172 : unsigned long val_up, unsigned long val_down, void *v);
173 : extern int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
174 : unsigned long val_up, unsigned long val_down, void *v);
175 : extern int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
176 : unsigned long val_up, unsigned long val_down, void *v);
177 :
178 : #define NOTIFY_DONE 0x0000 /* Don't care */
179 : #define NOTIFY_OK 0x0001 /* Suits me */
180 : #define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
181 : #define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002)
182 : /* Bad/Veto action */
183 : /*
184 : * Clean way to return from the notifier and stop further calls.
185 : */
186 : #define NOTIFY_STOP (NOTIFY_OK|NOTIFY_STOP_MASK)
187 :
188 : /* Encapsulate (negative) errno value (in particular, NOTIFY_BAD <=> EPERM). */
189 0 : static inline int notifier_from_errno(int err)
190 : {
191 0 : if (err)
192 0 : return NOTIFY_STOP_MASK | (NOTIFY_OK - err);
193 :
194 : return NOTIFY_OK;
195 : }
196 :
197 : /* Restore (negative) errno value from notify return value. */
198 26 : static inline int notifier_to_errno(int ret)
199 : {
200 26 : ret &= ~NOTIFY_STOP_MASK;
201 26 : return ret > NOTIFY_OK ? NOTIFY_OK - ret : 0;
202 : }
203 :
204 : /*
205 : * Declared notifiers so far. I can imagine quite a few more chains
206 : * over time (eg laptop power reset chains, reboot chain (to clean
207 : * device units up), device [un]mount chain, module load/unload chain,
208 : * low memory chain, screenblank chain (for plug in modular screenblankers)
209 : * VC switch chains (for loadable kernel svgalib VC switch helpers) etc...
210 : */
211 :
212 : /* CPU notfiers are defined in include/linux/cpu.h. */
213 :
214 : /* netdevice notifiers are defined in include/linux/netdevice.h */
215 :
216 : /* reboot notifiers are defined in include/linux/reboot.h. */
217 :
218 : /* Hibernation and suspend events are defined in include/linux/suspend.h. */
219 :
220 : /* Virtual Terminal events are defined in include/linux/vt.h. */
221 :
222 : #define NETLINK_URELEASE 0x0001 /* Unicast netlink socket released */
223 :
224 : /* Console keyboard events.
225 : * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
226 : * KBD_KEYSYM. */
227 : #define KBD_KEYCODE 0x0001 /* Keyboard keycode, called before any other */
228 : #define KBD_UNBOUND_KEYCODE 0x0002 /* Keyboard keycode which is not bound to any other */
229 : #define KBD_UNICODE 0x0003 /* Keyboard unicode */
230 : #define KBD_KEYSYM 0x0004 /* Keyboard keysym */
231 : #define KBD_POST_KEYSYM 0x0005 /* Called after keyboard keysym interpretation */
232 :
233 : extern struct blocking_notifier_head reboot_notifier_list;
234 :
235 : #endif /* __KERNEL__ */
236 : #endif /* _LINUX_NOTIFIER_H */
|