Driver works for a while, and then hangs silently (possible fix?)
MIchael MacDonald <[email protected]> Tue, 01 Apr 2003 15:32:26 -0500
| Newsgroups | gmane.linux.drivers.realtek.devel |
|---|---|
| Message-ID | <[email protected]> |
I have a D-Link DFE690-TXD Cardbus card based on the 8139 running as the
second ethernet adapter in a Toshiba Satellite 1415-S105 laptop with
Slackware 8.1 (kernel version 2.4.18). I built and installed the
rtl8139.c adapter and it seemed to work fine for a day or so, but then
the card stopped responding--the computer could do no input or output
over that interface. Rebooting the laptop cleared the problem.
This happened several times (the laptop was plugged in the whole time
and no power management features were turned on). The problem seemed to
be load dependent. I was able to find a load (the GNOME galaxy screen
saver directed to a remote X display) that would consistently hang the
card after a few minutes.
I set the debug=8 module option. I now got "Media selection tick"
messages from the module every minute, both before and after it hanged,
but no other message. Looking at the interface with ifconfig, it would
show no packet errors either before or after it stopped working.
However, I noticed that after the interface stopped working, the packet
receive count would continue to go up (presumably as it received packets
from other machines on that network), but the packet sent count would
stay constant.
I tried the rtl8139-diag program. I noticed that when the card was
"hung", it continued to cycle through its receive buffer address space,
but that its send buffer registers stayed constant.
At this point I tried poking around in the rtl8139.c source code. It
seemed as though that it should be invariant that if
netif_queue_paused(dev) was true, the send queue should be full. So I
put the following test in the rtl8139_timer function:
if (netif_queue_paused(dev) && np->cur_tx - (volatile unsigned
int)np->dirty_tx < NUM_TX_DESC) {
if ( netif_queue_paused(dev))
rtl8129_tx_timeout(dev);
}
(where I test netif_queue_paused twice to avoid a race condition)
When I tried this version of the driver, sure enough after the card
hanged, at the next "Media selection tick" interval, the module reported
a transmit time out and reset the transmit queue. However, this did not
unhang the card! It would report the transmit time out again every
timer interval, and seem to reset the chip, but the interface remained
hanged.
After further poking around in the driver source, I guessed that it
might be a good idea to call netif_resume_tx_queue instead of
netif_unpause_tx_queue (which is a NOOP on 2.4+ kernels) at the end of
the rtl8129_tx_timeout function. I made this change. Now, when the
card becomes hanged, at the next timer interval, the test I inserted
detects the condition and the rtl8129_tx_timeout function successfully
gets the card going again.
OK, this makes the card usable again, since I can put up with the
very-occasional x-second delay before the card resets. However, perhaps
there is a better way to keep the problem I am detecting from arising in
the first place?