[realtek] transmit timeout revisited
Charl P. Botha
c.p.botha@its.tudelft.nl
Mon, 27 Nov 2000 17:50:40 +0100
Sean,
Thanks for the prompt reply!
On Mon, Nov 27, 2000 at 11:30:08AM -0500, Sean MacLennan wrote:
> if ((atomic_read (&tp->cur_tx) - atomic_read (&tp->dirty_tx)) >= NUM_TX_DESC)
> netif_stop_queue (dev);
>
> What happens is that the if returns true, but by the time the
> netif_stop_queue is called, the tx handler has written out the
> buffers. This means everything hangs for 6 seconds until the stack
> calls the tx_timeout routine.
>
> I am using the following hack. If you have a better solution, let me
> know.
>
> if ((atomic_read (&tp->cur_tx) - atomic_read (&tp->dirty_tx)) >= NUM_TX_DESC) {
> netif_stop_queue (dev);
> if (atomic_read (&tp->cur_tx) == atomic_read (&tp->dirty_tx) &&
> netif_queue_stopped(dev))
> netif_wake_queue(dev);
> }
>
> If you have any questions (or the above code got mangled) let me know.
As far as I can make out, this race condition IS handled in v1.12 of Donald
Becker's rtl8139.c. I quote from line 979:
/* There is a race condition here -- we might read dirty_tx, take an
interrupt that clears the Tx queue, and only then set tx_full.
So we do this in two phases. */
if (++tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) /* Typical path */
clear_bit(0, (void*)&dev->tbusy);
else {
set_bit(0, &tp->tx_full);
if (tp->cur_tx - (volatile int)tp->dirty_tx < NUM_TX_DESC) {
clear_bit(0, (void*)&dev->tbusy);
clear_bit(0, &tp->tx_full);
}
}
(note that Donald's else clause corresponds to Jeff's if)
In anycase, I can't test the 8139too.c, because there aren't any backports
of the latest driver (and I believe there are some bugs in the version that
have been backported) to 2.2.x.
Any other race conditions that you know of? :)
Thanks again!
Charl
--
charl p. botha | computer graphics and cad/cam
http://cpbotha.net/ | http://www.cg.its.tudelft.nl/