commit e4a774fe09f5a19c31181312e8b15e1f8ffbbb7f
Author: Ryota Ozaki <ozaki-r@iij.ad.jp>
Date:   Tue Aug 5 10:59:52 2014 +0900

    Add debug facility for pserialize

diff --git a/sys/kern/subr_pserialize.c b/sys/kern/subr_pserialize.c
index 0c9f93f..5d1536e 100644
--- a/sys/kern/subr_pserialize.c
+++ b/sys/kern/subr_pserialize.c
@@ -187,6 +187,9 @@ pserialize_read_enter(void)
 {
 
 	KASSERT(!cpu_intr_p());
+#ifdef LOCKDEBUG
+	curlwp->l_psz_n_reading++;
+#endif
 	return splsoftserial();
 }
 
@@ -195,6 +198,9 @@ pserialize_read_exit(int s)
 {
 
 	splx(s);
+#ifdef LOCKDEBUG
+	KASSERT(--curlwp->l_psz_n_reading >= 0);
+#endif
 }
 
 /*
@@ -209,6 +215,13 @@ pserialize_switchpoint(void)
 	pserialize_t psz, next;
 	cpuid_t cid;
 
+#ifdef LOCKDEBUG
+	/*
+	 * We have to ensure LWP never come here from inside a critical section.
+	 */
+	KASSERT(curlwp->l_psz_n_reading == 0);
+#endif
+
 	/*
 	 * If no updates pending, bail out.  No need to lock in order to
 	 * test psz_work_todo; the only ill effect of missing an update
diff --git a/sys/sys/lwp.h b/sys/sys/lwp.h
index 634eecc..c20ab97 100644
--- a/sys/sys/lwp.h
+++ b/sys/sys/lwp.h
@@ -196,6 +196,10 @@ struct lwp {
 	uint64_t	*l_syscall_counter; /* !: counter for current process */
 
 	struct kdtrace_thread *l_dtrace; /* (: DTrace-specific data. */
+
+#ifdef LOCKDEBUG
+	int		l_psz_n_reading; /* !: # of critical sections LWP is in */
+#endif
 };
 
 /*