PERFORCE change 111521 for review

Paolo Pisati piso at FreeBSD.org
Mon Dec 11 17:47:02 PST 2006


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

Change 111521 by piso at piso_newluxor on 2006/12/12 01:43:55

	Turn the main MD interrupt handling function
	(i.e. for i386 intr_machdep.c::intr_execute_handlers()) 
	into MI code (kern_intr.c::mi_handle_intr()).
	
	Compiles for: amd64, i386, ia64, powerpc, sparc64.
	Tested on: i386.
	MIA: arm and sun4v.

Affected files ...

.. //depot/projects/soc2006/intr_filter/amd64/amd64/intr_machdep.c#11 edit
.. //depot/projects/soc2006/intr_filter/arm/arm/intr.c#8 edit
.. //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#17 edit
.. //depot/projects/soc2006/intr_filter/ia64/ia64/interrupt.c#10 edit
.. //depot/projects/soc2006/intr_filter/kern/kern_intr.c#19 edit
.. //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#13 edit
.. //depot/projects/soc2006/intr_filter/sparc64/sparc64/intr_machdep.c#11 edit
.. //depot/projects/soc2006/intr_filter/sys/interrupt.h#8 edit

Differences ...

==== //depot/projects/soc2006/intr_filter/amd64/amd64/intr_machdep.c#11 (text+ko) ====

@@ -76,6 +76,10 @@
 
 extern struct callout stray_callout_handle;
 
+static void intr_eoi_src(void *arg);
+static void intr_disab_eoi_src(void *arg);
+void intr_callout_reset(void);
+
 #ifdef SMP
 static int assign_cpu;
 
@@ -234,11 +238,20 @@
 }
 
 void
+intr_callout_reset(void)
+{
+
+	mtx_lock_spin(&intr_table_lock);
+	callout_reset(&stray_callout_handle, hz, &stray_detection, &walk_intr_src);
+	mtx_unlock_spin(&intr_table_lock);	
+}
+
+void
 intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
 {
 	struct thread *td;
 	struct intr_event *ie;
-	int error, vector, thread;
+	int res, vector;
 
 	td = curthread;
 
@@ -261,11 +274,20 @@
 	if (vector == 0)
 		clkintr_pending = 1;
 
-	/*
-	 * For stray interrupts, mask and EOI the source, bump the
-	 * stray count, and log the condition.
-	 */
-	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers)) {
+	res = mi_handle_intr(ie, frame, intr_eoi_src, intr_disab_eoi_src, isrc);
+	switch(res) {
+	case 0:
+		/* FALLTHROUGH */
+	case ECHILD:
+		break;
+	case EFAULT:
+		panic("Bad stray interrupt\n");
+		break;		
+	case EINVAL:
+		/*
+		 * For stray interrupts, mask and EOI the source, bump the
+		 * stray count, and log the condition.
+		 */
 		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 		(*isrc->is_straycount)++;
 		if (*isrc->is_straycount < MAX_STRAY_LOG)
@@ -274,47 +296,29 @@
 			log(LOG_CRIT,
 			    "too many stray irq %d's: not logging anymore\n",
 			    vector);
-		return;
+		break;
+	default:
+		printf("Ouch! Return code from mi_handle_intr()"
+		       "not expected.\n");
 	}
+}
 
-	/*
-	 * Execute fast interrupt handlers directly.
-	 * To support clock handlers, if a handler registers
-	 * with a NULL argument, then we pass it a pointer to
-	 * a trapframe as its argument.
-	 */
-	td->td_intr_nesting_level++;
-	thread = 0;
-	critical_enter();
-	thread = intr_filter_loop(ie, frame);
+static void
+intr_eoi_src(void *arg)
+{
+	struct intsrc *isrc;
 
-	/*
-	 * If the interrupt was fully served, send it an EOI but leave it 
-	 * unmasked. Otherwise, if there are any threaded handlers that need 
-	 * to run or it was a stray interrupt, mask the source as well as 
-	 * sending it an EOI.
-	 */
-	if (thread & FILTER_HANDLED)
-		isrc->is_pic->pic_eoi_source(isrc);		
-	else
-		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);	
-	critical_exit();
+	isrc = arg;
+	isrc->is_pic->pic_eoi_source(isrc);
+}
 
