summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts
diff options
context:
space:
mode:
authorasomers <asomers@FreeBSD.org>2013-12-16 19:59:34 +0000
committerasomers <asomers@FreeBSD.org>2013-12-16 19:59:34 +0000
commit34ade72d5f333ee47cbd09a453c1578f2e92fc66 (patch)
tree91a163c3552e24c0cecf3159976a883b6befb3e9 /sys/cddl/contrib/opensolaris/uts
parentd72da1522ebaf9f726ebc64ad1bd4c7b3eef10ec (diff)
downloadFreeBSD-src-34ade72d5f333ee47cbd09a453c1578f2e92fc66.zip
FreeBSD-src-34ade72d5f333ee47cbd09a453c1578f2e92fc66.tar.gz
MFC r258311
opensolaris/uts/common/dtrace/fasttrap.c Fix several problems that can cause panics on kldload and kldunload. * kproc_create(fasttrap_pid_cleanup_cb, ...) gets called before fasttrap_provs.fth_table gets allocated. This can lead to a panic on module load, because fasttrap_pid_cleanup_cb references fasttrap_provs.fth_table. Move kproc_create down after the point that fasttrap_provs.fth_table gets allocated, and modify the error handling accordingly. * dtrace_fasttrap_{fork,exec,exit} weren't getting NULLed until after fasttrap_provs.fth_table got freed. That caused panics on module unload because fasttrap_exec_exit calls fasttrap_provider_retire, which references fasttrap_provs.fth_table. NULL those function pointers earlier. * There wasn't any code to destroy the fasttrap_{tpoints,provs,procs}.fth_table mutexes on module unload, leading to a resource leak when WITNESS is enabled. Destroy those mutexes during fasttrap_unload(). Sponsored by: Spectra Logic Corporation
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c63
1 files changed, 40 insertions, 23 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
index fd5508f..d72ee63 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
@@ -2284,13 +2284,6 @@ fasttrap_load(void)
mutex_init(&fasttrap_count_mtx, "fasttrap count mtx", MUTEX_DEFAULT,
NULL);
- ret = kproc_create(fasttrap_pid_cleanup_cb, NULL,
- &fasttrap_cleanup_proc, 0, 0, "ftcleanup");
- if (ret != 0) {
- destroy_dev(fasttrap_cdev);
- return (ret);
- }
-
#if defined(sun)
fasttrap_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
"fasttrap-max-probes", FASTTRAP_MAX_DEFAULT);
@@ -2344,6 +2337,24 @@ fasttrap_load(void)
"providers bucket mtx", MUTEX_DEFAULT, NULL);
#endif
+ ret = kproc_create(fasttrap_pid_cleanup_cb, NULL,
+ &fasttrap_cleanup_proc, 0, 0, "ftcleanup");
+ if (ret != 0) {
+ destroy_dev(fasttrap_cdev);
+#if !defined(sun)
+ for (i = 0; i < fasttrap_provs.fth_nent; i++)
+ mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx);
+ for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
+ mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
+#endif
+ kmem_free(fasttrap_provs.fth_table, fasttrap_provs.fth_nent *
+ sizeof (fasttrap_bucket_t));
+ mtx_destroy(&fasttrap_cleanup_mtx);
+ mutex_destroy(&fasttrap_count_mtx);
+ return (ret);
+ }
+
+
/*
* ... and the procs hash table.
*/
@@ -2436,6 +2447,20 @@ fasttrap_unload(void)
return (-1);
}
+ /*
+ * Stop new processes from entering these hooks now, before the
+ * fasttrap_cleanup thread runs. That way all processes will hopefully
+ * be out of these hooks before we free fasttrap_provs.fth_table
+ */
+ ASSERT(dtrace_fasttrap_fork == &fasttrap_fork);
+ dtrace_fasttrap_fork = NULL;
+
+ ASSERT(dtrace_fasttrap_exec == &fasttrap_exec_exit);
+ dtrace_fasttrap_exec = NULL;
+
+ ASSERT(dtrace_fasttrap_exit == &fasttrap_exec_exit);
+ dtrace_fasttrap_exit = NULL;
+
mtx_lock(&fasttrap_cleanup_mtx);
fasttrap_cleanup_drain = 1;
/* Wait for the cleanup thread to finish up and signal us. */
@@ -2451,6 +2476,14 @@ fasttrap_unload(void)
mutex_exit(&fasttrap_count_mtx);
#endif
+#if !defined(sun)
+ for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
+ mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
+ for (i = 0; i < fasttrap_provs.fth_nent; i++)
+ mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx);
+ for (i = 0; i < fasttrap_procs.fth_nent; i++)
+ mutex_destroy(&fasttrap_procs.fth_table[i].ftb_mtx);
+#endif
kmem_free(fasttrap_tpoints.fth_table,
fasttrap_tpoints.fth_nent * sizeof (fasttrap_bucket_t));
fasttrap_tpoints.fth_nent = 0;
@@ -2463,22 +2496,6 @@ fasttrap_unload(void)
fasttrap_procs.fth_nent * sizeof (fasttrap_bucket_t));
fasttrap_procs.fth_nent = 0;
- /*
- * We know there are no tracepoints in any process anywhere in
- * the system so there is no process which has its p_dtrace_count
- * greater than zero, therefore we know that no thread can actively
- * be executing code in fasttrap_fork(). Similarly for p_dtrace_probes
- * and fasttrap_exec() and fasttrap_exit().
- */
- ASSERT(dtrace_fasttrap_fork == &fasttrap_fork);
- dtrace_fasttrap_fork = NULL;
-
- ASSERT(dtrace_fasttrap_exec == &fasttrap_exec_exit);
- dtrace_fasttrap_exec = NULL;
-
- ASSERT(dtrace_fasttrap_exit == &fasttrap_exec_exit);
- dtrace_fasttrap_exit = NULL;
-
#if !defined(sun)
destroy_dev(fasttrap_cdev);
mutex_destroy(&fasttrap_count_mtx);
OpenPOWER on IntegriCloud