summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_exit.c42
-rw-r--r--sys/kern/kern_ktrace.c2
2 files changed, 26 insertions, 18 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 7700a8f..696a101 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -356,26 +356,32 @@ retry:
mtx_unlock(&Giant);
#ifdef KTRACE
/*
- * Drain any pending records on the thread and release the trace
- * file. It might be better if drain-and-clear were atomic.
+ * Disable tracing, then drain any pending records and release
+ * the trace file.
*/
- ktrprocexit(td);
- PROC_LOCK(p);
- mtx_lock(&ktrace_mtx);
- p->p_traceflag = 0; /* don't trace the vrele() */
- tracevp = p->p_tracevp;
- p->p_tracevp = NULL;
- tracecred = p->p_tracecred;
- p->p_tracecred = NULL;
- mtx_unlock(&ktrace_mtx);
- PROC_UNLOCK(p);
- if (tracevp != NULL) {
- locked = VFS_LOCK_GIANT(tracevp->v_mount);
- vrele(tracevp);
- VFS_UNLOCK_GIANT(locked);
+ if (p->p_traceflag != 0) {
+ PROC_LOCK(p);
+ mtx_lock(&ktrace_mtx);
+ p->p_traceflag = 0;
+ mtx_unlock(&ktrace_mtx);
+ PROC_UNLOCK(p);
+ ktrprocexit(td);
+ PROC_LOCK(p);
+ mtx_lock(&ktrace_mtx);
+ tracevp = p->p_tracevp;
+ p->p_tracevp = NULL;
+ tracecred = p->p_tracecred;
+ p->p_tracecred = NULL;
+ mtx_unlock(&ktrace_mtx);
+ PROC_UNLOCK(p);
+ if (tracevp != NULL) {
+ locked = VFS_LOCK_GIANT(tracevp->v_mount);
+ vrele(tracevp);
+ VFS_UNLOCK_GIANT(locked);
+ }
+ if (tracecred != NULL)
+ crfree(tracecred);
}
- if (tracecred != NULL)
- crfree(tracecred);
#endif
/*
* Release reference to text vnode
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 2b7ee33..0ca4a30 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -444,6 +444,8 @@ void
ktruserret(struct thread *td)
{
+ if (STAILQ_EMPTY(&td->td_proc->p_ktr))
+ return;
ktrace_enter(td);
sx_xlock(&ktrace_sx);
ktr_drain(td);
OpenPOWER on IntegriCloud