-	/* Interrupt storm logic */
-	if (thread & FILTER_STRAY) {
-		printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name);
-		ie->ie_count = INT_MAX;    
-		mtx_lock_spin(&intr_table_lock);
-		callout_reset(&stray_callout_handle, hz, &stray_detection, &walk_intr_src);
-		mtx_unlock_spin(&intr_table_lock);
-	}
+static void
+intr_disab_eoi_src(void *arg)
+{
+	struct intsrc *isrc;
 
-	/* Schedule the ithread if needed. */
-	if (thread & FILTER_SCHEDULE_THREAD) {
-		error = intr_event_schedule_thread(ie);
-		KASSERT(error == 0, ("bad stray interrupt"));
-	}
-	td->td_intr_nesting_level--;
+	isrc = arg;
+	isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 }
 
 void

==== //depot/projects/soc2006/intr_filter/arm/arm/intr.c#8 (text+ko) ====

@@ -102,11 +102,11 @@
 
 /* Stray detection MD code */
 static struct intr_event *
-walk_intr_events(void) {
+walk_intrs_events(void) {
 	struct intr_event *ie;
 	static int i = 0;
 
-	for (; i<NIRQ; ) {
+	for (; i < NIRQ; ) {
 		int j = i++;
 		ie = intr_events[j];
 		if (ie != NULL)
@@ -121,39 +121,37 @@
 {
 	struct intr_event *event;
 	struct thread *td = curthread;
-	int i, thread;
+	int i, thread, res;
 
 	PCPU_LAZY_INC(cnt.v_intr);
-	td->td_intr_nesting_level++;
 	while ((i = arm_get_next_irq()) != -1) {
 		arm_mask_irq(i);
 		intrcnt[intrcnt_tab[i]]++;
 		event = intr_events[i];
-		if (!event || TAILQ_EMPTY(&event->ie_handlers))
-			continue;
-
-		/* Execute fast handlers. */
-		thread = intr_filter_loop(event, frame);
-
-		/* Interrupt storm logic */
-		if (thread & FILTER_STRAY) {
-			if (event->ie_enable == NULL || event->ie_pending == NULL)
-				printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n");
-			else {
-				printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", event->ie_name);
-				event->ie_count = INT_MAX;    
-				// XXX missing callout_init_mtx(&stray_callout_handle, ...);
-				callout_reset(&stray_callout_handle, hz, 
-					      &stray_detection, &walk_intr_events);
-			}
-		}
-
-		// XXX eoi & mask intr not verified.
-		/* Schedule thread if needed. */
-		if (thread & FILTER_SCHEDULE_THREAD)
-			intr_event_schedule_thread(event);
-		else
+		res = mi_handle_intr(event, frame, intr_eoi_src_stub, 
+				     intr_disab_eoi_src_stub, NULL);
+		switch (res) {
+		case 0:
+			break;
+		case ECHILD:
 			arm_unmask_irq(i);
+			break;
+		case EFAULT:
+			/* FALLTHROUGH */
+		case EINVAL:
+			break;
+		default:
+			printf("Ouch! Return code from mi_handle_intr()"
+			       "not expected.\n");
+		}			       
 	}
-	td->td_intr_nesting_level--;
+}
+
+void
+intr_callout_reset(void) 
+{
+	
+	// XXX missing callout_init_mtx(&stray_callout_handle, ...);
+	callout_reset(&stray_callout_handle, hz, 
+		      &stray_detection, &walk_intrs_events);
 }

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

@@ -67,6 +67,10 @@
 
 extern struct callout stray_callout_handle;
 
+static void intr_eoi_src(void *arg);
+static void intr_disab_eoi_src(void *arg);
+void intr_callout_reset(void);
+
 #ifdef SMP
 static int assign_cpu;
 
@@ -216,11 +220,11 @@
 
 /* Stray detection MD code */
 static struct intr_event *
-walk_intr_src(void) {
+walk_intrs_src(void) {
 	struct intsrc *isrc;
 	static int i = 0;
 
-	for (; i<NUM_IO_INTS; ) {
+	for (; i < NUM_IO_INTS; ) {
 		int j = i++;
 		isrc = interrupt_sources[j];
 		if (isrc != NULL && isrc->is_event != NULL)
@@ -235,8 +239,7 @@
 {
 	struct thread *td;
 	struct intr_event *ie;
-	struct intr_thread *ithd = NULL;
-	int error, vector, thread;
+	int res, vector;
 
 	td = curthread;
 
@@ -259,11 +262,20 @@
 	if (vector == 0)
 		clkintr_pending = 1;
 
-	/*
-	 * For stray interrupts, mask and EOI the source, bump the
-	 * stray count, and log the condition.
-	 */
-	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers)) {
+	res = mi_handle_intr(ie, frame, intr_eoi_src, intr_disab_eoi_src, isrc);
+	switch(res) {
+	case 0:
+		/* FALLTHROUGH */
+	case ECHILD:
+		break;
+	case EFAULT:
+		panic("Bad stray interrupt\n");
+		break;		
+	case EINVAL:
+		/*
+		 * For stray interrupts, mask and EOI the source, bump the
+		 * stray count, and log the condition.
+		 */
 		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 		(*isrc->is_straycount)++;
 		if (*isrc->is_straycount < MAX_STRAY_LOG)
@@ -272,40 +284,39 @@
 			log(LOG_CRIT,
 			    "too many stray irq %d's: not logging anymore\n",
 			    vector);
-		return;
+		break;
+	default:
+		printf("Ouch! Return code from mi_handle_intr()"
+		       "not expected.\n");
 	}
+}
+
+void
+intr_callout_reset(void)
+{
+
+	mtx_lock_spin(&intr_table_lock);
+	callout_reset(&stray_callout_handle, hz, 
+		      &stray_detection, &walk_intrs_src);
+	mtx_unlock_spin(&intr_table_lock);
+}
 
-	td->td_intr_nesting_level++;
-	thread = 0;
-	critical_enter();
-	thread = intr_filter_loop(ie, frame, &ithd);
-	
-	/*
-	 * If the interrupt was fully served, send it an EOI but leave it 
-	 * unmasked. Otherwise, if it was a stray interrupt, mask the source 
-	 * as well as sending it an EOI.
-	 */
-	if (thread & FILTER_HANDLED)
-		isrc->is_pic->pic_eoi_source(isrc);		
-	else
-		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
-	critical_exit();
-	
-	/* Interrupt storm logic */
-	if (thread & FILTER_STRAY) {
-		printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name);
-		ie->ie_count = INT_MAX;    
-		mtx_lock_spin(&intr_table_lock);
-		callout_reset(&stray_callout_handle, hz, &stray_detection, &walk_intr_src);
-		mtx_unlock_spin(&intr_table_lock);
-	}
+static void
+intr_eoi_src(void *arg)
+{
+	struct intsrc *isrc;
+
+	isrc = arg;
+	isrc->is_pic->pic_eoi_source(isrc);
+}
+
+static void
+intr_disab_eoi_src(void *arg)
+{
+	struct intsrc *isrc;
 
-	/* Schedule an ithread if needed. */
-	if (thread & FILTER_SCHEDULE_THREAD) {
-		error = intr_event_schedule_thread(ie, ithd);
-		KASSERT(error == 0, ("bad stray interrupt"));
-	}
-	td->td_intr_nesting_level--;
+	isrc = arg;
+	isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 }
 
 void

==== //depot/projects/soc2006/intr_filter/ia64/ia64/interrupt.c#10 (text+ko) ====

@@ -262,6 +262,8 @@
 
 extern struct callout stray_callout_handle;
 
+void intr_callout_reset(void);
+
 extern struct sapic *ia64_sapics[];
 extern int ia64_sapic_count;
 
@@ -358,7 +360,7 @@
 	struct ia64_intr *ia64_i;
 	static int i = 0;
 
-	for (; i<IA64_NUMI; ) {
+	for (; i < IA64_NUMI; ) {
 		int j = i++;
 		ia64_i = ia64_intrs[j];
 		if (ia64_i != NULL && ia64_i->event != NULL)
@@ -369,11 +371,20 @@
 }
 
 void
-ia64_dispatch_intr(void *frame __unused, unsigned long vector)
+intr_callout_reset(void) 
+{
+	
+	mtx_lock_spin(&ia64_intrs_lock);
+	callout_reset(&stray_callout_handle, hz, 
+		      &stray_detection, &walk_intr_ia64);
+	mtx_unlock_spin(&ia64_intrs_lock);	
+}
+
+void
+ia64_dispatch_intr(void *frame, unsigned long vector)
 {
 	struct ia64_intr *i;
-	struct intr_event *ie;			/* our interrupt event */
-	int error, thread;
+	int res;
 
 	/*
 	 * Find the interrupt thread for this vector.
@@ -385,45 +396,24 @@
 	if (i->cntp)
 		atomic_add_long(i->cntp, 1);
 
-	ie = i->event;
-	KASSERT(ie != NULL, ("interrupt vector without an event"));
-
-	/*
-	 * As an optimization, if an event has no handlers, don't
-	 * schedule it to run.
-	 */
-	if (TAILQ_EMPTY(&ie->ie_handlers))
-		return;
-
-	/*
-	 * Execute all fast interrupt handlers directly without Giant.  Note
-	 * that this means that any fast interrupt handler must be MP safe.
-	 */
-	thread = 0;
-	critical_enter();
-	thread = intr_filter_loop(ie, NULL);
-	critical_exit();
-
-	/* Interrupt storm logic */
-	if (thread & FILTER_STRAY) {
-		if (ie->ie_enable == NULL || ie->ie_pending == NULL)
-			printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n");
-		else {
-			printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name);
-			ie->ie_count = INT_MAX;    
-			mtx_lock_spin(&ia64_intrs_lock);
-			callout_reset(&stray_callout_handle, hz, 
-				      &stray_detection, &walk_intr_ia64);
-			mtx_unlock_spin(&ia64_intrs_lock);
-		}
-	}
-
-	// XXX eoi & mask intr not verified.
-	if (thread & FILTER_SCHEDULE_THREAD) {
-		error = intr_event_schedule_thread(ie);
-		KASSERT(error == 0, ("got an impossible stray interrupt"));
-	} else
+	res = mi_handle_intr(i->event, frame, intr_eoi_src_stub, 
+			     intr_disab_eoi_src_stub, NULL);
+	switch (res) {
+	case 0:
+		break;
+	case ECHILD:
 		ia64_send_eoi(vector);
+		break;
+	case EFAULT:
+		panic("Got an impossible stray interrupt\n");
+		break;
+	case EINVAL:
+		panic("Interrupt vector without an event\n");
+		break;
+	default:
+		printf("Ouch! Return code from mi_handle_intr()"
+		       "not expected.\n");
+	}		
 }
 
 #ifdef DDB

==== //depot/projects/soc2006/intr_filter/kern/kern_intr.c#19 (text+ko) ====

@@ -62,6 +62,9 @@
 struct callout stray_callout_handle;
 static int backoff = 1;
 
+/* MD function */
+extern void intr_callout_reset(void);
+
 /*
  * Describe an interrupt thread.  There is one of these per interrupt event.
  */
@@ -877,7 +880,7 @@
 		}
 
 		KASSERT(ret != FILTER_SCHEDULE_THREAD, 
-			"intr_filter_loop: FILTER_SCHEDULE_THREAD from filter");
+			("intr_filter_loop: FILTER_SCHEDULE_THREAD from filter"));
 
 		if (ret & FILTER_STRAY)
 			continue;
@@ -939,6 +942,109 @@
 	}
 }
 
+/* 
+ * To avoid code duplication across different archs, use these functions 
+ * for interrupt eoiing and disabling when you don't actually need to do
+ * any real action on the interrupt controller.
+ */
+void
+intr_eoi_src_stub(void *arg __unused)
+{ 
+	;
+}
+
+void
+intr_disab_eoi_src_stub(void *arg __unused)
+{
+	;
+}
+
+/*
+ * Main interrupt handling body.
+ *
+ * Input:
+ * o ie:                        the event connected to this interrupt.
+ * o frame:                     some archs (i.e. i386) pass a frame to some.
+ *                              handlers as their main argument.
+ * o intr_eoi_src():            turn off an irq.
+ * o intr_disab_eoi_src():      mask and turn off an irq.
+ * o arg:                       struct intsrc passed to the 2 previous 
+ *                              intr_*_src() functions or NULL.
+ *
+ *                              NOTA BENE: i386 and amd64 handle their
+ *                              interrupt controllers through the
+ *                              intr_*_src() functions, so they are
+ *                              defined in the MD code for these archs.
+ *                              All the other archs (arm, ia64,
+ *                              powerpc, sparc64, etcetc) that don't
+ *                              use these facilities, will pass a NULL
+ *                              pointer for arg, and use the stub
+ *                              functions intr_eoi_src_stub() for
+ *                              intr_eoi_src() and
+ *                              intr_disab_eoi_src_stub() for
+ *                              intr_disab_eoi_src().
+ *
+ * Return value:
+ * o 0:                         everything ok.
+ * o EINVAL:                    stray interrupt.
+ * o ECHILD:                    no ithread scheduled.
+ * o EFAULT:                    something went wrong with ithread scheduling.
+ */
+int
+mi_handle_intr(struct intr_event *ie, struct trapframe *frame, 
+	       void (*intr_eoi_src)(void *), 
+	       void (*intr_disab_eoi_src)(void *), void *arg)
+{
+	struct intr_thread *ithd;
+	struct thread *td;
+	int error, res, thread;
+
+	ithd = NULL;
+	res = 0;
+	td = curthread;
+
+	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers))
+		return (EINVAL);
+
+	td->td_intr_nesting_level++;
+	thread = 0;
+	critical_enter();
+	thread = intr_filter_loop(ie, frame, &ithd);
+	
+	/*
+	 * If the interrupt was fully served, send it an EOI but leave
+	 * it unmasked. Otherwise, mask the source as well as sending
+	 * it an EOI.
+	 */
+	if (thread & FILTER_HANDLED)
+		intr_eoi_src(arg);
+	else
+		intr_disab_eoi_src(arg);
+	critical_exit();
+	
+	/* Interrupt storm logic */
+	if (thread & FILTER_STRAY) {
+		if (ie->ie_enable == NULL || ie->ie_pending == NULL)
+			printf("Interrupt stray detection not present:"
+			       "check ie_enable and ie_pending\n");
+		else {
+			printf("Interrupt stray detected on \"%s\";"
+			       "throttling interrupt source\n", ie->ie_name);
+			ie->ie_count = INT_MAX;    
+			intr_callout_reset();
+		}
+	}
+
+	/* Schedule an ithread if needed. */
+	if (thread & FILTER_SCHEDULE_THREAD) {
+		error = intr_event_schedule_thread(ie, ithd);
+		res = (error == 0) ? 0 : EFAULT;
+	} else
+		res = ECHILD;
+	td->td_intr_nesting_level--;
+	return (res);
+}
+
 #ifdef DDB
 /*
  * Dump details about an interrupt handler

==== //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#13 (text+ko) ====

@@ -91,6 +91,8 @@
 
 extern struct callout stray_callout_handle;
 
+void intr_callout_reset(void);
+
 extern int	extint, extsize;
 extern u_long	extint_call;
 
@@ -241,45 +243,39 @@
 }
 
 void
+intr_callout_reset(void)
+{
+	
+	mtx_lock_spin(&intr_table_lock);
+	callout_reset(&stray_callout_handle, hz, 
+		      &stray_detection, &walk_intr_ppc);
+	mtx_unlock_spin(&intr_table_lock);
+}
+
+void
 intr_handle(u_int irq)
 {
 	struct ppc_intr_handler *ppc_ih = &intr_handlers[irq];
 	struct intr_event *ie = ppc_ih->ih_event;
-	int error, thread;
+	int res;
 
-	if (ie == NULL) {
+	res = mi_handle_intr(ie, NULL, intr_eoi_src_stub,
+			     intr_disab_eoi_src_stub, NULL);
+	switch (res) {
+	case 0:
+		/* FALLTHROUGH */
+	case ECHILD:
+		atomic_add_long(ppc_ih->ih_count, 1);
+		break;
+	case EFAULT:
+		atomic_add_long(ppc_ih->ih_count, 1);
+		/* FALLTHROUGH */
+	case EINVAL:
 		intr_stray_handler(ppc_ih);
