|
|
发表于 2005-3-16 21:12:14
|
显示全部楼层
Re: eth0: Too much work at interrupt
Paul Gortmaker (gpg109@rsphy1.anu.edu.au)
Mon, 4 Dec 1995 12:52:08 +1100 (EST)
Messages sorted by: [ date ][ thread ][ subject ][ author ]
Next message: Alan Cox: "Re: Question..."
Previous message: Victor Hugo Velasco Esparza: "Re: My ppp is s-l-o-w"
--------------------------------------------------------------------------------
> I keep getting syslog messages like this:
>
> eth0: Too much work at interrupt, status 0x41
> eth0: Too much work at interrupt, status 0x01
>
> What can I do to fix this? Is is related to my computer, the card, or
> my local net.
All of the above :-)
> I am running 1.2.13 on a 486SX25 with an SMC Elite 16C ultra. I have
> used this card in other machines without any such errors.
They are harmless. The Ultra uses what was the RDC bit (0x40) of
NE2000 designs as an early Rx interrupt. Even though no processing
is done on an RDC interrupt, the 8390 driver still counts it as
one "work event" during that interrupt handler pass. (All the other
sh-mem 8390 cards won't ever post an RDC interrupt). This creates
an artificially high "work event" count per interrupt handler pass.
Since the interrupt handler keeps calling the Rx and Tx-done routines
while there are packets to be processed, a slower machine will have
a higher average "work event" count per interrupt handler pass.
(ie. faster machines can do the required work before more new work
arrives and thus fall out the bottom of the IRQ handler sooner.)
Ok, enough technical cruft. The proper cure is to set the early
Rx packet threshold to (max_pkt_size-1) -- Donald once mentioned
that he had done this on a development version of the driver he had.
At present smc-ultra.c doesn't initialize this register at all.
I don't have the specs to tell you where that reg. is, so until I get
in touch with Donald, here is a hack for 1.2.13 to make 8390.c not
count "RDC only" events as work.
if (interrupts & ENISR_RDC) {
- if (dev->mem_start)
- outb_p(ENISR_RDC, e8390_base + EN0_ISR);
+ outb_p(ENISR_RDC, e8390_base + EN0_ISR);
+ if (interrupts == ENISR_RDC) nr_serviced--;
}
Alternatively, you can just double the value of MAX_SERVICE in 8390.h
which will effectively do the same thing.
Clear as mud.
Paul. |
|