Re: Small example program shut down urtwn
hm, interesting! I wonder if urtwn and/or usb is missing some bus barriers for ARM or something? -a On 4 September 2016 at 14:18, Otacíliowrote: > Dears > > I wrote these two small programs to help debug a problem that I think I have > found when using urtwn driver in a baglebone black. The problem is 100% > reproducible. > > In a server machine I run: > > serverUDP 2508 > > In beaglebone black I run: > > ./clientUDP servername 2508 9216 0 > > All the times, after some packages be sent the urtwn interface do not > respond from ping and stops send others packages. Some times this error > message appears: > > % urtwn0: device timeout > > I have tested with RTL8192CU and RTL8188CUS > > The problem do no occurs in my notebook. > > Following the server and client > > #include > #include > #include > #include > #include > #include > #include > #include > > #define BUFFER_LEN1024*1024 > > void diep(char *s) > { > perror(s); > exit(1); > } > > int main(int argc, char **argv) > { > int lidos; > struct sockaddr_in si_me, si_other; > int s, i, slen=sizeof(si_other); > char buf[BUFFER_LEN]; > int aux; > > if(argc != 2){ > fprintf(stderr, "Voce deve usar %s \n", argv[0]); > exit(1); > } > > if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) > diep("socket"); > > memset((char *) _me, 0, sizeof(si_me)); > si_me.sin_family = AF_INET; > si_me.sin_port = htons(strtol(argv[1], (char **)NULL, 10)); > si_me.sin_addr.s_addr = htonl(INADDR_ANY); > if (bind(s, (struct sockaddr *)_me, sizeof(si_me))==-1) > diep("bind"); > > i = 1; > do { > if ((lidos = recvfrom(s, buf, BUFFER_LEN, 0, (struct sockaddr > *)_other, (socklen_t *)))==-1) > diep("recvfrom()"); > aux = ntohl(*(int*)[0]); > printf("Perdidos %d pacotes (%0.2f%%)\n", aux - i, 100*((float)(aux > - i))/((float)aux)); > printf("Sequencia %d Recebidos %d bytes\n", aux, lidos); > i++; > }while(lidos>0); > > close(s); > return 0; > } > > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > > #define SOCKET_ERROR-1 > #define INVALID_SOCKET-1 > > #define SRV_IP "127.0.0.1" > > void diep(char *s) > { > perror(s); > exit(1); > } > > > int main(int argc, char **argv) > { > struct sockaddr_in si_other; > int s, i, slen=sizeof(si_other); > char *buf; > int tamanho; > int npack; > struct addrinfo *result = NULL, > *ptr = NULL, > hints; > int iResult, aux; > fd_set fdset; > > if(argc != 5){ > fprintf(stderr,"Voce deve usar %s de pacotes>\n", argv[0]); > exit(1); > } > > tamanho= (int)strtol(argv[3], (char **)NULL, 10); > npack= (int)strtol(argv[4], (char **)NULL, 10); > > buf = malloc(tamanho); > > bzero(, sizeof(hints)); > hints.ai_family = AF_UNSPEC; > hints.ai_socktype = SOCK_DGRAM; > hints.ai_protocol = IPPROTO_UDP; > > iResult = getaddrinfo(argv[1], argv[2], , ); > if ( iResult != 0 ) { > printf("getaddrinfo failed with error: %d\n", iResult); > return 1; > } > > // Attempt to connect to an address until one succeeds > for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { > > // Create a SOCKET for connecting to server > s = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); > if (s < 0){ > perror("socket"); > return 1; >} > >// Connect to server. >iResult = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); >if (iResult == SOCKET_ERROR) { > close(s); > s = INVALID_SOCKET; >continue; >} > >break; > } > > freeaddrinfo(result); > FD_ZERO(); > FD_SET(s, ); > for (i=1; i<=npack || npack==0; i++) { > aux = htonl(i); > memcpy([0], , sizeof(aux)); > aux = htonl(npack); > memcpy([0+sizeof(i)], , sizeof(aux)); > do{ > if(select(s+1, NULL, , NULL, NULL )<0) > diep("select()"); > }while(!FD_ISSET(s, )); > if (send(s, buf, tamanho, 0)==-1) > diep("sendto()"); > } > printf("Enviados %d pacotes de %d bytes\n", npack, tamanho); > > close(s); > return 0; > } > ___ > 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" ___ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to
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"