On Friday 17 July 2009 16:47:38 ext Oliver Neukum wrote: > Am Freitag, 17. Juli 2009 11:56:06 schrieb Rémi Denis-Courmont: > > + atomic_dec(&pnd->tx_queue); > > + netif_wake_queue(dev); > > Now that I think about it this seems to be a race condition. > What makes sure that your are still below the limit when you > wake the queue? The netif TX queue serializes usbpn_xmit() against itself. Then, at all times: tx_queue + !netif_queue_stopped() <= tx_queue_len (in other words either tx_queue = tx_queue_len and queue is stopped, or tx_queue < tx_queue_len). Initially: 0 + 1 <= tx_queue_len, the assertion is initially true. Recurrently: If usbpn_xmit() is called, then the queue was not stopped, so tx_queue < tx_queue_len. Then the queue is stopped. In the race free cases, either tx_queue is incremented up to the limit, and the queue remains stopped; the assertion is still valid. Alternatively tx_queue remains below limit and the queue gets woken again; the assertion is still valid. In the racy case, tx_complete() fires, incrementation in usbpn_xmit() and decrementation in tx_complete() will cancel each other. So, regardless of their respective order, tx_queue will be unchanged, and the assertion remains valid. A fortiori, it works fine if usbpn_xmit() races with more than one call of tx_complete(). The cases that tx_complete() runs while the queue is not transmitting is evident. -- Rémi Denis-Courmont Nokia Devices R&D, Maemo Software, Helsinki -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html