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:
parent
ca298e5594
commit
a51dae09ec
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137775
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user