1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * $FreeBSD$ 29 */ 30 31 #ifndef _SYS_EVENTHANDLER_H_ 32 #define _SYS_EVENTHANDLER_H_ 33 34 #include <sys/_eventhandler.h> 35 #include <sys/lock.h> 36 #include <sys/ktr.h> 37 #include <sys/mutex.h> 38 #include <sys/queue.h> 39 40 #ifdef VIMAGE 41 struct eventhandler_entry_vimage { 42 void (* func)(void); /* Original function registered. */ 43 void *ee_arg; /* Original argument registered. */ 44 void *sparep[2]; 45 }; 46 #endif 47 48 struct eventhandler_list { 49 char *el_name; 50 int el_flags; /* Unused. */ 51 u_int el_runcount; 52 struct mtx el_lock; 53 TAILQ_ENTRY(eventhandler_list) el_link; 54 TAILQ_HEAD(,eventhandler_entry) el_entries; 55 }; 56 57 #define EHL_LOCK(p) mtx_lock(&(p)->el_lock) 58 #define EHL_UNLOCK(p) mtx_unlock(&(p)->el_lock) 59 #define EHL_LOCK_ASSERT(p, x) mtx_assert(&(p)->el_lock, x) 60 61 /* 62 * Macro to invoke the handlers for a given event. 63 */ 64 #define _EVENTHANDLER_INVOKE(name, list, ...) do { \ 65 struct eventhandler_entry *_ep; \ 66 struct eventhandler_entry_ ## name *_t; \ 67 \ 68 EHL_LOCK_ASSERT((list), MA_OWNED); \ 69 (list)->el_runcount++; \ 70 KASSERT((list)->el_runcount > 0, \ 71 ("eventhandler_invoke: runcount overflow")); \ 72 CTR0(KTR_EVH, "eventhandler_invoke(\"" __STRING(name) "\")"); \ 73 TAILQ_FOREACH(_ep, &((list)->el_entries), ee_link) { \ 74 if (_ep->ee_priority != EHE_DEAD_PRIORITY) { \ 75 EHL_UNLOCK((list)); \ 76 _t = (struct eventhandler_entry_ ## name *)_ep; \ 77 CTR1(KTR_EVH, "eventhandler_invoke: executing %p", \ 78 (void *)_t->eh_func); \ 79 _t->eh_func(_ep->ee_arg , ## __VA_ARGS__); \ 80 EHL_LOCK((list)); \ 81 } \ 82 } \ 83 KASSERT((list)->el_runcount > 0, \ 84 ("eventhandler_invoke: runcount underflow")); \ 85 (list)->el_runcount--; \ 86 if ((list)->el_runcount == 0) \ 87 eventhandler_prune_list(list); \ 88 EHL_UNLOCK((list)); \ 89 } while (0) 90 91 /* 92 * You can optionally use the EVENTHANDLER_LIST and EVENTHANDLER_DIRECT macros 93 * to pre-define a symbol for the eventhandler list. This symbol can be used by 94 * EVENTHANDLER_DIRECT_INVOKE, which has the advantage of not needing to do a 95 * locked search of the global list of eventhandler lists. At least 96 * EVENTHANDLER_LIST_DEFINE must be used for EVENTHANDLER_DIRECT_INVOKE to 97 * work. EVENTHANDLER_LIST_DECLARE is only needed if the call to 98 * EVENTHANDLER_DIRECT_INVOKE is in a different compilation unit from 99 * EVENTHANDLER_LIST_DEFINE. If the events are even relatively high frequency 100 * it is suggested that you directly define a list for them. 101 */ 102 #define EVENTHANDLER_LIST_DEFINE(name) \ 103 struct eventhandler_list *_eventhandler_list_ ## name ; \ 104 static void _ehl_init_ ## name (void * ctx __unused) \ 105 { \ 106 _eventhandler_list_ ## name = eventhandler_create_list(#name); \ 107 } \ 108 SYSINIT(name ## _ehl_init, SI_SUB_EVENTHANDLER, SI_ORDER_ANY, \ 109 _ehl_init_ ## name, NULL); \ 110 struct __hack 111 112 #define EVENTHANDLER_DIRECT_INVOKE(name, ...) do { \ 113 struct eventhandler_list *_el; \ 114 \ 115 _el = _eventhandler_list_ ## name ; \ 116 if (!TAILQ_EMPTY(&_el->el_entries)) { \ 117 EHL_LOCK(_el); \ 118 _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ 119 } \ 120 } while (0) 121 122 #define EVENTHANDLER_DEFINE(name, func, arg, priority) \ 123 static eventhandler_tag name ## _tag; \ 124 static void name ## _evh_init(void *ctx) \ 125 { \ 126 name ## _tag = EVENTHANDLER_REGISTER(name, func, ctx, \ 127 priority); \ 128 } \ 129 SYSINIT(name ## _evh_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, \ 130 name ## _evh_init, arg); \ 131 struct __hack 132 133 #define EVENTHANDLER_INVOKE(name, ...) \ 134 do { \ 135 struct eventhandler_list *_el; \ 136 \ 137 if ((_el = eventhandler_find_list(#name)) != NULL) \ 138 _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ 139 } while (0) 140 141 #define EVENTHANDLER_REGISTER(name, func, arg, priority) \ 142 eventhandler_register(NULL, #name, func, arg, priority) 143 144 #define EVENTHANDLER_DEREGISTER(name, tag) \ 145 do { \ 146 struct eventhandler_list *_el; \ 147 \ 148 if ((_el = eventhandler_find_list(#name)) != NULL) \ 149 eventhandler_deregister(_el, tag); \ 150 } while (0) 151 152 #define EVENTHANDLER_DEREGISTER_NOWAIT(name, tag) \ 153 do { \ 154 struct eventhandler_list *_el; \ 155 \ 156 if ((_el = eventhandler_find_list(#name)) != NULL) \ 157 eventhandler_deregister_nowait(_el, tag); \ 158 } while (0) 159 160 eventhandler_tag eventhandler_register(struct eventhandler_list *list, 161 const char *name, void *func, void *arg, int priority); 162 void eventhandler_deregister(struct eventhandler_list *list, 163 eventhandler_tag tag); 164 void eventhandler_deregister_nowait(struct eventhandler_list *list, 165 eventhandler_tag tag); 166 struct eventhandler_list *eventhandler_find_list(const char *name); 167 void eventhandler_prune_list(struct eventhandler_list *list); 168 struct eventhandler_list *eventhandler_create_list(const char *name); 169 170 #ifdef VIMAGE 171 typedef void (*vimage_iterator_func_t)(void *, ...); 172 173 eventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list, 174 const char *name, void *func, void *arg, int priority, 175 vimage_iterator_func_t); 176 #endif 177 178 /* 179 * Standard system event queues. 180 */ 181 182 /* Generic priority levels */ 183 #define EVENTHANDLER_PRI_FIRST 0 184 #define EVENTHANDLER_PRI_ANY 10000 185 #define EVENTHANDLER_PRI_LAST 20000 186 187 /* Shutdown events */ 188 typedef void (*shutdown_fn)(void *, int); 189 190 #define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST 191 #define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY 192 #define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST 193 194 EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ 195 EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ 196 EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); 197 198 /* Power state change events */ 199 typedef void (*power_change_fn)(void *); 200 EVENTHANDLER_DECLARE(power_resume, power_change_fn); 201 EVENTHANDLER_DECLARE(power_suspend, power_change_fn); 202 EVENTHANDLER_DECLARE(power_suspend_early, power_change_fn); 203 204 /* Low memory event */ 205 typedef void (*vm_lowmem_handler_t)(void *, int); 206 #define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST 207 EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); 208 /* Some of mbuf(9) zones reached maximum */ 209 EVENTHANDLER_DECLARE(mbuf_lowmem, vm_lowmem_handler_t); 210 211 /* Root mounted event */ 212 typedef void (*mountroot_handler_t)(void *); 213 EVENTHANDLER_DECLARE(mountroot, mountroot_handler_t); 214 215 /* File system mount events */ 216 struct mount; 217 struct vnode; 218 struct thread; 219 typedef void (*vfs_mounted_notify_fn)(void *, struct mount *, struct vnode *, 220 struct thread *); 221 typedef void (*vfs_unmounted_notify_fn)(void *, struct mount *, 222 struct thread *); 223 EVENTHANDLER_DECLARE(vfs_mounted, vfs_mounted_notify_fn); 224 EVENTHANDLER_DECLARE(vfs_unmounted, vfs_unmounted_notify_fn); 225 226 /* 227 * Process events 228 * process_fork and exit handlers are called without Giant. 229 * exec handlers are called with Giant, but that is by accident. 230 */ 231 struct proc; 232 struct image_params; 233 234 typedef void (*exitlist_fn)(void *, struct proc *); 235 typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int); 236 typedef void (*execlist_fn)(void *, struct proc *, struct image_params *); 237 typedef void (*proc_ctor_fn)(void *, struct proc *); 238 typedef void (*proc_dtor_fn)(void *, struct proc *); 239 typedef void (*proc_init_fn)(void *, struct proc *); 240 typedef void (*proc_fini_fn)(void *, struct proc *); 241 EVENTHANDLER_DECLARE(process_ctor, proc_ctor_fn); 242 EVENTHANDLER_DECLARE(process_dtor, proc_dtor_fn); 243 EVENTHANDLER_DECLARE(process_init, proc_init_fn); 244 EVENTHANDLER_DECLARE(process_fini, proc_fini_fn); 245 EVENTHANDLER_DECLARE(process_exit, exitlist_fn); 246 EVENTHANDLER_DECLARE(process_fork, forklist_fn); 247 EVENTHANDLER_DECLARE(process_exec, execlist_fn); 248 249 /* 250 * application dump event 251 */ 252 typedef void (*app_coredump_start_fn)(void *, struct thread *, char *name); 253 typedef void (*app_coredump_progress_fn)(void *, struct thread *td, int byte_count); 254 typedef void (*app_coredump_finish_fn)(void *, struct thread *td); 255 typedef void (*app_coredump_error_fn)(void *, struct thread *td, char *msg, ...); 256 257 EVENTHANDLER_DECLARE(app_coredump_start, app_coredump_start_fn); 258 EVENTHANDLER_DECLARE(app_coredump_progress, app_coredump_progress_fn); 259 EVENTHANDLER_DECLARE(app_coredump_finish, app_coredump_finish_fn); 260 EVENTHANDLER_DECLARE(app_coredump_error, app_coredump_error_fn); 261 262 typedef void (*thread_ctor_fn)(void *, struct thread *); 263 typedef void (*thread_dtor_fn)(void *, struct thread *); 264 typedef void (*thread_fini_fn)(void *, struct thread *); 265 typedef void (*thread_init_fn)(void *, struct thread *); 266 EVENTHANDLER_DECLARE(thread_ctor, thread_ctor_fn); 267 EVENTHANDLER_DECLARE(thread_dtor, thread_dtor_fn); 268 EVENTHANDLER_DECLARE(thread_init, thread_init_fn); 269 EVENTHANDLER_DECLARE(thread_fini, thread_fini_fn); 270 271 typedef void (*uma_zone_chfn)(void *); 272 EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); 273 EVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn); 274 EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); 275 276 /* Kernel linker file load and unload events */ 277 struct linker_file; 278 typedef void (*kld_load_fn)(void *, struct linker_file *); 279 typedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t); 280 typedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *); 281 EVENTHANDLER_DECLARE(kld_load, kld_load_fn); 282 EVENTHANDLER_DECLARE(kld_unload, kld_unload_fn); 283 EVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn); 284 285 /* Generic graphics framebuffer interface */ 286 struct fb_info; 287 typedef void (*register_framebuffer_fn)(void *, struct fb_info *); 288 typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *); 289 EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn); 290 EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn); 291 292 /* Veto ada attachment */ 293 struct cam_path; 294 struct ata_params; 295 typedef void (*ada_probe_veto_fn)(void *, struct cam_path *, 296 struct ata_params *, int *); 297 EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn); 298 299 /* Swap device events */ 300 struct swdevt; 301 typedef void (*swapon_fn)(void *, struct swdevt *); 302 typedef void (*swapoff_fn)(void *, struct swdevt *); 303 EVENTHANDLER_DECLARE(swapon, swapon_fn); 304 EVENTHANDLER_DECLARE(swapoff, swapoff_fn); 305 306 /* newbus device events */ 307 enum evhdev_detach { 308 EVHDEV_DETACH_BEGIN, /* Before detach() is called */ 309 EVHDEV_DETACH_COMPLETE, /* After detach() returns 0 */ 310 EVHDEV_DETACH_FAILED /* After detach() returns err */ 311 }; 312 typedef void (*device_attach_fn)(void *, device_t); 313 typedef void (*device_detach_fn)(void *, device_t, enum evhdev_detach); 314 typedef void (*device_nomatch_fn)(void *, device_t); 315 EVENTHANDLER_DECLARE(device_attach, device_attach_fn); 316 EVENTHANDLER_DECLARE(device_detach, device_detach_fn); 317 EVENTHANDLER_DECLARE(device_nomatch, device_nomatch_fn); 318 319 /* Interface address addition and removal event */ 320 struct ifaddr; 321 typedef void (*rt_addrmsg_fn)(void *, struct ifaddr *, int); 322 EVENTHANDLER_DECLARE(rt_addrmsg, rt_addrmsg_fn); 323 324 #endif /* _SYS_EVENTHANDLER_H_ */ 325