1179237Sjb/* 2179237Sjb * CDDL HEADER START 3179237Sjb * 4179237Sjb * The contents of this file are subject to the terms of the 5179237Sjb * Common Development and Distribution License (the "License"). 6179237Sjb * You may not use this file except in compliance with the License. 7179237Sjb * 8179237Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9179237Sjb * or http://www.opensolaris.org/os/licensing. 10179237Sjb * See the License for the specific language governing permissions 11179237Sjb * and limitations under the License. 12179237Sjb * 13179237Sjb * When distributing Covered Code, include this CDDL HEADER in each 14179237Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15179237Sjb * If applicable, add the following below this CDDL HEADER, with the 16179237Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17179237Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18179237Sjb * 19179237Sjb * CDDL HEADER END 20179237Sjb * 21179237Sjb * $FreeBSD$ 22179237Sjb * 23179237Sjb */ 24179237Sjb 25179237Sjbstatic int 26179237Sjbdtrace_unload() 27179237Sjb{ 28179237Sjb dtrace_state_t *state; 29179237Sjb int error = 0; 30179237Sjb 31184698Srodrigc destroy_dev(dtrace_dev); 32211611Srpaulo destroy_dev(helper_dev); 33179237Sjb 34179237Sjb mutex_enter(&dtrace_provider_lock); 35179237Sjb mutex_enter(&dtrace_lock); 36179237Sjb mutex_enter(&cpu_lock); 37179237Sjb 38179237Sjb ASSERT(dtrace_opens == 0); 39179237Sjb 40179237Sjb if (dtrace_helpers > 0) { 41179237Sjb mutex_exit(&cpu_lock); 42179237Sjb mutex_exit(&dtrace_lock); 43179237Sjb mutex_exit(&dtrace_provider_lock); 44179237Sjb return (EBUSY); 45179237Sjb } 46179237Sjb 47179237Sjb if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) { 48179237Sjb mutex_exit(&cpu_lock); 49179237Sjb mutex_exit(&dtrace_lock); 50179237Sjb mutex_exit(&dtrace_provider_lock); 51179237Sjb return (EBUSY); 52179237Sjb } 53179237Sjb 54179237Sjb dtrace_provider = NULL; 55254309Smarkj EVENTHANDLER_DEREGISTER(kld_load, dtrace_kld_load_tag); 56254813Smarkj EVENTHANDLER_DEREGISTER(kld_unload_try, dtrace_kld_unload_try_tag); 57179237Sjb 58179237Sjb if ((state = dtrace_anon_grab()) != NULL) { 59179237Sjb /* 60179237Sjb * If there were ECBs on this state, the provider should 61179237Sjb * have not been allowed to detach; assert that there is 62179237Sjb * none. 63179237Sjb */ 64179237Sjb ASSERT(state->dts_necbs == 0); 65179237Sjb dtrace_state_destroy(state); 66179237Sjb } 67179237Sjb 68179237Sjb bzero(&dtrace_anon, sizeof (dtrace_anon_t)); 69179237Sjb 70179237Sjb mutex_exit(&cpu_lock); 71179237Sjb 72179237Sjb if (dtrace_probes != NULL) { 73179237Sjb kmem_free(dtrace_probes, 0); 74179237Sjb dtrace_probes = NULL; 75179237Sjb dtrace_nprobes = 0; 76179237Sjb } 77179237Sjb 78179237Sjb dtrace_hash_destroy(dtrace_bymod); 79179237Sjb dtrace_hash_destroy(dtrace_byfunc); 80179237Sjb dtrace_hash_destroy(dtrace_byname); 81179237Sjb dtrace_bymod = NULL; 82179237Sjb dtrace_byfunc = NULL; 83179237Sjb dtrace_byname = NULL; 84179237Sjb 85179237Sjb kmem_cache_destroy(dtrace_state_cache); 86179237Sjb 87260131Smarkj delete_unrhdr(dtrace_arena); 88179237Sjb 89179237Sjb if (dtrace_toxrange != NULL) { 90179237Sjb kmem_free(dtrace_toxrange, 0); 91179237Sjb dtrace_toxrange = NULL; 92179237Sjb dtrace_toxranges = 0; 93179237Sjb dtrace_toxranges_max = 0; 94179237Sjb } 95179237Sjb 96179237Sjb ASSERT(dtrace_vtime_references == 0); 97179237Sjb ASSERT(dtrace_opens == 0); 98179237Sjb ASSERT(dtrace_retained == NULL); 99179237Sjb 100179237Sjb mutex_exit(&dtrace_lock); 101179237Sjb mutex_exit(&dtrace_provider_lock); 102179237Sjb 103179237Sjb mutex_destroy(&dtrace_meta_lock); 104179237Sjb mutex_destroy(&dtrace_provider_lock); 105179237Sjb mutex_destroy(&dtrace_lock); 106253996Savg#ifdef DEBUG 107179237Sjb mutex_destroy(&dtrace_errlock); 108253996Savg#endif 109179237Sjb 110256148Smarkj taskq_destroy(dtrace_taskq); 111256148Smarkj 112179237Sjb /* Reset our hook for exceptions. */ 113179237Sjb dtrace_invop_uninit(); 114179237Sjb 115179237Sjb /* 116179237Sjb * Reset our hook for thread switches, but ensure that vtime isn't 117179237Sjb * active first. 118179237Sjb */ 119179237Sjb dtrace_vtime_active = 0; 120179237Sjb dtrace_vtime_switch_func = NULL; 121179237Sjb 122179237Sjb /* Unhook from the trap handler. */ 123179237Sjb dtrace_trap_func = NULL; 124179237Sjb 125179237Sjb return (error); 126179237Sjb} 127