PERFORCE change 103113 for review

Paolo Pisati piso at FreeBSD.org
Thu Aug 3 13:22:51 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=103113

Change 103113 by piso at piso_newluxor on 2006/08/03 13:22:23

	First implementation of interrupt storm logic for filters:
	
	in case an interrupt come, and no filters claim it (and we
	don't have any ithread_only handler on that line), 
	throttle the line (mask the interrupt and mark the source) and
	kick off a timeout once per second.
	
	Timeout function (when called) will check all the interrupts:
	
	if any of these interrupt is marked, check if it is
	still pending else unmask/unmark the source. If the interrupt 
	is still pending, call filters and if any of them claim the 
	interrupt, unmask/unmark it. Else, if no filter claims the 
	interrupt, increase the timeout threshold for next check.
	
	TODO:
	-The code is still MD, but i would like to make it MI.
	
	-we need tunable timeout tresholds (upper & lower).
	
	-filters are called with a NULL frame parameter, while
	some of them expect to receive a valid trapframe...
	
	-i should call callout_drain() but i can't find a place
	where to do that: i guess we don't do cleanup in this case,
	case if we need to drain the callout, it means we are 
	shutting down the box, right? 

Affected files ...

.. //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#8 edit

Differences ...

==== //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#8 (text+ko) ====

@@ -45,6 +45,7 @@
 #include <sys/lock.h>
 #include <sys/ktr.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/syslog.h>
@@ -63,6 +64,9 @@
 static struct intsrc *interrupt_sources[NUM_IO_INTS];
 static struct mtx intr_table_lock;
 
+static struct callout callout_handle;
+static int backoff = 1;
+
 #ifdef SMP
 static int assign_cpu;
 
@@ -165,6 +169,57 @@
 	return (isrc->is_pic->pic_config_intr(isrc, trig, pol));
 }
 
+static struct intsrc *
+walk_intr_src(void) {
+	static int i = 0;
+
+	for (; i<NUM_IO_INTS; i++) {
+		if (interrupt_sources[i] != NULL)
+			return (interrupt_sources[i]);
+	}
+	i = 0;
+	return (NULL);
+}
+
+static void
+stray_detection(void *arg __unused) 
+{
+	struct intsrc *isrc;
+	struct intr_event *ie;
+	int thread;
+
+	/* analyze all the interrupt sources... */
+	while ((isrc = walk_intr_src()) != NULL) {
+		ie = isrc->is_event;
+		/* is this interrupt marked as being throttled? */
+		if (ie != NULL && ie->ie_count == INT_MAX) {
+			/* and is the interrupt still pending? */
+			if (isrc->is_pic->pic_source_pending(isrc)) {
+				/* 
+				 * yes, it's still pending: call filters...
+				 */
+				thread = intr_filter_loop(ie, NULL /* XXX frame */ );
+				if (thread & FILTER_STRAY) {
+					/* 
+					 * no filter claimed the intr, 
+					 * backoff with a longer timeout 
+					 */
+					backoff++; // XXX we need thresholds...
+					callout_reset(&callout_handle, hz*backoff, 
+						      &stray_detection, NULL);
+					continue;
+				}
+			}
+			/*
+			 * a filter claimed the intr, or the intr was not
+			 * pending anymore: unmask it
+			 */
+			ie->ie_count = 0;
+			isrc->is_pic->pic_enable_source(isrc);
+		}
+	}
+}
+
 void
 intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
 {
@@ -225,6 +280,15 @@
 		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 	critical_exit();
 
+	
+	/* Interrupt storm logic */
+	if (thread & FILTER_STRAY) {
+		ie->ie_count = INT_MAX;    
+		mtx_lock_spin(&intr_table_lock);
+		callout_reset(&callout_handle, hz, &stray_detection, NULL);
+		mtx_unlock_spin(&intr_table_lock);
+	}
+
 	/* Schedule the ithread if needed. */
 	if (thread & FILTER_SCHEDULE_THREAD) {
 		error = intr_event_schedule_thread(ie);
@@ -309,6 +373,8 @@
 	intrcnt_setname("???", 0);
 	intrcnt_index = 1;
 	mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN);
+	callout_init_mtx(&callout_handle, &intr_table_lock, 0);
+	// XXX - we don't drain the callout...
 }
 SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL)
 


More information about the p4-projects mailing list