Re: usb xfer timeout issue

2010-10-18 Thread Kevin Chadwick
On Sun, 17 Oct 2010 23:01:01 +
Jacob Meuser jake...@sdf.lonestar.org wrote:

 unless someone sees a problem, or has a better solution, I think this
 should go in soon.

Xfer and bb_reset rings bells with some panics I had. If/when this goes
in and I find time I'll try all the devices I've had problems with
(different devices, different releases, I think, weird, certain usbs
always fine) and see if I can get a panic/lock-up.

Many Thanks for all the usb work



usb xfer timeout issue

2010-10-17 Thread Jacob Meuser
when a usb transfer (xfer) is started, the underlying hci driver
adds a timeout that adds a usb task that aborts the xfer.

if an xfer is synchronous, the upper usb layer sleeps waiting for
the xfer to complete.  it will also be woken up by the above mentioned
abort task if the xfer times out.

but what happens if a synchronous xfer run in the task thread stalls?
it can't be aborted by the abort task, because that won't run until
after the xfer wakes up!

I'm pretty sure this is what's causing the boot hangs in PR 6491 and
the one reported on m...@.

afaics, this issue is not new, but now that we're using the task
thread for attach/detach, we're more likely to hit it.

the patch below solves the issue by running another task thread that
is to be used ONLY for abort tasks.  I first looked at making the
upper usb layer timeout on it's own, but that's not possible without
major redesign.  I also thought about making the abort tasks workq
tasks, but that doesn't work because there is more than one way to
abort an xfer, and we may need to abort the abort task.  workqs have
no way to remove tasks from the queue but this is possible with
usb tasks.

it's not terribly easy to trigger an xfer timeout, but I did get at
least two, and things did recover.

unless someone sees a problem, or has a better solution, I think this
should go in soon.

yes, I had to hit each driver that uses usb tasks, but I think it's
also better to be explicit, now that we have 3 different types of
usb tasks ...

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: ehci.c
===
RCS file: /cvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.112
diff -u -p ehci.c
--- ehci.c  29 Sep 2010 20:06:38 -  1.112
+++ ehci.c  17 Oct 2010 22:12:50 -
@@ -1221,7 +1221,7 @@ ehci_allocx(struct usbd_bus *bus)
if (xfer != NULL) {
memset(xfer, 0, sizeof(struct ehci_xfer));
usb_init_task(EXFER(xfer)-abort_task, ehci_timeout_task,
-   xfer);
+   xfer, USB_TASK_TYPE_ABORT);
EXFER(xfer)-ehci_xfer_flags = 0;
 #ifdef DIAGNOSTIC
EXFER(xfer)-isdone = 1;
Index: if_atu.c
===
RCS file: /cvs/src/sys/dev/usb/if_atu.c,v
retrieving revision 1.94
diff -u -p if_atu.c
--- if_atu.c21 Nov 2009 14:18:34 -  1.94
+++ if_atu.c17 Oct 2010 22:12:51 -
@@ -1467,7 +1467,7 @@ atu_complete_attach(struct atu_softc *sc)
/* setup ifmedia interface */
ieee80211_media_init(ifp, atu_media_change, atu_media_status);
 
-   usb_init_task(sc-sc_task, atu_task, sc);
+   usb_init_task(sc-sc_task, atu_task, sc, USB_TASK_TYPE_GENERIC);
 
 #if NBPFILTER  0
bpfattach(sc-sc_radiobpf, sc-sc_ic.ic_if, DLT_IEEE802_11_RADIO,
Index: if_aue.c
===
RCS file: /cvs/src/sys/dev/usb/if_aue.c,v
retrieving revision 1.79
diff -u -p if_aue.c
--- if_aue.c24 Sep 2010 08:33:58 -  1.79
+++ if_aue.c17 Oct 2010 22:12:51 -
@@ -734,8 +734,10 @@ aue_attach(struct device *parent, struct device *self,
return;
}
 
-   usb_init_task(sc-aue_tick_task, aue_tick_task, sc);
-   usb_init_task(sc-aue_stop_task, (void (*)(void *))aue_stop, sc);
+   usb_init_task(sc-aue_tick_task, aue_tick_task, sc,
+   USB_TASK_TYPE_GENERIC);
+   usb_init_task(sc-aue_stop_task, (void (*)(void *))aue_stop, sc,
+   USB_TASK_TYPE_GENERIC);
rw_init(sc-aue_mii_lock, auemii);
 
err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, iface);
Index: if_axe.c
===
RCS file: /cvs/src/sys/dev/usb/if_axe.c,v
retrieving revision 1.99
diff -u -p if_axe.c
--- if_axe.c24 Sep 2010 03:21:21 -  1.99
+++ if_axe.c17 Oct 2010 22:12:51 -
@@ -676,9 +676,11 @@ axe_attach(struct device *parent, struct device *self,
 
sc-axe_flags = axe_lookup(uaa-vendor, uaa-product)-axe_flags;
 
-   usb_init_task(sc-axe_tick_task, axe_tick_task, sc);
+   usb_init_task(sc-axe_tick_task, axe_tick_task, sc,
+   USB_TASK_TYPE_GENERIC);
rw_init(sc-axe_mii_lock, axemii);
-   usb_init_task(sc-axe_stop_task, (void (*)(void *))axe_stop, sc);
+   usb_init_task(sc-axe_stop_task, (void (*)(void *))axe_stop, sc,
+   USB_TASK_TYPE_GENERIC);
 
err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, sc-axe_iface);
if (err) {
Index: if_cue.c
===
RCS file: /cvs/src/sys/dev/usb/if_cue.c,v
retrieving revision 1.53
diff -u -p if_cue.c
--- if_cue.c24 Sep 2010 08:33:58 -  1.53
+++ if_cue.c17 Oct 2010 22:12:51 -
@@ -470,8 +470,10 @@ cue_attach(struct device *parent, struct device *self,
sc-cue_product =