Home | History | Annotate | Line # | Download | only in dtrace
      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