[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/