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:
John Baldwin 2004-11-03 22:11:20 +00:00
parent 20f13585ef
commit c957c14d05

View File

@ -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);