dtrace_unload.c revision 262052
140617Smsmith/* 240617Smsmith * CDDL HEADER START 340617Smsmith * 440617Smsmith * The contents of this file are subject to the terms of the 540617Smsmith * Common Development and Distribution License (the "License"). 640617Smsmith * You may not use this file except in compliance with the License. 740617Smsmith * 840617Smsmith * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 940617Smsmith * or http://www.opensolaris.org/os/licensing. 1040617Smsmith * See the License for the specific language governing permissions 1140617Smsmith * and limitations under the License. 1240617Smsmith * 1340617Smsmith * When distributing Covered Code, include this CDDL HEADER in each 1440617Smsmith * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1540617Smsmith * If applicable, add the following below this CDDL HEADER, with the 1640617Smsmith * fields enclosed by brackets "[]" replaced with your own identifying 1740617Smsmith * information: Portions Copyright [yyyy] [name of copyright owner] 1840617Smsmith * 1940617Smsmith * CDDL HEADER END 2040617Smsmith * 2140617Smsmith * $FreeBSD: stable/9/sys/cddl/dev/dtrace/dtrace_unload.c 262052 2014-02-17 13:29:48Z avg $ 2240617Smsmith * 2340617Smsmith */ 2440617Smsmith 2540617Smsmithstatic int 2640617Smsmithdtrace_unload() 27119482Sobrien{ 28119482Sobrien dtrace_state_t *state; 29119482Sobrien int error = 0; 3040617Smsmith 3140617Smsmith#if __FreeBSD_version < 800039 3240617Smsmith /* 3340617Smsmith * Check if there is still an event handler callback 3440617Smsmith * registered. 3540617Smsmith */ 3640617Smsmith if (eh_tag != 0) { 3740617Smsmith /* De-register the device cloning event handler. */ 3840617Smsmith EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); 39162814Sru eh_tag = 0; 4040617Smsmith 4140617Smsmith /* Stop device cloning. */ 4240617Smsmith clone_cleanup(&dtrace_clones); 4340617Smsmith } 4440617Smsmith#else 4540617Smsmith destroy_dev(dtrace_dev); 4640617Smsmith destroy_dev(helper_dev); 4740617Smsmith#endif 4840617Smsmith 4940617Smsmith mutex_enter(&dtrace_provider_lock); 5040617Smsmith mutex_enter(&dtrace_lock); 5140617Smsmith mutex_enter(&cpu_lock); 5264187Sjhb 5340617Smsmith ASSERT(dtrace_opens == 0); 5440617Smsmith 5540617Smsmith if (dtrace_helpers > 0) { 5640617Smsmith mutex_exit(&cpu_lock); 5740617Smsmith mutex_exit(&dtrace_lock); 5840617Smsmith mutex_exit(&dtrace_provider_lock); 5940617Smsmith return (EBUSY); 6040617Smsmith } 6140617Smsmith 6240617Smsmith if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) { 6340617Smsmith mutex_exit(&cpu_lock); 6440617Smsmith mutex_exit(&dtrace_lock); 6540617Smsmith mutex_exit(&dtrace_provider_lock); 6640617Smsmith return (EBUSY); 6740617Smsmith } 6840617Smsmith 6940617Smsmith dtrace_provider = NULL; 7040617Smsmith EVENTHANDLER_DEREGISTER(kld_load, dtrace_kld_load_tag); 7140617Smsmith EVENTHANDLER_DEREGISTER(kld_unload_try, dtrace_kld_unload_try_tag); 7240617Smsmith 7340617Smsmith if ((state = dtrace_anon_grab()) != NULL) { 7440617Smsmith /* 7540617Smsmith * If there were ECBs on this state, the provider should 7640617Smsmith * have not been allowed to detach; assert that there is 7740617Smsmith * none. 7840617Smsmith */ 7940617Smsmith ASSERT(state->dts_necbs == 0); 8040617Smsmith dtrace_state_destroy(state); 8140617Smsmith } 8240617Smsmith 8340617Smsmith bzero(&dtrace_anon, sizeof (dtrace_anon_t)); 8440617Smsmith 8540617Smsmith mutex_exit(&cpu_lock); 8640617Smsmith 8740617Smsmith if (dtrace_helptrace_enabled) { 8840617Smsmith kmem_free(dtrace_helptrace_buffer, 0); 8940617Smsmith dtrace_helptrace_buffer = NULL; 9040617Smsmith } 9140617Smsmith 9240617Smsmith if (dtrace_probes != NULL) { 9340617Smsmith kmem_free(dtrace_probes, 0); 9440617Smsmith dtrace_probes = NULL; 9540617Smsmith dtrace_nprobes = 0; 9640617Smsmith } 9740617Smsmith 9840617Smsmith dtrace_hash_destroy(dtrace_bymod); 9940617Smsmith dtrace_hash_destroy(dtrace_byfunc); 10040617Smsmith dtrace_hash_destroy(dtrace_byname); 10140617Smsmith dtrace_bymod = NULL; 10240617Smsmith dtrace_byfunc = NULL; 10340617Smsmith dtrace_byname = NULL; 10440617Smsmith 10540617Smsmith kmem_cache_destroy(dtrace_state_cache); 10640617Smsmith 10740617Smsmith delete_unrhdr(dtrace_arena); 10840617Smsmith 10940617Smsmith if (dtrace_toxrange != NULL) { 11040617Smsmith kmem_free(dtrace_toxrange, 0); 11140617Smsmith dtrace_toxrange = NULL; 11240617Smsmith dtrace_toxranges = 0; 11340617Smsmith dtrace_toxranges_max = 0; 11440617Smsmith } 11540617Smsmith 116136779Ssimokawa ASSERT(dtrace_vtime_references == 0); 117136779Ssimokawa ASSERT(dtrace_opens == 0); 118136779Ssimokawa ASSERT(dtrace_retained == NULL); 119136779Ssimokawa 12040617Smsmith mutex_exit(&dtrace_lock); 12140617Smsmith mutex_exit(&dtrace_provider_lock); 12240617Smsmith 12340617Smsmith mutex_destroy(&dtrace_meta_lock); 12464187Sjhb mutex_destroy(&dtrace_provider_lock); 12540617Smsmith mutex_destroy(&dtrace_lock); 12640617Smsmith#ifdef DEBUG 12740617Smsmith mutex_destroy(&dtrace_errlock); 12840617Smsmith#endif 12940617Smsmith 13040617Smsmith /* Reset our hook for exceptions. */ 13140617Smsmith dtrace_invop_uninit(); 13240617Smsmith 13340617Smsmith /* 13440617Smsmith * Reset our hook for thread switches, but ensure that vtime isn't 13540617Smsmith * active first. 13640617Smsmith */ 13740617Smsmith dtrace_vtime_active = 0; 13840617Smsmith dtrace_vtime_switch_func = NULL; 13940617Smsmith 14040617Smsmith /* Unhook from the trap handler. */ 14140617Smsmith dtrace_trap_func = NULL; 14240617Smsmith 14340617Smsmith return (error); 14440617Smsmith} 14540617Smsmith