1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-23 11:18:54 +00:00

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
This commit is contained in:
John Baldwin 2004-11-16 16:09:46 +00:00
parent ca298e5594
commit a51dae09ec
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137775

View File

@ -485,7 +485,7 @@ ithread_loop(void *arg)
struct intrhand *ih; /* and our interrupt handler chain */ struct intrhand *ih; /* and our interrupt handler chain */
struct thread *td; struct thread *td;
struct proc *p; struct proc *p;
int count, warned; int count, warned, storming;
td = curthread; td = curthread;
p = td->td_proc; p = td->td_proc;
@ -494,6 +494,7 @@ ithread_loop(void *arg)
("%s: ithread and proc linkage out of sync", __func__)); ("%s: ithread and proc linkage out of sync", __func__));
count = 0; count = 0;
warned = 0; warned = 0;
storming = 0;
/* /*
* As long as we have interrupts outstanding, go through the * As long as we have interrupts outstanding, go through the
@ -549,10 +550,26 @@ ithread_loop(void *arg)
} }
/* /*
* If we detect an interrupt storm, pause with the * Interrupt storm handling:
* source masked until the next hardclock tick. *
* 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) { count >= intr_storm_threshold) {
if (!warned) { if (!warned) {
printf( printf(
@ -560,7 +577,7 @@ ithread_loop(void *arg)
p->p_comm); p->p_comm);
warned = 1; warned = 1;
} }
tsleep(&count, td->td_priority, "istorm", 1); storming = 1;
count = 0; count = 0;
} else } else
count++; count++;
@ -580,6 +597,7 @@ ithread_loop(void *arg)
if (!ithd->it_need) { if (!ithd->it_need) {
TD_SET_IWAIT(td); TD_SET_IWAIT(td);
count = 0; count = 0;
storming = 0;
CTR2(KTR_INTR, "%s: pid %d: done", __func__, p->p_pid); CTR2(KTR_INTR, "%s: pid %d: done", __func__, p->p_pid);
mi_switch(SW_VOL, NULL); mi_switch(SW_VOL, NULL);
CTR2(KTR_INTR, "%s: pid %d: resumed", __func__, p->p_pid); CTR2(KTR_INTR, "%s: pid %d: resumed", __func__, p->p_pid);