Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Oct 2019 21:24:26 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r353596 - in head/sys: kern sys
Message-ID:  <201910152124.x9FLOQIB060918@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Tue Oct 15 21:24:25 2019
New Revision: 353596
URL: https://svnweb.freebsd.org/changeset/base/353596

Log:
  When assertion for a thread not being in an epoch fails also print all
  entered epochs. Works with EPOCH_TRACE only.
  
  Reviewed by:	hselasky
  Differential Revision:	https://reviews.freebsd.org/D22017

Modified:
  head/sys/kern/kern_malloc.c
  head/sys/kern/kern_synch.c
  head/sys/kern/subr_epoch.c
  head/sys/kern/subr_trap.c
  head/sys/sys/epoch.h

Modified: head/sys/kern/kern_malloc.c
==============================================================================
--- head/sys/kern/kern_malloc.c	Tue Oct 15 21:22:13 2019	(r353595)
+++ head/sys/kern/kern_malloc.c	Tue Oct 15 21:24:25 2019	(r353596)
@@ -520,6 +520,10 @@ malloc_dbg(caddr_t *vap, size_t *sizep, struct malloc_
 	if (flags & M_WAITOK) {
 		KASSERT(curthread->td_intr_nesting_level == 0,
 		   ("malloc(M_WAITOK) in interrupt context"));
+#ifdef EPOCH_TRACE
+		if (__predict_false(curthread->td_epochnest > 0))
+			epoch_trace_list(curthread);
+#endif
 		KASSERT(curthread->td_epochnest == 0,
 			("malloc(M_WAITOK) in epoch context"));		
 	}

Modified: head/sys/kern/kern_synch.c
==============================================================================
--- head/sys/kern/kern_synch.c	Tue Oct 15 21:22:13 2019	(r353595)
+++ head/sys/kern/kern_synch.c	Tue Oct 15 21:24:25 2019	(r353596)
@@ -148,6 +148,10 @@ _sleep(void *ident, struct lock_object *lock, int prio
 	    ("sleeping without a lock"));
 	KASSERT(ident != NULL, ("_sleep: NULL ident"));
 	KASSERT(TD_IS_RUNNING(td), ("_sleep: curthread not running"));
+#ifdef EPOCH_TRACE
+	if (__predict_false(curthread->td_epochnest > 0))
+		epoch_trace_list(curthread);
+#endif
 	KASSERT(td->td_epochnest == 0, ("sleeping in an epoch section"));
 	if (priority & PDROP)
 		KASSERT(lock != NULL && lock != &Giant.lock_object,

Modified: head/sys/kern/subr_epoch.c
==============================================================================
--- head/sys/kern/subr_epoch.c	Tue Oct 15 21:22:13 2019	(r353595)
+++ head/sys/kern/subr_epoch.c	Tue Oct 15 21:24:25 2019	(r353596)
@@ -234,6 +234,17 @@ epoch_trace_exit(struct thread *td, epoch_t epoch, epo
 	} else
 		SLIST_REMOVE_HEAD(&td->td_epochs, et_tlink);
 }
+
+/* Used by assertions that check thread state before going to sleep. */
+void
+epoch_trace_list(struct thread *td)
+{
+	epoch_tracker_t iet;
+
+	SLIST_FOREACH(iet, &td->td_epochs, et_tlink)
+		printf("Epoch %s entered at %s:%d\n", iet->et_epoch->e_name,
+		    iet->et_file, iet->et_line);
+}
 #endif /* EPOCH_TRACE */
 
 static void

Modified: head/sys/kern/subr_trap.c
==============================================================================
--- head/sys/kern/subr_trap.c	Tue Oct 15 21:22:13 2019	(r353595)
+++ head/sys/kern/subr_trap.c	Tue Oct 15 21:24:25 2019	(r353596)
@@ -166,6 +166,10 @@ userret(struct thread *td, struct trapframe *frame)
 	WITNESS_WARN(WARN_PANIC, NULL, "userret: returning");
 	KASSERT(td->td_critnest == 0,
 	    ("userret: Returning in a critical section"));
+#ifdef EPOCH_TRACE
+	if (__predict_false(curthread->td_epochnest > 0))
+		epoch_trace_list(curthread);
+#endif
 	KASSERT(td->td_epochnest == 0,
 	    ("userret: Returning in an epoch section"));
 	KASSERT(td->td_locks == 0,

Modified: head/sys/sys/epoch.h
==============================================================================
--- head/sys/sys/epoch.h	Tue Oct 15 21:22:13 2019	(r353595)
+++ head/sys/sys/epoch.h	Tue Oct 15 21:24:25 2019	(r353596)
@@ -83,6 +83,7 @@ DPCPU_DECLARE(struct grouptask, epoch_cb_task);
 void _epoch_enter_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE);
 void _epoch_exit_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE);
 #ifdef EPOCH_TRACE
+void epoch_trace_list(struct thread *);
 #define	epoch_enter_preempt(epoch, et)	_epoch_enter_preempt(epoch, et, __FILE__, __LINE__)
 #define	epoch_exit_preempt(epoch, et)	_epoch_exit_preempt(epoch, et, __FILE__, __LINE__)
 #else



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910152124.x9FLOQIB060918>