1 /* $NetBSD: dtrace_unload.c,v 1.7 2018/05/28 21:05:03 chs Exp $ */ 2 3 /* 4 * CDDL HEADER START 5 * 6 * The contents of this file are subject to the terms of the 7 * Common Development and Distribution License (the "License"). 8 * You may not use this file except in compliance with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 * 23 * $FreeBSD: head/sys/cddl/dev/dtrace/dtrace_unload.c 278166 2015-02-03 19:39:53Z pfg $ 24 * 25 */ 26 27 static int 28 dtrace_unload() 29 { 30 dtrace_state_t *state; 31 int error = 0; 32 33 #ifdef __FreeBSD__ 34 destroy_dev(dtrace_dev); 35 destroy_dev(helper_dev); 36 #endif 37 38 #ifdef __NetBSD__ 39 module_unregister_callbacks(dtrace_modcb); 40 #endif 41 42 mutex_enter(&dtrace_provider_lock); 43 mutex_enter(&dtrace_lock); 44 mutex_enter(&cpu_lock); 45 46 if (dtrace_opens > 0 || dtrace_helpers > 0) { 47 mutex_exit(&cpu_lock); 48 mutex_exit(&dtrace_lock); 49 mutex_exit(&dtrace_provider_lock); 50 return (EBUSY); 51 } 52 53 if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) { 54 mutex_exit(&cpu_lock); 55 mutex_exit(&dtrace_lock); 56 mutex_exit(&dtrace_provider_lock); 57 return (EBUSY); 58 } 59 60 dtrace_provider = NULL; 61 #ifdef __FreeBSD__ 62 EVENTHANDLER_DEREGISTER(kld_load, dtrace_kld_load_tag); 63 EVENTHANDLER_DEREGISTER(kld_unload_try, dtrace_kld_unload_try_tag); 64 #endif 65 66 if ((state = dtrace_anon_grab()) != NULL) { 67 /* 68 * If there were ECBs on this state, the provider should 69 * have not been allowed to detach; assert that there is 70 * none. 71 */ 72 ASSERT(state->dts_necbs == 0); 73 dtrace_state_destroy(state); 74 } 75 76 bzero(&dtrace_anon, sizeof (dtrace_anon_t)); 77 78 mutex_exit(&cpu_lock); 79 80 if (dtrace_probes != NULL) { 81 kmem_free(dtrace_probes, dtrace_nprobes * sizeof (dtrace_probe_t *)); 82 dtrace_probes = NULL; 83 dtrace_nprobes = 0; 84 } 85 86 dtrace_hash_destroy(dtrace_bymod); 87 dtrace_hash_destroy(dtrace_byfunc); 88 dtrace_hash_destroy(dtrace_byname); 89 dtrace_bymod = NULL; 90 dtrace_byfunc = NULL; 91 dtrace_byname = NULL; 92 93 kmem_cache_destroy(dtrace_state_cache); 94 95 #ifdef __FreeBSD__ 96 delete_unrhdr(dtrace_arena); 97 #endif 98 #ifdef __NetBSD__ 99 vmem_destroy(dtrace_arena); 100 #endif 101 102 if (dtrace_toxrange != NULL) { 103 kmem_free(dtrace_toxrange, 104 dtrace_toxranges_max * sizeof (dtrace_toxrange_t)); 105 dtrace_toxrange = NULL; 106 dtrace_toxranges = 0; 107 dtrace_toxranges_max = 0; 108 } 109 110 ASSERT(dtrace_vtime_references == 0); 111 ASSERT(dtrace_opens == 0); 112 ASSERT(dtrace_retained == NULL); 113 114 mutex_exit(&dtrace_lock); 115 mutex_exit(&dtrace_provider_lock); 116 117 mutex_destroy(&dtrace_meta_lock); 118 mutex_destroy(&dtrace_provider_lock); 119 mutex_destroy(&dtrace_lock); 120 #ifdef DEBUG 121 mutex_destroy(&dtrace_errlock); 122 #endif 123 124 #ifdef __FreeBSD__ 125 taskq_destroy(dtrace_taskq); 126 #endif 127 128 /* Reset our hook for exceptions. */ 129 dtrace_invop_uninit(); 130 131 /* 132 * Reset our hook for thread switches, but ensure that vtime isn't 133 * active first. 134 */ 135 dtrace_vtime_active = 0; 136 dtrace_vtime_switch_func = NULL; 137 138 /* Unhook from the trap handler. */ 139 dtrace_trap_func = NULL; 140 141 return (error); 142 } 143