[1476] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Re: eth0: Too much work at interrupt

daemon@ATHENA.MIT.EDU (Paul Gortmaker)
Mon Dec 4 01:04:46 1995

From: Paul Gortmaker <gpg109@rsphy1.anu.edu.au>
To: submit-linux-dev-net@ratatosk.yggdrasil.com
Date: Mon, 4 Dec 1995 12:52:08 +1100 (EST)
Cc: submit-linux-dev-kernel@ratatosk.yggdrasil.com
In-Reply-To: <Pine.LNX.3.91.951128203412.22847A-100000@parker.bio.uci.edu> from "Brooke Paul" at Nov 28, 95 08:37:22 pm

> 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.



home help back first fref pref prev next nref lref last post