tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Interrupt storm mitigation needed
On Thu, Feb 12, 2015 at 09:36:52AM +0100, Joerg Sonnenberger wrote:
> Well, let's try the first hack of keep uhci interrupts off and just poll
> via timeout.
Let's not forget the second part in the header ;)
Joerg
Index: uhci.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/dev/usb/uhci.c,v
retrieving revision 1.264
diff -u -p -r1.264 uhci.c
--- uhci.c 5 Aug 2014 06:35:24 -0000 1.264
+++ uhci.c 12 Feb 2015 08:35:26 -0000
@@ -72,6 +72,11 @@ __KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.2
/*#define UHCI_CTL_LOOP */
+Static int uhci_intr1(uhci_softc_t *);
+static void uhci_intr1_wrap(void *sc)
+{
+ uhci_intr1(sc);
+}
#ifdef UHCI_DEBUG
uhci_softc_t *thesc;
@@ -542,8 +547,11 @@ uhci_init(uhci_softc_t *sc)
DPRINTFN(1,("uhci_init: enabling\n"));
err = uhci_run(sc, 1, 0); /* and here we go... */
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
+
+ callout_init(&sc->sc_simulated_interrupt, CALLOUT_MPSAFE);
+ callout_setfunc(&sc->sc_simulated_interrupt, uhci_intr1_wrap, sc);
+ callout_schedule(&sc->sc_simulated_interrupt, 1);
+
return err;
}
@@ -720,8 +728,6 @@ uhci_resume(device_t dv, const pmf_qual_
UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */
usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_DELAY, &sc->sc_intr_lock);
UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE |
- UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE);
UHCICMD(sc, UHCI_CMD_MAXP);
uhci_run(sc, 1, 1); /* and start traffic again */
usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_RECOVERY, &sc->sc_intr_lock);
@@ -735,6 +741,7 @@ uhci_resume(device_t dv, const pmf_qual_
#endif
sc->sc_suspend = PWR_RESUME;
+ callout_schedule(&sc->sc_simulated_interrupt, 1);
mutex_spin_exit(&sc->sc_intr_lock);
return true;
@@ -1270,8 +1277,6 @@ uhci_remove_bulk(uhci_softc_t *sc, uhci_
sc->sc_bulk_end = pqh;
}
-Static int uhci_intr1(uhci_softc_t *);
-
int
uhci_intr(void *arg)
{
@@ -1290,8 +1295,6 @@ uhci_intr(void *arg)
goto done;
}
- ret = uhci_intr1(sc);
-
done:
mutex_spin_exit(&sc->sc_intr_lock);
return ret;
@@ -1313,8 +1316,10 @@ uhci_intr1(uhci_softc_t *sc)
KASSERT(mutex_owned(&sc->sc_intr_lock));
status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
- if (status == 0) /* The interrupt was not for us. */
+ if (status == 0) { /* The interrupt was not for us. */
+ callout_schedule(&sc->sc_simulated_interrupt, 1);
return (0);
+ }
if (sc->sc_suspend != PWR_RESUME) {
#ifdef DIAGNOSTIC
@@ -1322,6 +1327,7 @@ uhci_intr1(uhci_softc_t *sc)
device_xname(sc->sc_dev));
#endif
UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */
+ callout_schedule(&sc->sc_simulated_interrupt, 1);
return (0);
}
@@ -1368,6 +1374,7 @@ uhci_intr1(uhci_softc_t *sc)
DPRINTFN(15, ("%s: uhci_intr: exit\n", device_xname(sc->sc_dev)));
+ callout_schedule(&sc->sc_simulated_interrupt, 1);
return (1);
}
Index: uhcivar.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/dev/usb/uhcivar.h,v
retrieving revision 1.52
diff -u -p -r1.52 uhcivar.h
--- uhcivar.h 29 Jan 2013 00:00:15 -0000 1.52
+++ uhcivar.h 12 Feb 2015 07:06:37 -0000
@@ -136,6 +136,7 @@ typedef struct uhci_softc {
bus_space_tag_t iot;
bus_space_handle_t ioh;
bus_size_t sc_size;
+ struct callout sc_simulated_interrupt;
kmutex_t sc_lock;
kmutex_t sc_intr_lock;
Home |
Main Index |
Thread Index |
Old Index