Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Jan 2004 07:24:41 -0800 (PST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 46130 for review
Message-ID:  <200401291524.i0TFOfCu083148@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=46130

Change 46130 by jhb@jhb_slimer on 2004/01/29 07:23:40

	Implement simple throttling for interrupt storms.

Affected files ...

.. //depot/projects/smpng/sys/kern/kern_intr.c#40 edit

Differences ...

==== //depot/projects/smpng/sys/kern/kern_intr.c#40 (text+ko) ====

@@ -72,6 +72,11 @@
 static void	ithread_loop(void *);
 static void	start_softintr(void *);
 
+static int intr_storm_threshold = 500;
+TUNABLE_INT("hw.intr_storm_threshold", &intr_storm_threshold);
+SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RW, &intr_storm_threshold, 0,
+    "Number of consecutive interrupts before interrupt storm protection is enabled.");
+
 u_char
 ithread_priority(enum intr_type flags)
 {
@@ -488,12 +493,15 @@
 	struct intrhand *ih;		/* and our interrupt handler chain */
 	struct thread *td;
 	struct proc *p;
+	int count, warned;
 	
 	td = curthread;
 	p = td->td_proc;
 	ithd = (struct ithd *)arg;	/* point to myself */
 	KASSERT(ithd->it_td == td && td->td_ithd == ithd,
 	    ("%s: ithread and proc linkage out of sync", __func__));
+	count = 0;
+	warned = 0;
 
 	/*
 	 * As long as we have interrupts outstanding, go through the
@@ -523,6 +531,22 @@
 			 * another pass.
 			 */
 			atomic_store_rel_int(&ithd->it_need, 0);
+
+			/*
+			 * If we detect an interrupt storm, pause with the source masked
+			 * for 1/10th of a second.
+			 */
+			if (count >= intr_storm_threshold) {
+				if (!warned) {
+					printf(
+			"Interrupt storm detected on \"%s\", throttling interrupt source\n",
+					    p->p_comm);
+					warned = 1;
+				}
+				tsleep(&count, td->td_priority, "throttle", hz / 10);
+				count = 0;
+			} else
+				count++;
 restart:
 			TAILQ_FOREACH(ih, &ithd->it_handlers, ih_next) {
 				if (ithd->it_flags & IT_SOFT && !ih->ih_need)
@@ -562,6 +586,7 @@
 		mtx_lock_spin(&sched_lock);
 		if (!ithd->it_need) {
 			TD_SET_IWAIT(td);
+			count = 0;
 			CTR2(KTR_INTR, "%s: pid %d: done", __func__, p->p_pid);
 			mi_switch(SW_VOL);
 			CTR2(KTR_INTR, "%s: pid %d: resumed", __func__, p->p_pid);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200401291524.i0TFOfCu083148>