FAST Interrupt patch for usb
M. Warner Losh
imp at bsdimp.com
Fri Nov 12 07:40:30 PST 2004
Here's a patch that make the usb subsystem use fast interrupts and
taskqueues. The usb system already allows for soft interrupts, but
this appears to be a little better. I've not done a 4.x port, nor
even bothered with supporting it. Others are welcome to tweak that
part of things. I've been running these patches for a couple of
months now. This should help people that have usb and network shared.
Comments?
Warner
-------------- next part --------------
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/ehci_pci.c /shadow/imp/p4/newcard/src/sys/dev/usb/ehci_pci.c
--- /shadow/imp/p4/src/sys/dev/usb/ehci_pci.c Sat Nov 6 12:30:30 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/ehci_pci.c Sat Nov 6 12:18:29 2004
@@ -282,7 +282,7 @@
sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
}
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
+ err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
(driver_intr_t *) ehci_intr, sc, &sc->ih);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/ehcivar.h /shadow/imp/p4/newcard/src/sys/dev/usb/ehcivar.h
--- /shadow/imp/p4/src/sys/dev/usb/ehcivar.h Sat Nov 6 12:30:30 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/ehcivar.h Sat Nov 6 12:18:30 2004
@@ -145,8 +145,9 @@
usb_callout_t sc_tmo_pcd;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
device_ptr_t sc_child; /* /dev/usb# device */
-
+#endif
char sc_dying;
} ehci_softc_t;
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/ohci_pci.c /shadow/imp/p4/newcard/src/sys/dev/usb/ohci_pci.c
--- /shadow/imp/p4/src/sys/dev/usb/ohci_pci.c Sat Nov 6 12:30:30 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/ohci_pci.c Sat Nov 6 12:18:30 2004
@@ -281,7 +281,7 @@
sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
}
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
+ err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
(driver_intr_t *) ohci_intr, sc, &sc->ih);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/ohcivar.h /shadow/imp/p4/newcard/src/sys/dev/usb/ohcivar.h
--- /shadow/imp/p4/src/sys/dev/usb/ohcivar.h Sat Nov 6 12:30:30 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/ohcivar.h Sat Nov 6 12:18:30 2004
@@ -147,7 +147,9 @@
usb_callout_t sc_tmo_rhsc;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
device_ptr_t sc_child;
+#endif
char sc_dying;
} ohci_softc_t;
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/uhci_pci.c /shadow/imp/p4/newcard/src/sys/dev/usb/uhci_pci.c
--- /shadow/imp/p4/src/sys/dev/usb/uhci_pci.c Sat Nov 6 12:30:31 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/uhci_pci.c Sat Nov 6 12:18:30 2004
@@ -327,7 +327,7 @@
break;
}
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
+ err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
(driver_intr_t *) uhci_intr, sc, &sc->ih);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/uhcivar.h /shadow/imp/p4/newcard/src/sys/dev/usb/uhcivar.h
--- /shadow/imp/p4/src/sys/dev/usb/uhcivar.h Sat Nov 6 12:30:31 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/uhcivar.h Sat Nov 6 12:18:30 2004
@@ -193,7 +193,9 @@
void *sc_shutdownhook; /* cookie from shutdown hook */
#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__)
device_ptr_t sc_child; /* /dev/usb# device */
+#endif
} uhci_softc_t;
usbd_status uhci_init(uhci_softc_t *);
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/usb.c /shadow/imp/p4/newcard/src/sys/dev/usb/usb.c
--- /shadow/imp/p4/src/sys/dev/usb/usb.c Sat Nov 6 12:30:32 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/usb.c Sat Nov 6 12:18:31 2004
@@ -213,6 +213,17 @@
return (UMATCH_GENERIC);
}
+#if defined(USB_USE_SOFTINTR) && defined(__HAVE_TASKQUEUE)
+static void
+usb_taskqueue_fn(void *argp, int pending)
+{
+ mtx_lock(&Giant);
+ usbd_bus_handle bus = argp;
+ bus->methods->soft_intr(bus);
+ mtx_unlock(&Giant);
+}
+#endif
+
USB_ATTACH(usb)
{
#if defined(__NetBSD__) || defined(__OpenBSD__)
@@ -264,6 +275,9 @@
usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
#ifdef USB_USE_SOFTINTR
+#ifdef __HAVE_TASKQUEUE
+ TASK_INIT(&sc->sc_bus->task, 0, usb_taskqueue_fn, sc->sc_bus);
+#else
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
/* XXX we should have our own level */
sc->sc_bus->soft = softintr_establish(IPL_SOFTNET,
@@ -277,6 +291,7 @@
usb_callout_init(sc->sc_bus->softi);
#endif
#endif
+#endif
err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, speed, 0,
&sc->sc_port);
@@ -745,7 +760,7 @@
void
usb_needs_explore(usbd_device_handle dev)
{
- DPRINTFN(2,("usb_needs_explore\n"));
+ printf("usb_needs_explore\n");
dev->bus->needs_explore = 1;
wakeup(&dev->bus->needs_explore);
}
@@ -847,6 +862,9 @@
if (bus->use_polling) {
bus->methods->soft_intr(bus);
} else {
+#ifdef __HAVE_TASKQUEUE
+ taskqueue_enqueue(taskqueue_thread, &bus->task);
+#else
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
softintr_schedule(bus->soft);
#else
@@ -854,6 +872,7 @@
callout_reset(&bus->softi, 0, bus->methods->soft_intr,
bus);
#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
+#endif
}
#else
bus->methods->soft_intr(bus);
@@ -920,6 +939,9 @@
usbd_finish();
#ifdef USB_USE_SOFTINTR
+#ifdef __HAVE_TASKQUEUE
+ /* XXX should disestablish this task item */
+#else
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
if (sc->sc_bus->soft != NULL) {
softintr_disestablish(sc->sc_bus->soft);
@@ -927,6 +949,7 @@
}
#else
callout_stop(&sc->sc_bus->softi);
+#endif
#endif
#endif
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/usb_port.h /shadow/imp/p4/newcard/src/sys/dev/usb/usb_port.h
--- /shadow/imp/p4/src/sys/dev/usb/usb_port.h Tue Nov 9 17:09:39 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/usb_port.h Tue Nov 9 17:09:31 2004
@@ -346,10 +346,9 @@
#define USBVERBOSE
-/* We don't use the soft interrupt code in FreeBSD. */
-#if 0
#define USB_USE_SOFTINTR
-#endif
+#define __HAVE_TASKQUEUE
+#include <sys/taskqueue.h>
#define Static static
@@ -525,7 +524,6 @@
SYSCTL_DECL(_hw_usb);
#endif
-#endif /* __FreeBSD__ */
+#endif /* FreeBSD */
#endif /* _USB_PORT_H */
-
diff --exclude CVS -I\$Revision -I\$Id -I\$Header -I \$FreeBSD -ur /shadow/imp/p4/src/sys/dev/usb/usbdivar.h /shadow/imp/p4/newcard/src/sys/dev/usb/usbdivar.h
--- /shadow/imp/p4/src/sys/dev/usb/usbdivar.h Sat Nov 6 12:30:32 2004
+++ /shadow/imp/p4/newcard/src/sys/dev/usb/usbdivar.h Sat Nov 6 12:18:31 2004
@@ -122,10 +122,14 @@
#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" }
#ifdef USB_USE_SOFTINTR
+#ifdef __HAVE_TASKQUEUE
+ struct task task;
+#else
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
void *soft; /* soft interrupt cookie */
#else
struct callout softi;
+#endif
#endif
#endif
More information about the freebsd-usb
mailing list