PERFORCE change 61351 for review

Julian Elischer julian at FreeBSD.org
Sat Sep 11 05:34:49 PDT 2004


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

Change 61351 by julian at julian_ref on 2004/09/11 12:33:50

	 Add debugging to try find the runq corruption problem

Affected files ...

.. //depot/projects/nsched/sys/kern/kern_fork.c#13 edit
.. //depot/projects/nsched/sys/kern/kern_switch.c#15 edit

Differences ...

==== //depot/projects/nsched/sys/kern/kern_fork.c#13 (text+ko) ====

@@ -256,7 +256,7 @@
 	 * other side with the expectation that the process is about to
 	 * exec.
 	 */
-	if (p1->p_flag & P_SA) {
+	if (p1->p_flag & P_HADTHREADS) {
 		/*
 		 * Idle the other threads for a second.
 		 * Since the user space is copied, it must remain stable.
@@ -727,7 +727,7 @@
 	/*
 	 * If other threads are waiting, let them continue now.
 	 */
-	if (p1->p_flag & P_SA) {
+	if (p1->p_flag & P_HADTHREADS) {
 		PROC_LOCK(p1);
 		thread_single_end();
 		PROC_UNLOCK(p1);
@@ -748,7 +748,7 @@
 	mac_destroy_proc(newproc);
 #endif
 	uma_zfree(proc_zone, newproc);
-	if (p1->p_flag & P_SA) {
+	if (p1->p_flag & P_HADTHREADS) {
 		PROC_LOCK(p1);
 		thread_single_end();
 		PROC_UNLOCK(p1);

==== //depot/projects/nsched/sys/kern/kern_switch.c#15 (text+ko) ====

@@ -118,6 +118,35 @@
 
 CTASSERT((RQB_BPW * RQB_LEN) == RQ_NQS);
 
+#ifdef	INVARIANTS
+#define CHECKRUNQ(kg, td) checkrunq((kg), (td));
+
+static void
+checkrunq(struct ksegrp *kg, struct thread *td)
+{
+	struct thread *td2;
+	int count = 0;
+	TAILQ_FOREACH(td2, &kg->kg_runq, td_runq) {
+		/* XXX Debugging hack */
+		if (!TD_ON_RUNQ(td2)) {
+			printf("thread in wrong state, td2= %p\n", td2);
+			panic("corruption in runqueue");
+		}
+		if (td == td2) {
+			printf("thread alreadyin runq, td2= %p\n", td);
+			panic("confusion in runqueue");
+		}
+		if (++count > 10000) {
+			printf("corrupt kg_runq, td= %p\n", td);
+			panic("deadlock in runqueue");
+		}
+	}
+}
+
+#else
+#define CHECKRUNQ(kg, td) 
+#endif
+
 #define td_kse td_sched
 
 /************************************************************************
@@ -153,6 +182,7 @@
 		td = ke->ke_thread;
 		KASSERT((td->td_kse == ke), ("kse/thread mismatch"));
 		kg = ke->ke_ksegrp;
+		CHECKRUNQ(kg, NULL)
 		if (td->td_proc->p_flag & P_HADTHREADS) {
 			if (kg->kg_last_assigned == td) {
 				kg->kg_last_assigned = TAILQ_PREV(td,
@@ -160,6 +190,7 @@
 			}
 			TAILQ_REMOVE(&kg->kg_runq, td, td_runq);
 			kg->kg_runnable--;
+			CHECKRUNQ(kg, td)
 		}
 		CTR2(KTR_RUNQ, "choosethread: td=%p pri=%d",
 		    td, td->td_priority);
@@ -257,6 +288,7 @@
    	td3 = TAILQ_PREV(td, threadqueue, td_runq);
 	TAILQ_REMOVE(&kg->kg_runq, td, td_runq);
 	kg->kg_runnable--;
+	CHECKRUNQ(kg, td)
 	if (ke->ke_state == KES_ONRUNQ) {
 		/*
 		 * This thread has been assigned to the system run queue.
@@ -273,6 +305,7 @@
 			kg->kg_last_assigned = td3;
 		/* slot_fill(kg); */ /* will replace it with another */
 	}
+	CHECKRUNQ(kg, NULL)
 }
 #endif
 
@@ -305,7 +338,7 @@
 
 	/* It is a threaded process */
 	kg = td->td_ksegrp;
-	TD_SET_CAN_RUN(td);
+	CHECKRUNQ(kg, NULL)
 	if (ke->ke_state == KES_ONRUNQ) {
 		if (kg->kg_last_assigned == td) {
 			kg->kg_last_assigned =
@@ -315,9 +348,11 @@
 		kg->kg_avail_opennings++;
 	}
 	TAILQ_REMOVE(&kg->kg_runq, td, td_runq);
+	CHECKRUNQ(kg, td)
 	kg->kg_runnable--;
 	td->td_priority = newpri;
 	setrunqueue(td, SRQ_BORING);
+	CHECKRUNQ(kg, NULL)
 }
 int limitcount;
 void
@@ -355,6 +390,7 @@
 		return;
 	}
 
+	CHECKRUNQ(kg, td)
 	tda = kg->kg_last_assigned;
 	if ((kg->kg_avail_opennings <= 0) &&
 	(tda && (tda->td_priority > td->td_priority))) {
@@ -380,18 +416,13 @@
 			TAILQ_INSERT_BEFORE(td2, td, td_runq);
 			break;
 		}
-		/* XXX Debugging hack */
-		if (++count > 10000) {
-			printf("setrunqueue(): corrupt kq_runq, td= %p\n", td);
-			panic("deadlock in setrunqueue");
-		}
 	}
 	if (td2 == NULL) {
 		/* We ran off the end of the TAILQ or it was empty. */
 		kg->kg_runnable++;
 		TAILQ_INSERT_TAIL(&kg->kg_runq, td, td_runq);
 	}
-
+	CHECKRUNQ(kg, NULL)
 	/*
 	 * If we have a slot to use, then put the thread on the system
 	 * run queue and if needed, readjust the last_assigned pointer.


More information about the p4-projects mailing list