Hi David,

I'm currently working on fixing possible disconnect races in a USB-WLAN driver, and to start with I'm trying to convince myself that such races don't exist in other USB networking drivers (and why).

I had a quick look at usbnet, and decided that one such possible race could occur if usbnet_start_xmit() is in progress while the user yanks out the device. That particular function uses the usbnet struct for that device, which is stored inside the net_device struct, which is freed during disconnect().

The most sensible approach to fixing this is to ensure that all current transmissions have completed before freeing the structures. And it looks like someone might have tried to implement this: disconnect() implicitly calls usbnet_stop(), which calls netif_stop_queue().

However, netif_stop_queue() may return with transmissions still running on other CPUs - I think netif_tx_disable() is what is needed, which guarantees that no transmissions are active when it returns.

Do you agree that this is a potential race?

Signed-off-by: Daniel Drake <[EMAIL PROTECTED]>
Index: linux/drivers/usb/net/usbnet.c
===================================================================
--- linux.orig/drivers/usb/net/usbnet.c
+++ linux/drivers/usb/net/usbnet.c
@@ -534,7 +534,7 @@ static int usbnet_stop (struct net_devic
 	DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
 	DECLARE_WAITQUEUE (wait, current);
 
-	netif_stop_queue (net);
+	netif_tx_disable (net);
 
 	if (netif_msg_ifdown (dev))
 		devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to