1 /* $NetBSD: dtrace_unload.c,v 1.4 2010/04/23 16:44:10 ahoka 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: src/sys/cddl/dev/dtrace/dtrace_unload.c,v 1.2.2.1 2009/08/03 08:13:06 kensmith Exp $ 24 * 25 */ 26 27 extern int dtrace_probes_size; 28 extern int dtrace_helptrace_size; 29 30 static int 31 dtrace_unload() 32 { 33 dtrace_state_t *state; 34 int error = 0; 35 36 mutex_enter(&dtrace_provider_lock); 37 mutex_enter(&dtrace_lock); 38 mutex_enter(&cpu_lock); 39 40 ASSERT(dtrace_opens == 0); 41 42 if (dtrace_helpers > 0) { 43 mutex_exit(&cpu_lock); 44 mutex_exit(&dtrace_lock); 45 mutex_exit(&dtrace_provider_lock); 46 return (EBUSY); 47 } 48 49 if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) { 50 mutex_exit(&cpu_lock); 51 mutex_exit(&dtrace_lock); 52 mutex_exit(&dtrace_provider_lock); 53 return (EBUSY); 54 } 55 56 dtrace_provider = NULL; 57 58 if ((state = dtrace_anon_grab()) != NULL) { 59 /* 60 * If there were ECBs on this state, the provider should 61 * have not been allowed to detach; assert that there is 62 * none. 63 */ 64 ASSERT(state->dts_necbs == 0); 65 dtrace_state_destroy(state); 66 } 67 68 bzero(&dtrace_anon, sizeof (dtrace_anon_t)); 69 70 mutex_exit(&cpu_lock); 71 72 if (dtrace_helptrace_enabled) { 73 kmem_free(dtrace_helptrace_buffer, dtrace_helptrace_size); 74 dtrace_helptrace_buffer = NULL; 75 } 76 77 if (dtrace_probes != NULL) { 78 kmem_free(dtrace_probes, dtrace_probes_size); 79 dtrace_probes = NULL; 80 dtrace_nprobes = 0; 81 } 82 83 dtrace_hash_destroy(dtrace_bymod); 84 dtrace_hash_destroy(dtrace_byfunc); 85 dtrace_hash_destroy(dtrace_byname); 86 dtrace_bymod = NULL; 87 dtrace_byfunc = NULL; 88 dtrace_byname = NULL; 89 90 kmem_cache_destroy(dtrace_state_cache); 91 92 vmem_destroy(dtrace_arena); 93 94 if (dtrace_toxrange != NULL) { 95 kmem_free(dtrace_toxrange, sizeof (dtrace_toxrange_t *)); 96 dtrace_toxrange = NULL; 97 dtrace_toxranges = 0; 98 dtrace_toxranges_max = 0; 99 } 100 101 ASSERT(dtrace_vtime_references == 0); 102 ASSERT(dtrace_opens == 0); 103 ASSERT(dtrace_retained == NULL); 104 105 mutex_exit(&dtrace_lock); 106 mutex_exit(&dtrace_provider_lock); 107 108 mutex_destroy(&dtrace_meta_lock); 109 mutex_destroy(&dtrace_provider_lock); 110 mutex_destroy(&dtrace_lock); 111 mutex_destroy(&dtrace_errlock); 112 113 /* XXX Hack */ 114 mutex_destroy(&mod_lock); 115 116 /* Reset our hook for exceptions. */ 117 dtrace_invop_uninit(); 118 119 /* 120 * Reset our hook for thread switches, but ensure that vtime isn't 121 * active first. 122 */ 123 dtrace_vtime_active = 0; 124 dtrace_vtime_switch_func = NULL; 125 126 /* Unhook from the trap handler. */ 127 dtrace_trap_func = NULL; 128 129 return (error); 130 } 131