Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Sep 2016 11:10:34 +0200
From:      Hans Petter Selasky <hps@selasky.org>
To:        Andriy Voskoboinyk <avos@freebsd.org>, Adrian Chadd <adrian@freebsd.org>
Cc:        "freebsd-wireless@freebsd.org" <freebsd-wireless@freebsd.org>, "freebsd-usb@freebsd.org" <freebsd-usb@freebsd.org>
Subject:   Re: Deadlock between device_detach() and usbd_do_request_flags()
Message-ID:  <67777201-e078-b519-566a-7a2a29363eee@selasky.org>
In-Reply-To: <55cff8ce-6132-53ec-3419-d27286dce622@selasky.org>
References:  <op.ynaawb2n4dikkl@localhost> <4cf378ff-63e1-7cdc-6120-9578fceec20d@selasky.org> <55cff8ce-6132-53ec-3419-d27286dce622@selasky.org>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------42EA583F81AFB157F5F19237
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

Can you test the attached patch? Does it solve your issue?

--HPS

--------------42EA583F81AFB157F5F19237
Content-Type: text/x-patch;
 name="usb_fix_deadlock.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="usb_fix_deadlock.diff"

Index: sys/dev/usb/usb_device.c
===================================================================
--- sys/dev/usb/usb_device.c	(revision 304569)
+++ sys/dev/usb/usb_device.c	(working copy)
@@ -1585,6 +1585,7 @@
 	/* initialise our SX-lock */
 	sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
 	sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
+	sx_init_flags(&udev->ctrl_sx, "USB control transfer SX lock", SX_DUPOK);
 
 	cv_init(&udev->ctrlreq_cv, "WCTRL");
 	cv_init(&udev->ref_cv, "UGONE");
@@ -2195,6 +2196,7 @@
 	
 	sx_destroy(&udev->enum_sx);
 	sx_destroy(&udev->sr_sx);
+	sx_destroy(&udev->ctrl_sx);
 
 	cv_destroy(&udev->ctrlreq_cv);
 	cv_destroy(&udev->ref_cv);
Index: sys/dev/usb/usb_device.h
===================================================================
--- sys/dev/usb/usb_device.h	(revision 304569)
+++ sys/dev/usb/usb_device.h	(working copy)
@@ -183,6 +183,7 @@
 	struct usb_udev_msg cs_msg[2];
 	struct sx enum_sx;
 	struct sx sr_sx;
+  	struct sx ctrl_sx;
 	struct mtx device_mtx;
 	struct cv ctrlreq_cv;
 	struct cv ref_cv;
Index: sys/dev/usb/usb_request.c
===================================================================
--- sys/dev/usb/usb_request.c	(revision 304569)
+++ sys/dev/usb/usb_request.c	(working copy)
@@ -418,7 +418,6 @@
 	uint16_t length;
 	uint16_t temp;
 	uint16_t acttemp;
-	uint8_t do_unlock;
 
 	if (timeout < 50) {
 		/* timeout is too small */
@@ -460,16 +459,16 @@
 	}
 
 	/*
-	 * Grab the USB device enumeration SX-lock serialization is
-	 * achieved when multiple threads are involved:
+	 * Serialize access to this function:
 	 */
-	do_unlock = usbd_enum_lock(udev);
+	sx_xlock(&udev->ctrl_sx);
 
 	/*
 	 * We need to allow suspend and resume at this point, else the
 	 * control transfer will timeout if the device is suspended!
 	 */
-	usbd_sr_unlock(udev);
+	if (usbd_enum_is_locked(udev))
+		usbd_sr_unlock(udev);
 
 	hr_func = usbd_get_hr_func(udev);
 
@@ -713,10 +712,10 @@
 	USB_XFER_UNLOCK(xfer);
 
 done:
-	usbd_sr_lock(udev);
+	sx_xunlock(&udev->ctrl_sx);
 
-	if (do_unlock)
-		usbd_enum_unlock(udev);
+	if (usbd_enum_is_locked(udev))
+		usbd_sr_lock(udev);
 
 	if ((mtx != NULL) && (mtx != &Giant))
 		mtx_lock(mtx);

--------------42EA583F81AFB157F5F19237--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?67777201-e078-b519-566a-7a2a29363eee>