Revert most of 1.109. Although it improved the situation on one particular
motherboard, in practice the changes resulted in many false positives for heavy network loads, etc. resulting in poor performance. Also, the motherboard referenced in the 1.109 log has other problems and simply does not seem to work with the APIC enabled even with the changes in 1.109. The correct fix for that board seems to be to not use the APIC at all. One thing kept from 1.109 is that throttled interrupts are now effectively polled on every clock tick rather than just 10 times per second. MFC after: 1 month Tested by: Shunsuke SHINOMIYA shino at fornext dot org
This commit is contained in:
parent
20f13585ef
commit
c957c14d05
@ -485,14 +485,14 @@ ithread_loop(void *arg)
|
||||
struct intrhand *ih; /* and our interrupt handler chain */
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
int count, warming, warned;
|
||||
int count, warned;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -514,7 +514,6 @@ ithread_loop(void *arg)
|
||||
|
||||
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,33 +547,13 @@ ithread_loop(void *arg)
|
||||
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.
|
||||
* If we detect an interrupt storm, pause with the
|
||||
* source masked until the next hardclock tick.
|
||||
*/
|
||||
if (count >= intr_storm_threshold) {
|
||||
if (intr_storm_threshold != 0 &&
|
||||
count >= intr_storm_threshold) {
|
||||
if (!warned) {
|
||||
printf(
|
||||
"Interrupt storm detected on \"%s\"; throttling interrupt source\n",
|
||||
@ -582,22 +561,12 @@ ithread_loop(void *arg)
|
||||
warned = 1;
|
||||
}
|
||||
tsleep(&count, td->td_priority, "istorm", 1);
|
||||
count = 0;
|
||||
} 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 +579,7 @@ ithread_loop(void *arg)
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (!ithd->it_need) {
|
||||
TD_SET_IWAIT(td);
|
||||
count = 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);
|
||||
|
Loading…
Reference in New Issue
Block a user