svn commit: r259519 - stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace
Alan Somers
asomers at FreeBSD.org
Tue Dec 17 16:11:00 UTC 2013
Author: asomers
Date: Tue Dec 17 16:10:59 2013
New Revision: 259519
URL: http://svnweb.freebsd.org/changeset/base/259519
Log:
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
Modified:
stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
Directory Properties:
stable/9/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c Tue Dec 17 15:34:38 2013 (r259518)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c Tue Dec 17 16:10:59 2013 (r259519)
@@ -2276,13 +2276,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);
@@ -2336,6 +2329,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.
*/
@@ -2428,6 +2439,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. */
@@ -2443,6 +2468,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;
@@ -2455,22 +2488,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);
More information about the svn-src-stable-9
mailing list