-		return;
-	}
-
-	atomic_add_long(ppc_ih->ih_count, 1);
-
-	critical_enter();
-	/* Execute fast interrupt handlers directly. */
-	thread = 0;
-	thread = intr_filter_loop(ie, NULL);
-	critical_exit();
-	
-	/* Interrupt storm logic */
-	if (thread & FILTER_STRAY) {
-		if (ie->ie_enable == NULL || ie->ie_pending == NULL)
-			printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n");
-		else {
-			printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name);
-			ie->ie_count = INT_MAX;    
-			mtx_lock_spin(&intr_table_lock);
-			callout_reset(&stray_callout_handle, hz, 
-				      &stray_detection, &walk_intr_ppc);
-			mtx_unlock_spin(&intr_table_lock);
-		}
-	}
-
-	// XXX eoi & mask intr not verified.
-	/* Schedule a heavyweight interrupt process. */
-	if (thread & FILTER_SCHEDULE_THREAD) {
-		error = intr_event_schedule_thread(ie);
-		if (error == EINVAL)
-			intr_stray_handler(ppc_ih);
+		break;
+	default:
+		printf("Ouch! Return code from mi_handle_intr()"
+		       "not expected.\n");
 	}
 }
 

==== //depot/projects/soc2006/intr_filter/sparc64/sparc64/intr_machdep.c#11 (text+ko) ====

