PERFORCE change 83036 for review

John Baldwin jhb at FreeBSD.org
Fri Sep 2 19:39:36 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=83036

Change 83036 by jhb at jhb_slimer on 2005/09/02 19:39:25

	Add a simple API to indicate that a thread is not allowed to sleep
	and use it in place of the g_xdown and g_xup mutexes.  Also, use
	it in the ithreads around the handlers.  Also, add a test for it to
	the crash module.

Affected files ...

.. //depot/projects/smpng/sys/geom/geom_io.c#37 edit
.. //depot/projects/smpng/sys/kern/kern_intr.c#69 edit
.. //depot/projects/smpng/sys/kern/subr_sleepqueue.c#17 edit
.. //depot/projects/smpng/sys/modules/crash/crash.c#17 edit
.. //depot/projects/smpng/sys/notes#53 edit
.. //depot/projects/smpng/sys/sys/proc.h#148 edit

Differences ...

==== //depot/projects/smpng/sys/geom/geom_io.c#37 (text+ko) ====

@@ -42,6 +42,7 @@
 #include <sys/malloc.h>
 #include <sys/bio.h>
 #include <sys/ktr.h>
+#include <sys/proc.h>
 
 #include <sys/errno.h>
 #include <geom/geom.h>
@@ -364,12 +365,6 @@
 	struct bio *bp;
 	off_t excess;
 	int error;
-#ifdef WITNESS
-	struct mtx mymutex;
- 
-	bzero(&mymutex, sizeof mymutex);
-	mtx_init(&mymutex, "g_xdown", NULL, MTX_DEF);
-#endif
 
 	for(;;) {
 		g_bioq_lock(&g_bio_run_down);
@@ -425,16 +420,12 @@
 		default:
 			break;
 		}
-#ifdef WITNESS
-		mtx_lock(&mymutex);
-#endif
+		THREAD_NO_SLEEPING();
 		CTR4(KTR_GEOM, "g_down starting bp %p provider %s off %ld "
 		    "len %ld", bp, bp->bio_to->name, bp->bio_offset,
 		    bp->bio_length);
 		bp->bio_to->geom->start(bp);
-#ifdef WITNESS
-		mtx_unlock(&mymutex);
-#endif
+		THREAD_SLEEPING_OK();
 	}
 }
 
