]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/cddl/dev/dtrace/dtrace_unload.c
Import libcxxrt master 00bc29eb6513624824a6d7db2ebc768a4216a604.
[FreeBSD/FreeBSD.git] / sys / cddl / dev / dtrace / dtrace_unload.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * $FreeBSD$
22  *
23  */
24
25 static int
26 dtrace_unload()
27 {
28         dtrace_state_t *state;
29         int error = 0;
30
31         destroy_dev(dtrace_dev);
32         destroy_dev(helper_dev);
33
34         mutex_enter(&dtrace_provider_lock);
35         mutex_enter(&dtrace_lock);
36         mutex_enter(&cpu_lock);
37
38         ASSERT(dtrace_opens == 0);
39
40         if (dtrace_helpers > 0) {
41                 mutex_exit(&cpu_lock);
42                 mutex_exit(&dtrace_lock);
43                 mutex_exit(&dtrace_provider_lock);
44                 return (EBUSY);
45         }
46
47         if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) {
48                 mutex_exit(&cpu_lock);
49                 mutex_exit(&dtrace_lock);
50                 mutex_exit(&dtrace_provider_lock);
51                 return (EBUSY);
52         }
53
54         dtrace_provider = NULL;
55         EVENTHANDLER_DEREGISTER(kld_load, dtrace_kld_load_tag);
56         EVENTHANDLER_DEREGISTER(kld_unload_try, dtrace_kld_unload_try_tag);
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, 0);
74                 dtrace_helptrace_buffer = NULL;
75         }
76
77         if (dtrace_probes != NULL) {
78                 kmem_free(dtrace_probes, 0);
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         delete_unrhdr(dtrace_arena);
93
94         if (dtrace_toxrange != NULL) {
95                 kmem_free(dtrace_toxrange, 0);
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 #ifdef DEBUG
112         mutex_destroy(&dtrace_errlock);
113 #endif
114
115         taskq_destroy(dtrace_taskq);
116
117         /* Reset our hook for exceptions. */
118         dtrace_invop_uninit();
119
120         /*
121          * Reset our hook for thread switches, but ensure that vtime isn't
122          * active first.
123          */
124         dtrace_vtime_active = 0;
125         dtrace_vtime_switch_func = NULL;
126
127         /* Unhook from the trap handler. */
128         dtrace_trap_func = NULL;
129
130         return (error);
131 }