]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/cddl/dev/dtrace/dtrace_unload.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 #if __FreeBSD_version < 800039
32         /*
33          * Check if there is still an event handler callback
34          * registered.
35          */
36         if (eh_tag != 0) {
37                 /* De-register the device cloning event handler. */
38                 EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
39                 eh_tag = 0;
40
41                 /* Stop device cloning. */
42                 clone_cleanup(&dtrace_clones);
43         }
44 #else
45         destroy_dev(dtrace_dev);
46         destroy_dev(helper_dev);
47 #endif
48
49         mutex_enter(&dtrace_provider_lock);
50         mutex_enter(&dtrace_lock);
51         mutex_enter(&cpu_lock);
52
53         ASSERT(dtrace_opens == 0);
54
55         if (dtrace_helpers > 0) {
56                 mutex_exit(&cpu_lock);
57                 mutex_exit(&dtrace_lock);
58                 mutex_exit(&dtrace_provider_lock);
59                 return (EBUSY);
60         }
61
62         if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) {
63                 mutex_exit(&cpu_lock);
64                 mutex_exit(&dtrace_lock);
65                 mutex_exit(&dtrace_provider_lock);
66                 return (EBUSY);
67         }
68
69         dtrace_provider = NULL;
70         EVENTHANDLER_DEREGISTER(kld_load, dtrace_kld_load_tag);
71         EVENTHANDLER_DEREGISTER(kld_unload_try, dtrace_kld_unload_try_tag);
72
73         if ((state = dtrace_anon_grab()) != NULL) {
74                 /*
75                  * If there were ECBs on this state, the provider should
76                  * have not been allowed to detach; assert that there is
77                  * none.
78                  */
79                 ASSERT(state->dts_necbs == 0);
80                 dtrace_state_destroy(state);
81         }
82
83         bzero(&dtrace_anon, sizeof (dtrace_anon_t));
84
85         mutex_exit(&cpu_lock);
86
87         if (dtrace_helptrace_enabled) {
88                 kmem_free(dtrace_helptrace_buffer, 0);
89                 dtrace_helptrace_buffer = NULL;
90         }
91
92         if (dtrace_probes != NULL) {
93                 kmem_free(dtrace_probes, 0);
94                 dtrace_probes = NULL;
95                 dtrace_nprobes = 0;
96         }
97
98         dtrace_hash_destroy(dtrace_bymod);
99         dtrace_hash_destroy(dtrace_byfunc);
100         dtrace_hash_destroy(dtrace_byname);
101         dtrace_bymod = NULL;
102         dtrace_byfunc = NULL;
103         dtrace_byname = NULL;
104
105         kmem_cache_destroy(dtrace_state_cache);
106
107         delete_unrhdr(dtrace_arena);
108
109         if (dtrace_toxrange != NULL) {
110                 kmem_free(dtrace_toxrange, 0);
111                 dtrace_toxrange = NULL;
112                 dtrace_toxranges = 0;
113                 dtrace_toxranges_max = 0;
114         }
115
116         ASSERT(dtrace_vtime_references == 0);
117         ASSERT(dtrace_opens == 0);
118         ASSERT(dtrace_retained == NULL);
119
120         mutex_exit(&dtrace_lock);
121         mutex_exit(&dtrace_provider_lock);
122
123         mutex_destroy(&dtrace_meta_lock);
124         mutex_destroy(&dtrace_provider_lock);
125         mutex_destroy(&dtrace_lock);
126 #ifdef DEBUG
127         mutex_destroy(&dtrace_errlock);
128 #endif
129
130         taskq_destroy(dtrace_taskq);
131
132         /* Reset our hook for exceptions. */
133         dtrace_invop_uninit();
134
135         /*
136          * Reset our hook for thread switches, but ensure that vtime isn't
137          * active first.
138          */
139         dtrace_vtime_active = 0;
140         dtrace_vtime_switch_func = NULL;
141
142         /* Unhook from the trap handler. */
143         dtrace_trap_func = NULL;
144
145         return (error);
146 }