@@ -462,40 +453,26 @@
 g_io_schedule_up(struct thread *tp __unused)
 {
 	struct bio *bp;
-#ifdef WITNESS
-	struct mtx mymutex;
- 
-	bzero(&mymutex, sizeof mymutex);
-	mtx_init(&mymutex, "g_xup", NULL, MTX_DEF);
-#endif
 	for(;;) {
 		g_bioq_lock(&g_bio_run_up);
 		bp = g_bioq_first(&g_bio_run_task);
 		if (bp != NULL) {
 			g_bioq_unlock(&g_bio_run_up);
-#ifdef WITNESS
-			mtx_lock(&mymutex);
-#endif
+			THREAD_NO_SLEEPING();
 			CTR1(KTR_GEOM, "g_up processing task bp %p", bp);
 			bp->bio_task(bp->bio_task_arg);
-#ifdef WITNESS
-			mtx_unlock(&mymutex);
-#endif
+			THREAD_SLEEPING_OK();
 			continue;
 		}
 		bp = g_bioq_first(&g_bio_run_up);
 		if (bp != NULL) {
 			g_bioq_unlock(&g_bio_run_up);
-#ifdef WITNESS
-			mtx_lock(&mymutex);
-#endif
+			THREAD_NO_SLEEPING();
 			CTR4(KTR_GEOM, "g_up biodone bp %p provider %s off "
 			    "%ld len %ld", bp, bp->bio_to->name,
 			    bp->bio_offset, bp->bio_length);
 			biodone(bp);
-#ifdef WITNESS
-			mtx_unlock(&mymutex);
-#endif
+			THREAD_SLEEPING_OK();
 			continue;
 		}
 		CTR0(KTR_GEOM, "g_up going to sleep");

==== //depot/projects/smpng/sys/kern/kern_intr.c#69 (text+ko) ====

@@ -521,6 +521,7 @@
 			 * another pass.
 			 */
 			atomic_store_rel_int(&ithd->it_need, 0);
+			THREAD_NO_SLEEPING();
 restart:
 			TAILQ_FOREACH(ih, &ithd->it_handlers, ih_next) {
 				if (ithd->it_flags & IT_SOFT && !ih->ih_need)
@@ -546,6 +547,7 @@
 				if ((ih->ih_flags & IH_MPSAFE) == 0)
 					mtx_unlock(&Giant);
 			}
+			THREAD_SLEEPING_OK();
 
 			/*
 			 * Interrupt storm handling:

==== //depot/projects/smpng/sys/kern/subr_sleepqueue.c#17 (text+ko) ====

@@ -269,6 +269,10 @@
 	MPASS(td->td_sleepqueue != NULL);
 	MPASS(wchan != NULL);
 
+	/* If this thread is not allowed to sleep, die a horrible death. */
+	KASSERT(!(td->td_pflags & TDP_NOSLEEPING),
+	    ("trying to sleep while sleeping is prohibited"));
+
 	/* Look up the sleep queue associated with the wait channel 'wchan'. */
 	sq = sleepq_lookup(wchan);
 

==== //depot/projects/smpng/sys/modules/crash/crash.c#17 (text+ko) ====

@@ -383,7 +383,18 @@
 }
 CRASH_EVENT("lock test1 mutex and then Giant", test_mtx_then_Giant);
 #endif
-	
+
+static void
+test_no_sleeping(void)
+{
+
+	printf("Should panic\n");
+	THREAD_NO_SLEEPING();
+	tsleep(&test1_mtx, curthread->td_priority, "sleep", 1);
+	THREAD_SLEEPING_OK();
+}
+CRASH_EVENT("sleep while sleeping is prohibited", test_no_sleeping);
+
 /* Help event should be last so that it is always event 1. */
 
 static void

==== //depot/projects/smpng/sys/notes#53 (text+ko) ====

@@ -85,7 +85,7 @@
   - fork counts?
 - Add a cache-line padded mtx_aligned union and use it for the mutex pools.
 - Robert wants intrcnt's for IPIs
-- Add checks to msleep() and cv_wait*() to ensure they aren't called by an
++ Add checks to msleep() and cv_wait*() to ensure they aren't called by an
   interrupt thread.  Would need to provide an exception for the istorm
   stuff.
 - Add witness checks to thread exit to make sure dying threads don't leak

==== //depot/projects/smpng/sys/sys/proc.h#148 (text+ko) ====

@@ -368,7 +368,7 @@
 #define	TDP_ALTSTACK	0x00000020 /* Have alternate signal stack. */
 #define	TDP_DEADLKTREAT	0x00000040 /* Lock aquisition - deadlock treatment. */
 #define	TDP_SA		0x00000080 /* A scheduler activation based thread. */
-#define	TDP_UNUSED8	0x00000100 /* --available -- */
+#define	TDP_NOSLEEPING	0x00000100 /* Thread is not allowed to sleep on a sq. */
 #define	TDP_OWEUPC	0x00000200 /* Call addupc() at next AST. */
 #define	TDP_UNUSED10	0x00000400 /* --available -- */
 #define	TDP_CAN_UNBIND	0x00000800 /* Only temporarily bound. */
@@ -793,6 +793,19 @@
 /* Check whether a thread is safe to be swapped out. */
 #define	thread_safetoswapout(td) (TD_IS_SLEEPING(td) || TD_IS_SUSPENDED(td))
 
+/* Control whether or not it is safe for curthread to sleep. */
+#define	THREAD_NO_SLEEPING() do {					\
+	KASSERT(!(curthread->td_pflags & TDP_NOSLEEPING),		\
+	    ("nested no sleeping"));					\
+	curthread->td_pflags |= TDP_NOSLEEPING;				\
+} while (0)
+
+#define	THREAD_SLEEPING_OK() do {					\
+	KASSERT((curthread->td_pflags & TDP_NOSLEEPING),		\
+	    ("nested sleeping ok"));					\
+	curthread->td_pflags &= ~TDP_NOSLEEPING;			\
+} while (0)
+
 /* Lock and unlock process arguments. */
 #define	PARGS_LOCK(p)		mtx_lock(&pargs_ref_lock)
 #define	PARGS_UNLOCK(p)		mtx_unlock(&pargs_ref_lock)


More information about the p4-projects mailing list