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 : #ifdef CONFIG_TREE_SRCU
77 : struct srcu_usage srcuu;
78 : #endif
79 : struct srcu_struct srcu;
80 : struct notifier_block __rcu *head;
81 : };
82 :
83 : #define ATOMIC_INIT_NOTIFIER_HEAD(name) do { \
84 : spin_lock_init(&(name)->lock); \
85 : (name)->head = NULL; \
86 : } while (0)
87 : #define BLOCKING_INIT_NOTIFIER_HEAD(name) do { \
88 : init_rwsem(&(name)->rwsem); \
89 : (name)->head = NULL; \
90 : } while (0)
91 : #define RAW_INIT_NOTIFIER_HEAD(name) do { \
92 : (name)->head = NULL; \
93 : } while (0)
94 :
95 : /* srcu_notifier_heads must be cleaned up dynamically */
96 : extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
97 : #define srcu_cleanup_notifier_head(name) \
98 : cleanup_srcu_struct(&(name)->srcu);
99 :
100 : #define ATOMIC_NOTIFIER_INIT(name) { \
101 : .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
102 : .head = NULL }
103 : #define BLOCKING_NOTIFIER_INIT(name) { \
104 : .rwsem = __RWSEM_INITIALIZER((name).rwsem), \
105 : .head = NULL }
106 : #define RAW_NOTIFIER_INIT(name) { \
107 : .head = NULL }
108 :
109 : #ifdef CONFIG_TREE_SRCU
110 : #define SRCU_NOTIFIER_INIT(name, pcpu) \
111 : { \
112 : .mutex = __MUTEX_INITIALIZER(name.mutex), \
113 : .head = NULL, \
114 : .srcuu = __SRCU_USAGE_INIT(name.srcuu), \
115 : .srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \
116 : }
117 : #else
118 : #define SRCU_NOTIFIER_INIT(name, pcpu) \
119 : { \
120 : .mutex = __MUTEX_INITIALIZER(name.mutex), \
121 : .head = NULL, \
122 : .srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \
123 : }
124 : #endif
125 :
126 : #define ATOMIC_NOTIFIER_HEAD(name) \
127 : struct atomic_notifier_head name = \
128 : ATOMIC_NOTIFIER_INIT(name)
129 : #define BLOCKING_NOTIFIER_HEAD(name) \
130 : struct blocking_notifier_head name = \
131 : BLOCKING_NOTIFIER_INIT(name)
132 : #define RAW_NOTIFIER_HEAD(name) \
133 : struct raw_notifier_head name = \
134 : RAW_NOTIFIER_INIT(name)
135 :
136 : #ifdef CONFIG_TREE_SRCU
137 : #define _SRCU_NOTIFIER_HEAD(name, mod) \
138 : static DEFINE_PER_CPU(struct srcu_data, name##_head_srcu_data); \
139 : mod struct srcu_notifier_head name = \
140 : SRCU_NOTIFIER_INIT(name, name##_head_srcu_data)
141 :
142 : #else
143 : #define _SRCU_NOTIFIER_HEAD(name, mod) \
144 : mod struct srcu_notifier_head name = \
145 : SRCU_NOTIFIER_INIT(name, name)
146 :
147 : #endif
148 :
149 : #define SRCU_NOTIFIER_HEAD(name) \
150 : _SRCU_NOTIFIER_HEAD(name, /* not static */)
151 :
152 : #define SRCU_NOTIFIER_HEAD_STATIC(name) \
153 : _SRCU_NOTIFIER_HEAD(name, static)
154 :
155 : #ifdef __KERNEL__
156 :
157 : extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
158 : struct notifier_block *nb);
159 : extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
160 : struct notifier_block *nb);
161 : extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
162 : struct notifier_block *nb);
163 : extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
164 : struct notifier_block *nb);
165 :
166 : extern int atomic_notifier_chain_register_unique_prio(
167 : struct atomic_notifier_head *nh, struct notifier_block *nb);
168 : extern int blocking_notifier_chain_register_unique_prio(
169 : struct blocking_notifier_head *nh, struct notifier_block *nb);
170 :
171 : extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
172 : struct notifier_block *nb);
173 : extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
174 : struct notifier_block *nb);
175 : extern int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
176 : struct notifier_block *nb);
177 : extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
178 : struct notifier_block *nb);
179 :
180 : extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
181 : unsigned long val, void *v);
182 : extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
183 : unsigned long val, void *v);
184 : extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
185 : unsigned long val, void *v);
186 : extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
187 : unsigned long val, void *v);
188 :
189 : extern int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
190 : unsigned long val_up, unsigned long val_down, void *v);
191 : extern int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
192 : unsigned long val_up, unsigned long val_down, void *v);
193 :
194 : extern bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh);
195 :
196 : #define NOTIFY_DONE 0x0000 /* Don't care */
197 : #define NOTIFY_OK 0x0001 /* Suits me */
198 : #define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
199 : #define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002)
200 : /* Bad/Veto action */
201 : /*
202 : * Clean way to return from the notifier and stop further calls.
203 : */
204 : #define NOTIFY_STOP (NOTIFY_OK|NOTIFY_STOP_MASK)
205 :
206 : /* Encapsulate (negative) errno value (in particular, NOTIFY_BAD <=> EPERM). */
207 : static inline int notifier_from_errno(int err)
208 : {
209 : if (err)
210 : return NOTIFY_STOP_MASK | (NOTIFY_OK - err);
211 :
212 : return NOTIFY_OK;
213 : }
214 :
215 : /* Restore (negative) errno value from notify return value. */
216 : static inline int notifier_to_errno(int ret)
217 : {
218 0 : ret &= ~NOTIFY_STOP_MASK;
219 0 : return ret > NOTIFY_OK ? NOTIFY_OK - ret : 0;
220 : }
221 :
222 : /*
223 : * Declared notifiers so far. I can imagine quite a few more chains
224 : * over time (eg laptop power reset chains, reboot chain (to clean
225 : * device units up), device [un]mount chain, module load/unload chain,
226 : * low memory chain, screenblank chain (for plug in modular screenblankers)
227 : * VC switch chains (for loadable kernel svgalib VC switch helpers) etc...
228 : */
229 :
230 : /* CPU notfiers are defined in include/linux/cpu.h. */
231 :
232 : /* netdevice notifiers are defined in include/linux/netdevice.h */
233 :
234 : /* reboot notifiers are defined in include/linux/reboot.h. */
235 :
236 : /* Hibernation and suspend events are defined in include/linux/suspend.h. */
237 :
238 : /* Virtual Terminal events are defined in include/linux/vt.h. */
239 :
240 : #define NETLINK_URELEASE 0x0001 /* Unicast netlink socket released */
241 :
242 : /* Console keyboard events.
243 : * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
244 : * KBD_KEYSYM. */
245 : #define KBD_KEYCODE 0x0001 /* Keyboard keycode, called before any other */
246 : #define KBD_UNBOUND_KEYCODE 0x0002 /* Keyboard keycode which is not bound to any other */
247 : #define KBD_UNICODE 0x0003 /* Keyboard unicode */
248 : #define KBD_KEYSYM 0x0004 /* Keyboard keysym */
249 : #define KBD_POST_KEYSYM 0x0005 /* Called after keyboard keysym interpretation */
250 :
251 : extern struct blocking_notifier_head reboot_notifier_list;
252 :
253 : #endif /* __KERNEL__ */
254 : #endif /* _LINUX_NOTIFIER_H */
|