When attaching a USB hub (anything from a generic DLink to a keyboard with integrated hub) while a userspace libusb query is going on, the kernel panics (trap 12, fault virtual address = 0xdeadc0e6) at usbd_device_fillinfo:1350; p->device is 0xdeadc0de. I have experimented several times, I think the cause is during hub attachment, there is a tsleep when waiting for power to settle (uhub.c:288). In this time, libusb's usb_find_devices happens to request an ioctl for a device exploration. At this point, the port structures of the hub are not yet initialized. I have a temporary fix that just initializes p->device to NULL before the sleep, but this doesn't solve a similar problem exists during hub detachment (which I haven't been able to narrow it down much further). Fix: Proposed patch (only a hackish fix for the attachment problem): @@ -284,6 +284,15 @@ goto bad; } + // Fixes crash on hub attachment + // Need to init device to NULL before delay sleep; + // otherwise exploration could hit an uninit'd port + for (p = 0; p < nports; p++) { + struct usbd_port *up = &hub->ports[p]; + up->device = NULL; + } + // end changes + /* Wait with power off for a while. */ usbd_delay_ms(dev, USB_POWER_DOWN_TIME); How-To-Repeat: Run a program that continuously polls for USB devices using libusb's usb_find_devices(), while attaching a USB hub. This won't cause it to crash everytime, but it is likely that out of 20 attachments, there will be at least one panic. A piece of code along the lines of while(1){ DPRINTF(("before usb_init\n")); usb_init(); DPRINTF(("before usb_find_busses\n")); usb_find_busses(); DPRINTF(("before usb_find_devices\n")); usb_find_devices(); } should do the trick of producing something like the log.
Would you happen to know if this happens on FreeBSD -current? Warner
Thanks for the update Victor. I can't get it to happen in current. Maybe I'm doing something differently than you. Do you have an easy recipe for causing the panic? Warner
Here is the code I just used to panic it just now (requires libusb): /////////// usbtest.c: #include "/usr/local/include/usb.h" int main(int argc, char **argv){ while(1){ usb_init (); usb_find_busses (); usb_find_devices (); } return 0; } //////////// Makefile: CC=gcc LD=ld CFLAGS = -g -c -Wall all: usbtest.o $(CC) -o usbtest usbtest.o /usr/local/lib/libusb.a clean: rm -f usbtest usbtest.tgz *.o *~ It took me about 15 plug-in/unplug cycles to get it to crash (sometimes as many as 30 during previous testing when I'm unlucky). There's about a 200ms window during which the panic will occur, and it's hard to say exactly when that is. You can probably add a printf to given an indication of where in the loop you're plugging in the hub, so you can change the timing around a bit. -victor
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
Keyword: crash – in lieu of summary line prefix: [panic] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>
Keyword: patch or patch-ready – in lieu of summary line prefix: [patch] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>