1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #ifndef _SYS_EVENTHANDLER_H_ 30 #define _SYS_EVENTHANDLER_H_ 31 32 #include <sys/_eventhandler.h> 33 #include <sys/lock.h> 34 #include <sys/ktr.h> 35 #include <sys/mutex.h> 36 #include <sys/power.h> 37 #include <sys/queue.h> 38 39 #ifdef VIMAGE 40 struct eventhandler_entry_vimage { 41 void (* func)(void); /* Original function registered. */ 42 void *ee_arg; /* Original argument registered. */ 43 void *sparep[2]; 44 }; 45 #endif 46 47 struct eventhandler_list { 48 char *el_name; 49 int el_flags; /* Unused. */ 50 u_int el_runcount; 51 struct mtx el_lock; 52 TAILQ_ENTRY(eventhandler_list) el_link; 53 TAILQ_HEAD(,eventhandler_entry) el_entries; 54 }; 55 56 #define EHL_LOCK(p) mtx_lock(&(p)->el_lock) 57 #define EHL_UNLOCK(p) mtx_unlock(&(p)->el_lock) 58 #define EHL_LOCK_ASSERT(p, x) mtx_assert(&(p)->el_lock, x) 59 60 /* 61 * Macro to invoke the handlers for a given event. 62 */ 63 #define _EVENTHANDLER_INVOKE(name, list, ...) do { \ 64 struct eventhandler_entry *_ep; \ 65 struct eventhandler_entry_ ## name *_t; \ 66 \ 67 EHL_LOCK_ASSERT((list), MA_OWNED); \ 68 (list)->el_runcount++; \ 69 KASSERT((list)->el_runcount > 0, \ 70 ("eventhandler_invoke: runcount overflow")); \ 71 CTR0(KTR_EVH, "eventhandler_invoke(\"" __STRING(name) "\")"); \ 72 TAILQ_FOREACH(_ep, &((list)->el_entries), ee_link) { \ 73 if (_ep->ee_priority != EHE_DEAD_PRIORITY) { \ 74 EHL_UNLOCK((list)); \ 75 _t = (struct eventhandler_entry_ ## name *)_ep; \ 76 CTR1(KTR_EVH, "eventhandler_invoke: executing %p", \ 77 (void *)_t->eh_func); \ 78 _t->eh_func(_ep->ee_arg , ## __VA_ARGS__); \ 79 EHL_LOCK((list)); \ 80 } \ 81 } \ 82 KASSERT((list)->el_runcount > 0, \ 83 ("eventhandler_invoke: runcount underflow")); \ 84 (list)->el_runcount--; \ 85 if ((list)->el_runcount == 0) \ 86 eventhandler_prune_list(list); \ 87 EHL_UNLOCK((list)); \ 88 } while (0) 89 90 /* 91 * You can optionally use the EVENTHANDLER_LIST and EVENTHANDLER_DIRECT macros 92 * to pre-define a symbol for the eventhandler list. This symbol can be used by 93 * EVENTHANDLER_DIRECT_INVOKE, which has the advantage of not needing to do a 94 * locked search of the global list of eventhandler lists. At least 95 * EVENTHANDLER_LIST_DEFINE must be used for EVENTHANDLER_DIRECT_INVOKE to 96 * work. EVENTHANDLER_LIST_DECLARE is only needed if the call to 97 * EVENTHANDLER_DIRECT_INVOKE is in a different compilation unit from 98 * EVENTHANDLER_LIST_DEFINE. If the events are even relatively high frequency 99 * it is suggested that you directly define a list for them. 100 */ 101 #define EVENTHANDLER_LIST_DEFINE(name) \ 102 struct eventhandler_list *_eventhandler_list_ ## name ; \ 103 static void _ehl_init_ ## name (void * ctx __unused) \ 104 { \ 105 _eventhandler_list_ ## name = eventhandler_create_list(#name); \ 106 } \ 107 SYSINIT(name ## _ehl_init, SI_SUB_EVENTHANDLER, SI_ORDER_ANY, \ 108 _ehl_init_ ## name, NULL); \ 109 struct __hack 110 111 #define EVENTHANDLER_DIRECT_INVOKE(name, ...) do { \ 112 struct eventhandler_list *_el; \ 113 \ 114 _el = _eventhandler_list_ ## name ; \ 115 if (!TAILQ_EMPTY(&_el->el_entries)) { \ 116 EHL_LOCK(_el); \ 117 _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ 118 } \ 119 } while (0) 120 121 #define EVENTHANDLER_DEFINE(name, func, arg, priority) \ 122 static eventhandler_tag name ## _tag; \ 123 static void name ## _evh_init(void *ctx) \ 124 { \ 125 name ## _tag = EVENTHANDLER_REGISTER(name, func, ctx, \ 126 priority); \ 127 } \ 128 SYSINIT(name ## _evh_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, \ 129 name ## _evh_init, arg); \ 130 struct __hack 131 132 #define EVENTHANDLER_INVOKE(name, ...) \ 133 do { \ 134 struct eventhandler_list *_el; \ 135 \ 136 if ((_el = eventhandler_find_list(#name)) != NULL) \ 137 _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ 138 } while (0) 139 140 #define EVENTHANDLER_REGISTER(name, func, arg, priority) \ 141 eventhandler_register(NULL, #name, func, arg, priority) 142 143 #define EVENTHANDLER_DEREGISTER(name, tag) \ 144 do { \ 145 struct eventhandler_list *_el; \ 146 \ 147 if ((_el = eventhandler_find_list(#name)) != NULL) \ 148 eventhandler_deregister(_el, tag); \ 149 } while (0) 150 151 #define EVENTHANDLER_DEREGISTER_NOWAIT(name, tag) \ 152 do { \ 153 struct eventhandler_list *_el; \ 154 \ 155 if ((_el = eventhandler_find_list(#name)) != NULL) \ 156 eventhandler_deregister_nowait(_el, tag); \ 157 } while (0) 158 159 eventhandler_tag eventhandler_register(struct eventhandler_list *list, 160 const char *name, void *func, void *arg, int priority); 161 void eventhandler_deregister(struct eventhandler_list *list, 162 eventhandler_tag tag); 163 void eventhandler_deregister_nowait(struct eventhandler_list *list, 164 eventhandler_tag tag); 165 struct eventhandler_list *eventhandler_find_list(const char *name); 166 void eventhandler_prune_list(struct eventhandler_list *list); 167 struct eventhandler_list *eventhandler_create_list(const char *name); 168 169 #ifdef VIMAGE 170 typedef void (*vimage_iterator_func_t)(void *, ...); 171 172 eventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list, 173 const char *name, void *func, void *arg, int priority, 174 vimage_iterator_func_t); 175 #endif 176 177 /* 178 * Standard system event queues. 179 */ 180 181 /* Generic priority levels */ 182 #define EVENTHANDLER_PRI_FIRST 0 183 #define EVENTHANDLER_PRI_ANY 10000 184 #define EVENTHANDLER_PRI_LAST 20000 185 186 /* 187 * Successive shutdown events invoked by kern_reboot(9). 188 * 189 * Handlers will receive the 'howto' value as their second argument. 190 * 191 * All handlers must be prepared to be executed from a panic/debugger context; 192 * see the man page for details. 193 */ 194 typedef void (*shutdown_fn)(void *, int); 195 196 #define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST 197 #define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY 198 #define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST 199 200 EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ 201 EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ 202 EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); 203 204 /* Power state change events */ 205 typedef void (*power_change_fn)(void *, enum power_stype stype); 206 EVENTHANDLER_DECLARE(power_resume, power_change_fn); 207 EVENTHANDLER_DECLARE(power_suspend, power_change_fn); 208 EVENTHANDLER_DECLARE(power_suspend_early, power_change_fn); 209 210 /* Low memory event */ 211 typedef void (*vm_lowmem_handler_t)(void *, int); 212 #define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST 213 EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); 214 /* Some of mbuf(9) zones reached maximum */ 215 EVENTHANDLER_DECLARE(mbuf_lowmem, vm_lowmem_handler_t); 216 217 /* Root mounted event */ 218 typedef void (*mountroot_handler_t)(void *); 219 EVENTHANDLER_DECLARE(mountroot, mountroot_handler_t); 220 221 /* File system mount events */ 222 struct mount; 223 struct vnode; 224 struct thread; 225 typedef void (*vfs_mounted_notify_fn)(void *, struct mount *, struct vnode *, 226 struct thread *); 227 typedef void (*vfs_unmounted_notify_fn)(void *, struct mount *, 228 struct thread *); 229 EVENTHANDLER_DECLARE(vfs_mounted, vfs_mounted_notify_fn); 230 EVENTHANDLER_DECLARE(vfs_unmounted, vfs_unmounted_notify_fn); 231 232 /* 233 * Process events 234 * process_fork and exit handlers are called without Giant. 235 * exec handlers are called with Giant, but that is by accident. 236 */ 237 struct proc; 238 struct image_params; 239 240 typedef void (*exitlist_fn)(void *, struct proc *); 241 typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int); 242 typedef void (*execlist_fn)(void *, struct proc *, struct image_params *); 243 typedef void (*proc_ctor_fn)(void *, struct proc *); 244 typedef void (*proc_dtor_fn)(void *, struct proc *); 245 typedef void (*proc_init_fn)(void *, struct proc *); 246 typedef void (*proc_fini_fn)(void *, struct proc *); 247 EVENTHANDLER_DECLARE(process_ctor, proc_ctor_fn); 248 EVENTHANDLER_DECLARE(process_dtor, proc_dtor_fn); 249 EVENTHANDLER_DECLARE(process_init, proc_init_fn); 250 EVENTHANDLER_DECLARE(process_fini, proc_fini_fn); 251 EVENTHANDLER_DECLARE(process_exit, exitlist_fn); 252 EVENTHANDLER_DECLARE(process_fork, forklist_fn); 253 EVENTHANDLER_DECLARE(process_exec, execlist_fn); 254 255 /* 256 * application dump event 257 */ 258 typedef void (*app_coredump_start_fn)(void *, struct thread *, char *name); 259 typedef void (*app_coredump_progress_fn)(void *, struct thread *td, int byte_count); 260 typedef void (*app_coredump_finish_fn)(void *, struct thread *td); 261 typedef void (*app_coredump_error_fn)(void *, struct thread *td, char *msg, ...); 262 263 EVENTHANDLER_DECLARE(app_coredump_start, app_coredump_start_fn); 264 EVENTHANDLER_DECLARE(app_coredump_progress, app_coredump_progress_fn); 265 EVENTHANDLER_DECLARE(app_coredump_finish, app_coredump_finish_fn); 266 EVENTHANDLER_DECLARE(app_coredump_error, app_coredump_error_fn); 267 268 typedef void (*thread_ctor_fn)(void *, struct thread *); 269 typedef void (*thread_dtor_fn)(void *, struct thread *); 270 typedef void (*thread_fini_fn)(void *, struct thread *); 271 typedef void (*thread_init_fn)(void *, struct thread *); 272 EVENTHANDLER_DECLARE(thread_ctor, thread_ctor_fn); 273 EVENTHANDLER_DECLARE(thread_dtor, thread_dtor_fn); 274 EVENTHANDLER_DECLARE(thread_init, thread_init_fn); 275 EVENTHANDLER_DECLARE(thread_fini, thread_fini_fn); 276 277 typedef void (*uma_zone_chfn)(void *); 278 EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); 279 EVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn); 280 EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); 281 282 /* Kernel linker file load and unload events */ 283 struct linker_file; 284 typedef void (*kld_load_fn)(void *, struct linker_file *); 285 typedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t); 286 typedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *); 287 EVENTHANDLER_DECLARE(kld_load, kld_load_fn); 288 EVENTHANDLER_DECLARE(kld_unload, kld_unload_fn); 289 EVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn); 290 291 /* Generic graphics framebuffer interface */ 292 struct fb_info; 293 typedef void (*register_framebuffer_fn)(void *, struct fb_info *); 294 typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *); 295 EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn); 296 EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn); 297 298 /* Veto ada attachment */ 299 struct cam_path; 300 struct ata_params; 301 typedef void (*ada_probe_veto_fn)(void *, struct cam_path *, 302 struct ata_params *, int *); 303 EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn); 304 305 /* Swap device events */ 306 struct swdevt; 307 typedef void (*swapon_fn)(void *, struct swdevt *); 308 typedef void (*swapoff_fn)(void *, struct swdevt *); 309 EVENTHANDLER_DECLARE(swapon, swapon_fn); 310 EVENTHANDLER_DECLARE(swapoff, swapoff_fn); 311 312 /* newbus device events */ 313 enum evhdev_detach { 314 EVHDEV_DETACH_BEGIN, /* Before detach() is called */ 315 EVHDEV_DETACH_COMPLETE, /* After detach() returns 0 */ 316 EVHDEV_DETACH_FAILED /* After detach() returns err */ 317 }; 318 typedef void (*device_attach_fn)(void *, device_t); 319 typedef void (*device_detach_fn)(void *, device_t, enum evhdev_detach); 320 typedef void (*device_nomatch_fn)(void *, device_t); 321 EVENTHANDLER_DECLARE(device_attach, device_attach_fn); 322 EVENTHANDLER_DECLARE(device_detach, device_detach_fn); 323 EVENTHANDLER_DECLARE(device_nomatch, device_nomatch_fn); 324 325 /* Interface address addition and removal event */ 326 struct ifaddr; 327 typedef void (*rt_addrmsg_fn)(void *, struct ifaddr *, int); 328 EVENTHANDLER_DECLARE(rt_addrmsg, rt_addrmsg_fn); 329 330 /* Kernel environment variable change event */ 331 typedef void (*env_change_fn)(void *, const char *); 332 EVENTHANDLER_DECLARE(setenv, env_change_fn); 333 EVENTHANDLER_DECLARE(unsetenv, env_change_fn); 334 335 #endif /* _SYS_EVENTHANDLER_H_ */ 336