Re: Thinkpad 600e interrupt storm

John Baldwin <[email protected]>
Newsgroups gmane.os.freebsd.devel.mobile
Message-ID <[email protected]>
On Tuesday 01 February 2005 12:55 am, [email protected] 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 <[email protected]>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mobile
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.