Thinkpad 600e interrupt storm

John Baldwin jhb at FreeBSD.org
Mon Feb 7 08:56:37 PST 2005


On Tuesday 01 February 2005 12:55 am, list at understudy.net wrote:
> Hi ,
>
> I have loaded FreeBSD 5.3 on my Thinkpad 600e. However I am getting two
> errors on boot up that concern me.
> Interrupt storm detected on "irq10: pcic1"; throttling  interrupt source
> and
> Interrupt storm detected on "irq11: pcic0 uhci0"; throttling  interrupt
> source
>
> I have been through google and not found a workable solution to removing
> the errors. If anyone has an answer could you share it please.

Can you try using the interrupt storm modifications from HEAD:

Index: kern_intr.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_intr.c,v
retrieving revision 1.113.2.5
diff -u -r1.113.2.5 kern_intr.c
--- kern_intr.c	31 Jan 2005 23:26:15 -0000	1.113.2.5
+++ kern_intr.c	7 Feb 2005 16:51:48 -0000
@@ -485,15 +485,16 @@
 	struct intrhand *ih;		/* and our interrupt handler chain */
 	struct thread *td;
 	struct proc *p;
-	int count, warming, warned;
+	int count, warned, storming;
 	
 	td = curthread;
 	p = td->td_proc;
 	ithd = (struct ithd *)arg;	/* point to myself */
 	KASSERT(ithd->it_td == td && td->td_ithd == ithd,
 	    ("%s: ithread and proc linkage out of sync", __func__));
-	warming = 10 * intr_storm_threshold;
+	count = 0;
 	warned = 0;
+	storming = 0;
 
 	/*
 	 * As long as we have interrupts outstanding, go through the
@@ -514,7 +515,6 @@
 
 		CTR4(KTR_INTR, "%s: pid %d: (%s) need=%d", __func__,
 		     p->p_pid, p->p_comm, ithd->it_need);
-		count = 0;
 		while (ithd->it_need) {
 			/*
 			 * Service interrupts.  If another interrupt
@@ -548,56 +548,36 @@
 				if ((ih->ih_flags & IH_MPSAFE) == 0)
 					mtx_unlock(&Giant);
 			}
-			if (ithd->it_enable != NULL) {
-				ithd->it_enable(ithd->it_vector);
-
-				/*
-				 * Storm detection needs a delay here
-				 * to see slightly delayed interrupts
-				 * on some machines, but we don't
-				 * want to always delay, so only delay
-				 * while warming up.
-				 *
-				 * XXXRW: Calling DELAY() in the interrupt
-				 * path surely needs to be revisited.
-				 */
-				if (warming != 0) {
-					DELAY(1);
-					--warming;
-				}
-			}
 
 			/*
-			 * If we detect an interrupt storm, sleep until
-			 * the next hardclock tick.  We sleep at the
-			 * end of the loop instead of at the beginning
-			 * to ensure that we see slightly delayed
-			 * interrupts.
+			 * Interrupt storm handling:
+			 *
+			 * If this interrupt source is currently storming,
+			 * then throttle it to only fire the handler once
+			 * per clock tick.
+			 *
+			 * If this interrupt source is not currently
+			 * storming, but the number of back to back
+			 * interrupts exceeds the storm threshold, then
+			 * enter storming mode.
 			 */
-			if (count >= intr_storm_threshold) {
+			if (!storming && intr_storm_threshold != 0 &&
+			    count >= intr_storm_threshold) {
 				if (!warned) {
 					printf(
 	"Interrupt storm detected on \"%s\"; throttling interrupt source\n",
 					    p->p_comm);
 					warned = 1;
 				}
+				storming = 1;
+			}
+			if (storming)
 				tsleep(&count, td->td_priority, "istorm", 1);
+			else
+				count++;
 
-				/*
-				 * Fudge the count to re-throttle if the
-				 * interrupt is still active.  Our storm
-				 * detection is too primitive to detect
-				 * whether the storm has gone away
-				 * reliably, even if we were to waste a
-				 * lot of time spinning for the next
-				 * intr_storm_threshold interrupts, so
-				 * we assume that the storm hasn't gone
-				 * away unless the interrupt repeats
-				 * less often the hardclock interrupt.
-				 */
-				count = INT_MAX - 1;
-			}
-			count++;
+			if (ithd->it_enable != NULL)
+				ithd->it_enable(ithd->it_vector);
 		}
 		WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread");
 		mtx_assert(&Giant, MA_NOTOWNED);
@@ -610,6 +590,8 @@
 		mtx_lock_spin(&sched_lock);
 		if (!ithd->it_need) {
 			TD_SET_IWAIT(td);
+			count = 0;
+			storming = 0;
 			CTR2(KTR_INTR, "%s: pid %d: done", __func__, p->p_pid);
 			mi_switch(SW_VOL, NULL);
 			CTR2(KTR_INTR, "%s: pid %d: resumed", __func__, p->p_pid);


-- 
John Baldwin <jhb at FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org


More information about the freebsd-mobile mailing list