summaryrefslogtreecommitdiffstats
path: root/sys/cddl/dev/dtrace/dtrace_unload.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cddl/dev/dtrace/dtrace_unload.c')
-rw-r--r--sys/cddl/dev/dtrace/dtrace_unload.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/sys/cddl/dev/dtrace/dtrace_unload.c b/sys/cddl/dev/dtrace/dtrace_unload.c
new file mode 100644
index 0000000..eb14543
--- /dev/null
+++ b/sys/cddl/dev/dtrace/dtrace_unload.c
@@ -0,0 +1,138 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ *
+ */
+
+static int
+dtrace_unload()
+{
+ dtrace_state_t *state;
+ int error = 0;
+
+ /*
+ * Check if there is still an event handler callback
+ * registered.
+ */
+ if (eh_tag != 0) {
+ /* De-register the device cloning event handler. */
+ EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
+ eh_tag = 0;
+
+ /* Stop device cloning. */
+ clone_cleanup(&dtrace_clones);
+ }
+
+ mutex_enter(&dtrace_provider_lock);
+ mutex_enter(&dtrace_lock);
+ mutex_enter(&cpu_lock);
+
+ ASSERT(dtrace_opens == 0);
+
+ if (dtrace_helpers > 0) {
+ mutex_exit(&cpu_lock);
+ mutex_exit(&dtrace_lock);
+ mutex_exit(&dtrace_provider_lock);
+ return (EBUSY);
+ }
+
+ if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) {
+ mutex_exit(&cpu_lock);
+ mutex_exit(&dtrace_lock);
+ mutex_exit(&dtrace_provider_lock);
+ return (EBUSY);
+ }
+
+ dtrace_provider = NULL;
+
+ if ((state = dtrace_anon_grab()) != NULL) {
+ /*
+ * If there were ECBs on this state, the provider should
+ * have not been allowed to detach; assert that there is
+ * none.
+ */
+ ASSERT(state->dts_necbs == 0);
+ dtrace_state_destroy(state);
+ }
+
+ bzero(&dtrace_anon, sizeof (dtrace_anon_t));
+
+ mutex_exit(&cpu_lock);
+
+ if (dtrace_helptrace_enabled) {
+ kmem_free(dtrace_helptrace_buffer, 0);
+ dtrace_helptrace_buffer = NULL;
+ }
+
+ if (dtrace_probes != NULL) {
+ kmem_free(dtrace_probes, 0);
+ dtrace_probes = NULL;
+ dtrace_nprobes = 0;
+ }
+
+ dtrace_hash_destroy(dtrace_bymod);
+ dtrace_hash_destroy(dtrace_byfunc);
+ dtrace_hash_destroy(dtrace_byname);
+ dtrace_bymod = NULL;
+ dtrace_byfunc = NULL;
+ dtrace_byname = NULL;
+
+ kmem_cache_destroy(dtrace_state_cache);
+
+ delete_unrhdr(dtrace_arena);
+
+ if (dtrace_toxrange != NULL) {
+ kmem_free(dtrace_toxrange, 0);
+ dtrace_toxrange = NULL;
+ dtrace_toxranges = 0;
+ dtrace_toxranges_max = 0;
+ }
+
+ ASSERT(dtrace_vtime_references == 0);
+ ASSERT(dtrace_opens == 0);
+ ASSERT(dtrace_retained == NULL);
+
+ mutex_exit(&dtrace_lock);
+ mutex_exit(&dtrace_provider_lock);
+
+ mutex_destroy(&dtrace_meta_lock);
+ mutex_destroy(&dtrace_provider_lock);
+ mutex_destroy(&dtrace_lock);
+ mutex_destroy(&dtrace_errlock);
+
+ /* XXX Hack */
+ mutex_destroy(&mod_lock);
+
+ /* Reset our hook for exceptions. */
+ dtrace_invop_uninit();
+
+ /*
+ * Reset our hook for thread switches, but ensure that vtime isn't
+ * active first.
+ */
+ dtrace_vtime_active = 0;
+ dtrace_vtime_switch_func = NULL;
+
+ /* Unhook from the trap handler. */
+ dtrace_trap_func = NULL;
+
+ return (error);
+}
OpenPOWER on IntegriCloud