On Sat, Aug 09, 2003 at 11:01:28AM -0400, Jeff Garzik wrote:
> Andi Kleen wrote:
> >* netif_stop_queue in hard_start_xmit is not protected against the
> >interrupt by the spinlock. That's racy, isn't it?
>
> Shouldn't be, if done right. If the interrupt runs a TX completion
> cycle, it will run the code
> if (work_done && netif_queue_stopped(dev))
> netif_wake_queue(dev)
>
> Since ->hard_start_xmit is guaranteed never to be called if the queue is
> stopped, you also guaranteed that netif_wake_queue and ->hard_start_xmit
> are mutually exclusive.
The race is
CPU0 CPU1
hard_start_xmit
release lock
TX finished interrupt
my queue is full...
clean some packets
netif_wake_queue
netif_stop_queue
The netif_wake_queue is lost. It's only deadly when clean some packets
clears the full TX ring, otherwise it will likely recover with the
next TX finished interrupt but give suboptimal performance.
Fix is to do the my queue is full -> netif_stop_queue inside the spinlock.
-Andi
|