summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2004-11-16 16:09:46 +0000
committerjhb <jhb@FreeBSD.org>2004-11-16 16:09:46 +0000
commit9933c3bdef5c40de3dd15bd8c8e456f64ad93de9 (patch)
treec9888c5d256813195a29a3dfb6f04ca613008944 /sys
parent79cd9caa774b550ac404b756bf3e0ac20244c6ec (diff)
downloadFreeBSD-src-9933c3bdef5c40de3dd15bd8c8e456f64ad93de9.zip
FreeBSD-src-9933c3bdef5c40de3dd15bd8c8e456f64ad93de9.tar.gz
Adjust the interrupt storm handling code to better handle a storm. When
a storm is detected, enter "storming" mode which throttles the interrupt source such that the handlers are run once every clock tick. Previously we allowed a full set of storm_threshold interations through the handler before going back to sleep. Also, this currently will intentionally exit storming mode once a second to see if the storm has passed. Tested by: marcus Discussed with: bde
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_intr.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index 6569056..1156883 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -485,7 +485,7 @@ ithread_loop(void *arg)
struct intrhand *ih; /* and our interrupt handler chain */
struct thread *td;
struct proc *p;
- int count, warned;
+ int count, warned, storming;
td = curthread;
p = td->td_proc;
@@ -494,6 +494,7 @@ ithread_loop(void *arg)
("%s: ithread and proc linkage out of sync", __func__));
count = 0;
warned = 0;
+ storming = 0;
/*
* As long as we have interrupts outstanding, go through the
@@ -549,10 +550,26 @@ restart:
}
/*
- * If we detect an interrupt storm, pause with the
- * source masked until the next hardclock tick.
+ * Interrupt storm handling:
+ *
+ * If this interrupt source is currently storming,
+ * then throttle it to only fire the handler once
+ * per clock tick. Each second we go out of storming
+ * mode to see if the storm has subsided.
+ *
+ * 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 (intr_storm_threshold != 0 &&
+ if (storming) {
+ tsleep(&count, td->td_priority, "istorm", 1);
+ if (count > hz) {
+ storming = 0;
+ count = 0;
+ } else
+ count++;
+ } else if (intr_storm_threshold != 0 &&
count >= intr_storm_threshold) {
if (!warned) {
printf(
@@ -560,7 +577,7 @@ restart:
p->p_comm);
warned = 1;
}
- tsleep(&count, td->td_priority, "istorm", 1);
+ storming = 1;
count = 0;
} else
count++;
@@ -580,6 +597,7 @@ restart:
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);
OpenPOWER on IntegriCloud