Messages in this thread Patches in this message | | | Date | Sat, 31 Jul 2004 14:33:30 +0200 | From | Francois Romieu <> | Subject | Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) |
| |
Pasi Sjoholm <ptsjohol@cc.jyu.fi> : [interesting report] > The hardest part is to tell where the problem is but I think that > rtl8139_poll-function would be good place to start looking for the bug? > > readprofile didn't tell much.. Where to go next? I'm not so good > programmer that I could find the right place to fix..
In case it could make a difference: did you check if CONFIG_8139_OLD_RX_RESET changes the behavior or not ?
If it does not, I'd welcome a test report + log with the two attached patch applied. The first one is just a placebo but the second one could help.
Btw, you are probably right that the issue is not related to ksoftirqd at all.
-- Ueimor drivers/net/8139too.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-)
diff -puN drivers/net/8139too.c~r8139-10 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-10 2004-07-31 12:43:44.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-07-31 12:43:44.000000000 +0200 @@ -1934,6 +1934,7 @@ static int rtl8139_rx(struct net_device int received = 0; unsigned char *rx_ring = tp->rx_ring; unsigned int cur_rx = tp->cur_rx; + u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, @@ -1947,7 +1948,6 @@ static int rtl8139_rx(struct net_device unsigned int rx_size; unsigned int pkt_size; struct sk_buff *skb; - u16 status; rmb(); @@ -2024,17 +2024,17 @@ static int rtl8139_rx(struct net_device cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); + } - /* Clear out errors and receive interrupts */ - status = RTL_R16 (IntrStatus) & RxAckBits; - if (likely(status != 0)) { - if (unlikely(status & (RxFIFOOver | RxOverflow))) { - tp->stats.rx_errors++; - if (status & RxFIFOOver) - tp->stats.rx_fifo_errors++; - } - RTL_W16_F (IntrStatus, RxAckBits); + /* Clear out errors and receive interrupts */ + status = RTL_R16 (IntrStatus) & RxAckBits; + if (likely(status != 0)) { + if (unlikely(status & (RxFIFOOver | RxOverflow))) { + tp->stats.rx_errors++; + if (status & RxFIFOOver) + tp->stats.rx_fifo_errors++; } + RTL_W16_F (IntrStatus, RxAckBits); } done: _ drivers/net/8139too.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-)
diff -puN drivers/net/8139too.c~r8139-20 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-20 2004-07-31 12:44:12.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-07-31 14:20:36.000000000 +0200 @@ -593,6 +593,7 @@ struct rtl8139_private { int time_to_die; struct mii_if_info mii; unsigned int regs_len; + unsigned long fifo_copy_timeout; }; MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); @@ -1937,7 +1938,7 @@ static int rtl8139_rx(struct net_device u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," - " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, + " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); @@ -1977,6 +1978,14 @@ static int rtl8139_rx(struct net_device */ if (unlikely(rx_size == 0xfff0)) { tp->xstats.early_rx++; + if (!tp->fifo_copy_timeout) + tp->fifo_copy_timeout = jiffies + 2; + else if (time_after(jiffies, tp->fifo_copy_timeout)) { + DPRINTK ("%s: hung FIFO. Reset.", dev->name); + tp->fifo_copy_timeout = 0; + rtl8139_rx_err (rx_status, dev, tp, ioaddr); + return -1; + } goto done; } _
| |