Re: Deadlock between device_detach() and usbd_do_request_flags()
On 09/05/16 12:21, Andriy Voskoboinyk wrote: Mon, 05 Sep 2016 12:10:34 +0300 було написано Hans Petter Selasky: Works fine, thanks! P.S. Reliable test case: 1) ifconfig wlan1 create wlandev 2) wpa_supplicant -i wlan1 -c /etc/wpa_supplicant.conf & * wait for CTRL-EVENT-CONNECTED event 3) usbconfig -d . power_off Hi, Can you test the attached patch? Does it solve your issue? --HPS FYI: https://svnweb.freebsd.org/changeset/base/305421 --HPS ___ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"
Re: Deadlock between device_detach() and usbd_do_request_flags()
Mon, 05 Sep 2016 12:10:34 +0300 було написано Hans Petter Selasky: Works fine, thanks! P.S. Reliable test case: 1) ifconfig wlan1 create wlandev 2) wpa_supplicant -i wlan1 -c /etc/wpa_supplicant.conf & * wait for CTRL-EVENT-CONNECTED event 3) usbconfig -d . power_off Hi, Can you test the attached patch? Does it solve your issue? --HPS ___ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"
Re: Deadlock between device_detach() and usbd_do_request_flags()
Hi, Can you test the attached patch? Does it solve your issue? --HPS 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(>enum_sx, "USB config SX lock", SX_DUPOK); sx_init_flags(>sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS); + sx_init_flags(>ctrl_sx, "USB control transfer SX lock", SX_DUPOK); cv_init(>ctrlreq_cv, "WCTRL"); cv_init(>ref_cv, "UGONE"); @@ -2195,6 +2196,7 @@ sx_destroy(>enum_sx); sx_destroy(>sr_sx); + sx_destroy(>ctrl_sx); cv_destroy(>ctrlreq_cv); cv_destroy(>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(>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(>ctrl_sx); - if (do_unlock) - usbd_enum_unlock(udev); + if (usbd_enum_is_locked(udev)) + usbd_sr_lock(udev); if ((mtx != NULL) && (mtx != )) mtx_lock(mtx); ___ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"
Re: Deadlock between device_detach() and usbd_do_request_flags()
On 09/05/16 09:53, Hans Petter Selasky wrote: Hi, I think the right solution is to let usbd_do_request_flags() use its own SX lock for synchronization, instead of re-using the enumeration SX lock. What do you think about that? --HPS Hi, Another approach which will work is to setup your own USB control endpoint xfer, and use that. I'll have a look and see what can be done. --HPS ___ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"
Re: Deadlock between device_detach() and usbd_do_request_flags()
On 09/04/16 23:20, Andriy Voskoboinyk wrote: There is a rare, but reproducible deadlock for wlan(4) drivers: Thread 1: * uhub_explore_handle_re_enumerate() (obtains enum_sx lock) * usbd_set_config_index() * usb_unconfigure() * usb_detach_device() * usb_detach_device_sub() *typically is executed here (prevents another possible deadlock?) * ieee80211_ifdetach() * ieee80211_vap_destroy() * ic_vap_delete> * ieee80211_vap_detach() here it calls ieee80211_stop() and waits for -> INIT state transition Thread 2 (started from thread 1): * ieee80211_newstate_cb() * vap->iv_newstate() here: if the driver will try to call usbd_do_request_flags() (typically via / ) it will hang (because enum_sx lock is already held by thread 1). Another way: execute some periodical task that will try to access some registers (urtwn_temp_calib(), rum_ratectl_task(), run_ratectl_cb()) while thread 1 is running - deadlock is here too, since will wait for them indefinitely (via ieee80211_draintask()) Right now the most obvious (and, probably, wrong) way is to just detect & release all locks (usbd_enum_unlock()) for ieee80211_ifdetach() / ieee80211_draintask() and re-acquire them later (not tested yet). Hi, I think the right solution is to let usbd_do_request_flags() use its own SX lock for synchronization, instead of re-using the enumeration SX lock. What do you think about that? --HPS ___ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"