@@ -107,6 +107,8 @@
 
 extern struct callout stray_callout_handle;
 
+void intr_callout_reset(void);
+
 static void intr_execute_handlers(void *);
 static void intr_stray_level(struct trapframe *);
 static void intr_stray_vector(void *);
@@ -251,44 +253,41 @@
 	return (NULL);
 }
 
+void
+intr_callout_reset(void)
+{
+
+	mtx_lock_spin(&intr_table_lock);
+	callout_reset(&stray_callout_handle, hz, 
+		      &stray_detection, &walk_intr_sparc64);
+	mtx_unlock_spin(&intr_table_lock);
+}
+
 static void
 intr_execute_handlers(void *cookie)
 {
 	struct intr_vector *iv;
 	struct intr_event *ie;
-	int error = 0, thread;
+	int res;
 
 	iv = cookie;
 	ie = iv->iv_event;
-	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers)) {
+	res = mi_handle_intr(ie, NULL, intr_eoi_src_stub, intr_disab_eoi_src_stub, 
+			 NULL);
+	switch (res) {
+	case 0:
+		/* FALLTHROUGH */
+	case ECHILD:
+		break;
+	case EFAULT:
+		/* FALLTHROUGH */
+	case EINVAL:
 		intr_stray_vector(iv);
-		return;
+		break;
+	default:
+		printf("Ouch! Return code from mi_handle_intr()"
+		       "not expected.\n");
 	}
-
-	/* Execute fast interrupt handlers directly. */
-	thread = intr_filter_loop(ie, NULL);
-
-	/* Interrupt storm logic */
-	if (thread & FILTER_STRAY) {
-		if (ie->ie_enable == NULL || ie->ie_pending == NULL)
-			printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n");
-		else {
-			printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name);
-			ie->ie_count = INT_MAX;    
-			mtx_lock_spin(&intr_table_lock);
-			callout_reset(&stray_callout_handle, hz, 
-				      &stray_detection, &walk_intr_sparc64);
-			mtx_unlock_spin(&intr_table_lock);
-		}
-	}
-
-	// XXX eoi & mask intr not verified.
-	/* Schedule a heavyweight interrupt process. */
-	if (thread & FILTER_SCHEDULE_THREAD)
-		error = intr_event_schedule_thread(ie);
-
-	if (error == EINVAL)
-		intr_stray_vector(iv);
 }
 
 int

==== //depot/projects/soc2006/intr_filter/sys/interrupt.h#8 (text+ko) ====

@@ -119,6 +119,11 @@
 int     intr_filter_loop(struct intr_event *ie, struct trapframe *frame, 
 			 struct intr_thread **ithd);
 void    stray_detection(void *_arg);
+void    intr_eoi_src_stub(void *arg __unused);
+void    intr_disab_eoi_src_stub(void *arg __unused);
+int     mi_handle_intr(struct intr_event *ie, struct trapframe *frame,
+		       void (*intr_eoi_src)(void *),
+		       void (*intr_disab_eoi_src)(void *), void *arg);
 u_char	intr_priority(enum intr_type flags);
 int	intr_event_add_handler(struct intr_event *ie, const char *name,
 	    driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, enum intr_type flags,


More information about the p4-projects mailing list