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