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