Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 May 2009 19:45:37 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r192406 - in stable/7/sys: . amd64/amd64 arm/arm contrib/pf dev/ath/ath_hal dev/cxgb i386/i386 ia64/ia64 kern powerpc/powerpc sparc64/sparc64 sun4v/sun4v sys
Message-ID:  <200905191945.n4JJjb0Q008111@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Tue May 19 19:45:36 2009
New Revision: 192406
URL: http://svn.freebsd.org/changeset/base/192406

Log:
  MFC: Add a MI intr_event_handle() routine for the non-INTR_FILTER case.
  This allows all the INTR_FILTER #ifdef's to be removed from the MD
  interrupt code.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/intr_machdep.c
  stable/7/sys/arm/arm/intr.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/i386/i386/intr_machdep.c
  stable/7/sys/ia64/ia64/interrupt.c
  stable/7/sys/kern/kern_intr.c
  stable/7/sys/powerpc/powerpc/intr_machdep.c
  stable/7/sys/sparc64/sparc64/intr_machdep.c
  stable/7/sys/sun4v/sun4v/intr_machdep.c
  stable/7/sys/sys/interrupt.h

Modified: stable/7/sys/amd64/amd64/intr_machdep.c
==============================================================================
--- stable/7/sys/amd64/amd64/intr_machdep.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/amd64/amd64/intr_machdep.c	Tue May 19 19:45:36 2009	(r192406)
@@ -85,9 +85,6 @@ static void	intr_assign_next_cpu(struct 
 
 static int	intr_assign_cpu(void *arg, u_char cpu);
 static void	intr_disable_src(void *arg);
-#ifdef INTR_FILTER
-static void	intr_event_stray(void *cookie);
-#endif
 static void	intr_init(void *__dummy);
 static int	intr_pic_registered(struct pic *pic);
 static void	intrcnt_setname(const char *name, int index);
@@ -238,66 +235,12 @@ intr_disable_src(void *arg)
 	isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 }
 
-#ifdef INTR_FILTER
 void
 intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
 {
-	struct thread *td;
 	struct intr_event *ie;
-	int vector;
-
-	td = curthread;
-
-	/*
-	 * We count software interrupts when we process them.  The
-	 * code here follows previous practice, but there's an
-	 * argument for counting hardware interrupts when they're
-	 * processed too.
-	 */
-	(*isrc->is_count)++;
-	PCPU_INC(cnt.v_intr);
-
-	ie = isrc->is_event;
-
-	/*
-	 * XXX: We assume that IRQ 0 is only used for the ISA timer
-	 * device (clk).
-	 */
-	vector = isrc->is_pic->pic_vector(isrc);
-	if (vector == 0)
-		clkintr_pending = 1;
-
-	if (intr_event_handle(ie, frame) != 0)
-		intr_event_stray(isrc);
-}
-
-static void
-intr_event_stray(void *cookie)
-{
-	struct intsrc *isrc;
-
-	isrc = cookie;
-	/*
-	 * 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)
-		log(LOG_ERR, "stray irq%d\n", isrc->is_pic->pic_vector(isrc));
-	else if (*isrc->is_straycount == MAX_STRAY_LOG)
-		log(LOG_CRIT,
-		    "too many stray irq %d's: not logging anymore\n",
-		    isrc->is_pic->pic_vector(isrc));
-}
-#else
-void
-intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
-{
 	struct thread *td;
-	struct intr_event *ie;
-	struct intr_handler *ih;
-	int error, vector, thread, ret;
+	int vector;
 
 	td = curthread;
 
@@ -324,7 +267,7 @@ intr_execute_handlers(struct intsrc *isr
 	 * For stray interrupts, mask and EOI the source, bump the
 	 * stray count, and log the condition.
 	 */
-	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers)) {
+	if (intr_event_handle(ie, frame) != 0) {
 		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 		(*isrc->is_straycount)++;
 		if (*isrc->is_straycount < MAX_STRAY_LOG)
@@ -333,60 +276,8 @@ intr_execute_handlers(struct intsrc *isr
 			log(LOG_CRIT,
 			    "too many stray irq %d's: not logging anymore\n",
 			    vector);
-		return;
 	}
-
-	/*
-	 * 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++;
-	ret = 0;
-	thread = 0;
-	critical_enter();
-	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (ih->ih_filter == NULL) {
-			thread = 1;
-			continue;
-		}
-		CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
-		    ih->ih_filter, ih->ih_argument == NULL ? frame :
-		    ih->ih_argument, ih->ih_name);
-		if (ih->ih_argument == NULL)
-			ret = ih->ih_filter(frame);
-		else
-			ret = ih->ih_filter(ih->ih_argument);
-		/*
-		 * Wrapper handler special case: see
-		 * i386/intr_machdep.c::intr_execute_handlers()
-		 */
-		if (!thread) {
-			if (ret == FILTER_SCHEDULE_THREAD)
-				thread = 1;
-		}
-	}
-
-	/*
-	 * If there are any threaded handlers that need to run,
-	 * mask the source as well as sending it an EOI.  Otherwise,
-	 * just send it an EOI but leave it unmasked.
-	 */
-	if (thread)
-		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
-	else
-		isrc->is_pic->pic_eoi_source(isrc);
-
-	/* Schedule the ithread if needed. */
-	if (thread) {
-		error = intr_event_schedule_thread(ie);
-		KASSERT(error == 0, ("bad stray interrupt"));
-	}
-	critical_exit();
-	td->td_intr_nesting_level--;
 }
-#endif
 
 void
 intr_resume(void)

Modified: stable/7/sys/arm/arm/intr.c
==============================================================================
--- stable/7/sys/arm/arm/intr.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/arm/arm/intr.c	Tue May 19 19:45:36 2009	(r192406)
@@ -72,7 +72,7 @@ arm_setup_irqhandler(const char *name, d
 	if (event == NULL) {
 		error = intr_event_create(&event, (void *)irq, 0,
 		    (mask_fn)arm_mask_irq, (mask_fn)arm_unmask_irq,
-		    (mask_fn)arm_unmask_irq, NULL, "intr%d:", irq);
+		    NULL, NULL, "intr%d:", irq);
 		if (error)
 			return;
 		intr_events[irq] = event;
@@ -106,57 +106,17 @@ arm_handler_execute(struct trapframe *fr
 {
 	struct intr_event *event;
 	struct thread *td = curthread;
-#ifdef INTR_FILTER
 	int i;
-#else
-	int i, thread, ret;
-	struct intr_handler *ih;
-#endif
 
 	PCPU_INC(cnt.v_intr);
 	td->td_intr_nesting_level++;
 	while ((i = arm_get_next_irq()) != -1) {
-#ifndef INTR_FILTER
-		arm_mask_irq(i);
-#endif
 		intrcnt[intrcnt_tab[i]]++;
 		event = intr_events[i];
-		if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
-#ifdef INTR_FILTER
+		if (intr_event_handle(event, frame) != 0) {
+			/* XXX: Log stray IRQs */
 			arm_mask_irq(i);
-#endif
-			continue;
 		}
-
-#ifdef INTR_FILTER
-		intr_event_handle(event, frame);
-		/* XXX: Log stray IRQs */
-#else
-		/* Execute fast handlers. */
-		ret = 0;
-		thread = 0;
-		TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
-			if (ih->ih_filter == NULL)
-				thread = 1;
-			else
-				ret = ih->ih_filter(ih->ih_argument ?
-				    ih->ih_argument : frame);
-			/*
-			 * Wrapper handler special case: see
-			 * i386/intr_machdep.c::intr_execute_handlers()
-			 */
-			if (!thread) {
-				if (ret == FILTER_SCHEDULE_THREAD)
-					thread = 1;
-			}
-		}
-
-		/* Schedule thread if needed. */
-		if (thread)
-			intr_event_schedule_thread(event);
-		else
-			arm_unmask_irq(i);
-#endif
 	}
 	td->td_intr_nesting_level--;
 }

Modified: stable/7/sys/i386/i386/intr_machdep.c
==============================================================================
--- stable/7/sys/i386/i386/intr_machdep.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/i386/i386/intr_machdep.c	Tue May 19 19:45:36 2009	(r192406)
@@ -76,9 +76,6 @@ static void	intr_assign_next_cpu(struct 
 
 static int	intr_assign_cpu(void *arg, u_char cpu);
 static void	intr_disable_src(void *arg);
-#ifdef INTR_FILTER
-static void	intr_event_stray(void *cookie);
-#endif
 static void	intr_init(void *__dummy);
 static int	intr_pic_registered(struct pic *pic);
 static void	intrcnt_setname(const char *name, int index);
@@ -229,66 +226,12 @@ intr_disable_src(void *arg)
 	isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 }
 
-#ifdef INTR_FILTER
 void
 intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
 {
-	struct thread *td;
 	struct intr_event *ie;
-	int vector;
-
-	td = curthread;
-
-	/*
-	 * We count software interrupts when we process them.  The
-	 * code here follows previous practice, but there's an
-	 * argument for counting hardware interrupts when they're
-	 * processed too.
-	 */
-	(*isrc->is_count)++;
-	PCPU_INC(cnt.v_intr);
-
-	ie = isrc->is_event;
-
-	/*
-	 * XXX: We assume that IRQ 0 is only used for the ISA timer
-	 * device (clk).
-	 */
-	vector = isrc->is_pic->pic_vector(isrc);
-	if (vector == 0)
-		clkintr_pending = 1;
-
-	if (intr_event_handle(ie, frame) != 0)
-		intr_event_stray(isrc);		
-}
-
-static void
-intr_event_stray(void *cookie)
-{
-	struct intsrc *isrc;
-
-	isrc = cookie;
-	/*
-	 * 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)
-		log(LOG_ERR, "stray irq%d\n", isrc->is_pic->pic_vector(isrc));
-	else if (*isrc->is_straycount == MAX_STRAY_LOG)
-		log(LOG_CRIT,
-		    "too many stray irq %d's: not logging anymore\n",
-		    isrc->is_pic->pic_vector(isrc));
-}
-#else
-void
-intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
-{
 	struct thread *td;
-	struct intr_event *ie;
-	struct intr_handler *ih;
-	int error, vector, thread, ret;
+	int vector;
 
 	td = curthread;
 
@@ -315,7 +258,7 @@ intr_execute_handlers(struct intsrc *isr
 	 * For stray interrupts, mask and EOI the source, bump the
 	 * stray count, and log the condition.
 	 */
-	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers)) {
+	if (intr_event_handle(ie, frame) != 0) {
 		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 		(*isrc->is_straycount)++;
 		if (*isrc->is_straycount < MAX_STRAY_LOG)
@@ -324,70 +267,8 @@ intr_execute_handlers(struct intsrc *isr
 			log(LOG_CRIT,
 			    "too many stray irq %d's: not logging anymore\n",
 			    vector);
-		return;
 	}
-
-	/*
-	 * 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++;
-	ret = 0;
-	thread = 0;
-	critical_enter();
-	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (ih->ih_filter == NULL) {
-			thread = 1;
-			continue;
-		}
-		CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
-		    ih->ih_filter, ih->ih_argument == NULL ? frame :
-		    ih->ih_argument, ih->ih_name);
-		if (ih->ih_argument == NULL)
-			ret = ih->ih_filter(frame);
-		else
-			ret = ih->ih_filter(ih->ih_argument);
-		/* 
-		 * Wrapper handler special handling:
-		 *
-		 * in some particular cases (like pccard and pccbb), 
-		 * the _real_ device handler is wrapped in a couple of
-		 * functions - a filter wrapper and an ithread wrapper.
-		 * In this case (and just in this case), the filter wrapper 
-		 * could ask the system to schedule the ithread and mask
-		 * the interrupt source if the wrapped handler is composed
-		 * of just an ithread handler.
-		 *
-		 * TODO: write a generic wrapper to avoid people rolling 
-		 * their own
-		 */
-		if (!thread) {
-			if (ret == FILTER_SCHEDULE_THREAD)
-				thread = 1;
-		}
-	}
-
-	/*
-	 * If there are any threaded handlers that need to run,
-	 * mask the source as well as sending it an EOI.  Otherwise,
-	 * just send it an EOI but leave it unmasked.
-	 */
-	if (thread)
-		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
-	else
-		isrc->is_pic->pic_eoi_source(isrc);
-
-	/* Schedule the ithread if needed. */
-	if (thread) {
-		error = intr_event_schedule_thread(ie);
-		KASSERT(error == 0, ("bad stray interrupt"));
-	}
-	critical_exit();
-	td->td_intr_nesting_level--;
 }
-#endif
 
 void
 intr_resume(void)

Modified: stable/7/sys/ia64/ia64/interrupt.c
==============================================================================
--- stable/7/sys/ia64/ia64/interrupt.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/ia64/ia64/interrupt.c	Tue May 19 19:45:36 2009	(r192406)
@@ -385,10 +385,6 @@ ia64_dispatch_intr(void *frame, u_int ve
 {
 	struct ia64_intr *i;
 	struct intr_event *ie;			/* our interrupt event */
-#ifndef INTR_FILTER
-	struct intr_handler *ih;
-	int error, thread, ret;
-#endif
 
 	/*
 	 * Find the interrupt thread for this vector.
@@ -401,52 +397,14 @@ ia64_dispatch_intr(void *frame, u_int ve
 	ie = i->event;
 	KASSERT(ie != NULL, ("%s: interrupt without event", __func__));
 
-#ifdef INTR_FILTER
 	if (intr_event_handle(ie, frame) != 0) {
-		ia64_intr_mask((void *)(uintptr_t)vector);
-		log(LOG_ERR, "stray irq%u\n", i->irq);
-	}
-#else
-	/*
-	 * 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.
-	 */
-	ret = 0;
-	thread = 0;
-	critical_enter();
-	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (ih->ih_filter == NULL) {
-			thread = 1;
-			continue;
-		}
-		CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
-		    ih->ih_filter, ih->ih_argument, ih->ih_name);
-		ret = ih->ih_filter(ih->ih_argument);
 		/*
-		 * Wrapper handler special case: see
-		 * i386/intr_machdep.c::intr_execute_handlers()
+		 * XXX: The pre-INTR_FILTER code didn't mask stray
+		 * interrupts.
 		 */
-		if (!thread) {
-			if (ret == FILTER_SCHEDULE_THREAD)
-				thread = 1;
-		}
-	}
-
-	if (thread) {
 		ia64_intr_mask((void *)(uintptr_t)vector);
-		error = intr_event_schedule_thread(ie);
-		KASSERT(error == 0, ("%s: impossible stray", __func__));
-	} else
-		ia64_intr_eoi((void *)(uintptr_t)vector);
-	critical_exit();
-#endif
+		log(LOG_ERR, "stray irq%u\n", i->irq);
+	}
 }
 
 #ifdef DDB

Modified: stable/7/sys/kern/kern_intr.c
==============================================================================
--- stable/7/sys/kern/kern_intr.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/kern/kern_intr.c	Tue May 19 19:45:36 2009	(r192406)
@@ -94,9 +94,14 @@ static TAILQ_HEAD(, intr_event) event_li
 
 static void	intr_event_update(struct intr_event *ie);
 #ifdef INTR_FILTER
+static int	intr_event_schedule_thread(struct intr_event *ie,
+		    struct intr_thread *ithd);
+static int	intr_filter_loop(struct intr_event *ie,
+		    struct trapframe *frame, struct intr_thread **ithd);
 static struct intr_thread *ithread_create(const char *name,
 			      struct intr_handler *ih);
 #else
+static int	intr_event_schedule_thread(struct intr_event *ie);
 static struct intr_thread *ithread_create(const char *name);
 #endif
 static void	ithread_destroy(struct intr_thread *ithread);
@@ -240,8 +245,9 @@ intr_event_update(struct intr_event *ie)
 
 int
 intr_event_create(struct intr_event **event, void *source,int flags,
-    void (*disable)(void *), void (*enable)(void *), void (*eoi)(void *),
-    int (*assign_cpu)(void *, u_char), const char *fmt, ...)
+    void (*pre_ithread)(void *), void (*post_ithread)(void *),
+    void (*post_filter)(void *), int (*assign_cpu)(void *, u_char),
+    const char *fmt, ...)
 {
 	struct intr_event *ie;
 	va_list ap;
@@ -251,9 +257,9 @@ intr_event_create(struct intr_event **ev
 		return (EINVAL);
 	ie = malloc(sizeof(struct intr_event), M_ITHREAD, M_WAITOK | M_ZERO);
 	ie->ie_source = source;
-	ie->ie_disable = disable;
-	ie->ie_enable = enable;
-	ie->ie_eoi = eoi;
+	ie->ie_pre_ithread = pre_ithread;
+	ie->ie_post_ithread = post_ithread;
+	ie->ie_post_filter = post_filter;
 	ie->ie_assign_cpu = assign_cpu;
 	ie->ie_flags = flags;
 	ie->ie_cpu = NOCPU;
@@ -678,7 +684,7 @@ ok:
 	return (0);
 }
 
-int
+static int
 intr_event_schedule_thread(struct intr_event *ie)
 {
 	struct intr_entropy entropy;
@@ -835,7 +841,7 @@ ok:
 	return (0);
 }
 
-int
+static int
 intr_event_schedule_thread(struct intr_event *ie, struct intr_thread *it)
 {
 	struct intr_entropy entropy;
@@ -1078,8 +1084,8 @@ ithread_execute_handlers(struct proc *p,
 	 * Now that all the handlers have had a chance to run, reenable
 	 * the interrupt source.
 	 */
-	if (ie->ie_enable != NULL)
-		ie->ie_enable(ie->ie_source);
+	if (ie->ie_post_ithread != NULL)
+		ie->ie_post_ithread(ie->ie_source);
 }
 
 #ifndef INTR_FILTER
@@ -1166,6 +1172,90 @@ ithread_loop(void *arg)
 		thread_unlock(td);
 	}
 }
+
+/*
+ * 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.
+ * Return value:
+ * o 0:                         everything ok.
+ * o EINVAL:                    stray interrupt.
+ */
+int
+intr_event_handle(struct intr_event *ie, struct trapframe *frame)
+{
+	struct intr_handler *ih;
+	struct thread *td;
+	int error, ret, thread;
+
+	td = curthread;
+
+	/* An interrupt with no event or handlers is a stray interrupt. */
+	if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers))
+		return (EINVAL);
+
+	/*
+	 * 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;
+	ret = 0;
+	critical_enter();
+	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
+		if (ih->ih_filter == NULL) {
+			thread = 1;
+			continue;
+		}
+		CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
+		    ih->ih_filter, ih->ih_argument == NULL ? frame :
+		    ih->ih_argument, ih->ih_name);
+		if (ih->ih_argument == NULL)
+			ret = ih->ih_filter(frame);
+		else
+			ret = ih->ih_filter(ih->ih_argument);
+		/* 
+		 * Wrapper handler special handling:
+		 *
+		 * in some particular cases (like pccard and pccbb), 
+		 * the _real_ device handler is wrapped in a couple of
+		 * functions - a filter wrapper and an ithread wrapper.
+		 * In this case (and just in this case), the filter wrapper 
+		 * could ask the system to schedule the ithread and mask
+		 * the interrupt source if the wrapped handler is composed
+		 * of just an ithread handler.
+		 *
+		 * TODO: write a generic wrapper to avoid people rolling 
+		 * their own
+		 */
+		if (!thread) {
+			if (ret == FILTER_SCHEDULE_THREAD)
+				thread = 1;
+		}
+	}
+
+	if (thread) {
+		if (ie->ie_pre_ithread != NULL)
+			ie->ie_pre_ithread(ie->ie_source);
+	} else {
+		if (ie->ie_post_filter != NULL)
+			ie->ie_post_filter(ie->ie_source);
+	}
+	
+	/* Schedule the ithread if needed. */
+	if (thread) {
+		error = intr_event_schedule_thread(ie);
+		KASSERT(error == 0, ("bad stray interrupt"));
+	}
+	critical_exit();
+	td->td_intr_nesting_level--;
+	return (0);
+}
 #else
 /*
  * This is the main code for interrupt threads.
@@ -1281,7 +1371,7 @@ ithread_loop(void *arg)
  * scheduled.
  */
 
-int
+static int
 intr_filter_loop(struct intr_event *ie, struct trapframe *frame, 
 		 struct intr_thread **ithd) 
 {
@@ -1357,19 +1447,13 @@ intr_event_handle(struct intr_event *ie,
 	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.
-	 */
+	thread = intr_filter_loop(ie, frame, &ithd);	
 	if (thread & FILTER_HANDLED) {
-		if (ie->ie_eoi != NULL)
-			ie->ie_eoi(ie->ie_source);
+		if (ie->ie_post_filter != NULL)
+			ie->ie_post_filter(ie->ie_source);
 	} else {
-		if (ie->ie_disable != NULL)
-			ie->ie_disable(ie->ie_source);
+		if (ie->ie_pre_ithread != NULL)
+			ie->ie_pre_ithread(ie->ie_source);
 	}
 	critical_exit();
 	

Modified: stable/7/sys/powerpc/powerpc/intr_machdep.c
==============================================================================
--- stable/7/sys/powerpc/powerpc/intr_machdep.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/powerpc/powerpc/intr_machdep.c	Tue May 19 19:45:36 2009	(r192406)
@@ -228,10 +228,6 @@ powerpc_dispatch_intr(u_int vector, stru
 {
 	struct powerpc_intr *i;
 	struct intr_event *ie;
-#ifndef INTR_FILTER
-	struct intr_handler *ih;
-	int error, sched, ret;
-#endif
 
 	i = powerpc_intrs[vector];
 	if (i == NULL)
@@ -242,55 +238,15 @@ powerpc_dispatch_intr(u_int vector, stru
 	ie = i->event;
 	KASSERT(ie != NULL, ("%s: interrupt without an event", __func__));
 
-#ifdef INTR_FILTER
 	if (intr_event_handle(ie, tf) != 0) {
-		PIC_MASK(pic, i->irq);
-		log(LOG_ERR, "stray irq%u\n", i->irq);
-	}
-#else
-	if (TAILQ_EMPTY(&ie->ie_handlers))
 		goto stray;
-
-	/*
-	 * Execute all fast interrupt handlers directly without Giant.  Note
-	 * that this means that any fast interrupt handler must be MP safe.
-	 */
-	ret = 0;
-	sched = 0;
-	critical_enter();
-	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (ih->ih_filter == NULL) {
-			sched = 1;
-			continue;
-		}
-		CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
-		    ih->ih_filter, ih->ih_argument, ih->ih_name);
-		ret = ih->ih_filter(ih->ih_argument);
-		/*
-		 * Wrapper handler special case: see
-		 * i386/intr_machdep.c::intr_execute_handlers()
-		 */
-		if (!sched) {
-			if (ret == FILTER_SCHEDULE_THREAD)
-				sched = 1;
-		}
 	}
-
-	if (sched) {
-		PIC_MASK(pic, i->irq);
-		error = intr_event_schedule_thread(ie);
-		KASSERT(error == 0, ("%s: impossible stray interrupt",
-		    __func__));
-	} else
-		PIC_EOI(pic, i->irq);
-	critical_exit();
-#endif
 	return;
 
 stray:
 	stray_count++;
 	if (stray_count <= MAX_STRAY_LOG) {
-		printf("stray irq %d\n", i->irq);
+		printf("stray irq %d\n", i ? i->irq : -1);
 		if (stray_count >= MAX_STRAY_LOG) {
 			printf("got %d stray interrupts, not logging anymore\n",
 			    MAX_STRAY_LOG);

Modified: stable/7/sys/sparc64/sparc64/intr_machdep.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/intr_machdep.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/sparc64/sparc64/intr_machdep.c	Tue May 19 19:45:36 2009	(r192406)
@@ -275,57 +275,9 @@ static void
 intr_execute_handlers(void *cookie)
 {
 	struct intr_vector *iv;
-#ifndef INTR_FILTER
-	struct intr_event *ie;
-	struct intr_handler *ih;
-	int error, thread, ret;
-#endif
 
 	iv = cookie;
-#ifndef INTR_FILTER
-	ie = iv->iv_event;
-	if (iv->iv_ic == NULL || ie == NULL) {
-		intr_stray_vector(iv);
-		return;
-	}
-
-	/* Execute fast interrupt handlers directly. */
-	ret = 0;
-	thread = 0;
-	critical_enter();
-	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (ih->ih_filter == NULL) {
-			thread = 1;
-			continue;
-		}
-		MPASS(ih->ih_filter != NULL && ih->ih_argument != NULL);
-		CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
-		    ih->ih_filter, ih->ih_argument);
-		ret = ih->ih_filter(ih->ih_argument);
-		/*
-		 * Wrapper handler special case: see
-		 * i386/intr_machdep.c::intr_execute_handlers()
-		 */
-		if (!thread) {
-			if (ret == FILTER_SCHEDULE_THREAD)
-				thread = 1;
-		}
-	}
-	if (!thread)
-		iv->iv_ic->ic_clear(iv);
-
-	/* Schedule a heavyweight interrupt process. */
-	if (thread)
-		error = intr_event_schedule_thread(ie);
-	else if (TAILQ_EMPTY(&ie->ie_handlers))
-		error = EINVAL;
-	else
-		error = 0;
-	critical_exit();
-	if (error == EINVAL)
-#else
 	if (iv->iv_ic == NULL || intr_event_handle(iv->iv_event, NULL) != 0)
-#endif
 		intr_stray_vector(iv);
 }
 

Modified: stable/7/sys/sun4v/sun4v/intr_machdep.c
==============================================================================
--- stable/7/sys/sun4v/sun4v/intr_machdep.c	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/sun4v/sun4v/intr_machdep.c	Tue May 19 19:45:36 2009	(r192406)
@@ -101,12 +101,6 @@ struct intr_vector intr_vectors[IV_MAX];
 uint16_t intr_countp[IV_MAX];
 static u_long intr_stray_count[IV_MAX];
 
-struct ithread_vector_handler {
-	iv_func_t *ivh_handler;
-	void *ivh_arg;
-	u_int ivh_vec;
-};
-
 static char *pil_names[] = {
 	"stray",
 	"low",		/* PIL_LOW */
@@ -276,63 +270,23 @@ intr_init(void)
 }
 SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL);
 
+static void
+intr_enable(void *cookie)
+{
+	int vec;
+
+	vec = (uintptr_t)cookie;
+	hv_intr_setstate(vec, HV_INTR_IDLE_STATE);
+}
 
 static void
 intr_execute_handlers(void *cookie)
 {
 	struct intr_vector *iv;
-	struct intr_event *ie;
-	struct intr_handler *ih;
-	int fast, thread, ret;
 
 	iv = cookie;
-	ie = iv->iv_event;
-	if (ie == NULL) {
-		intr_stray_vector(iv);
-		return;
-	}
-	
-	ret = 0;
-	fast = thread = 0;
-	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (ih->ih_filter == NULL) {
-			thread = 1;
-			continue;
-		}
-		MPASS(ih->ih_filter != NULL && ih->ih_argument != NULL);
-		CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
-		    ih->ih_filter, ih->ih_argument);
-		ret = ih->ih_filter(ih->ih_argument);
-		fast = 1;
-		/*
-		 * Wrapper handler special case: see
-		 * i386/intr_machdep.c::intr_execute_handlers()
-		 */
-		if (!thread) {
-			if (ret == FILTER_SCHEDULE_THREAD)
-				thread = 1;
-		}
-	}
-
-	/* Schedule a heavyweight interrupt process. */
-	if (thread) 
-		intr_event_schedule_thread(ie);
-	else if (TAILQ_EMPTY(&ie->ie_handlers))
+	if (intr_event_handle(iv->iv_event, NULL) != 0)
 		intr_stray_vector(iv);
-
-	if (fast)
-		hv_intr_setstate(iv->iv_vec, HV_INTR_IDLE_STATE);
-
-}
-
-static void
-ithread_wrapper(void *arg)
-{
-	struct ithread_vector_handler *ivh = (struct ithread_vector_handler *)arg;
-	
-	ivh->ivh_handler(ivh->ivh_arg);
-	/* re-enable interrupt */
-	hv_intr_setstate(ivh->ivh_vec, HV_INTR_IDLE_STATE);
 }
 
 int
@@ -342,13 +296,8 @@ inthand_add(const char *name, int vec, d
 	struct intr_vector *iv;
 	struct intr_event *ie;		/* descriptor for the IRQ */
 	struct intr_event *orphan;
-	struct ithread_vector_handler *ivh;
 	int errcode, pil;
 
-	if (filt != NULL && handler != NULL) {
-		printf("both filt and handler set is not valid\n");
-		return (EINVAL);
-	}
 	/*
 	 * Work around a race where more than one CPU may be registering
 	 * handlers on the same IRQ at the same time.
@@ -359,7 +308,7 @@ inthand_add(const char *name, int vec, d
 	mtx_unlock_spin(&intr_table_lock);
 	if (ie == NULL) {
 		errcode = intr_event_create(&ie, (void *)(intptr_t)vec, 0, NULL,
-		    NULL, "vec%d:", vec);
+		    intr_enable, intr_enable, NULL, "vec%d:", vec);
 		if (errcode)
 			return (errcode);
 		mtx_lock_spin(&intr_table_lock);
@@ -374,26 +323,12 @@ inthand_add(const char *name, int vec, d
 		}
 	}
 
-	if (filt == NULL) {
-		ivh = (struct ithread_vector_handler *)
-			malloc(sizeof(struct ithread_vector_handler), M_DEVBUF, M_WAITOK);
-		ivh->ivh_handler = (driver_intr_t *)handler;
-		ivh->ivh_arg = arg;
-		ivh->ivh_vec = vec;
-		errcode = intr_event_add_handler(ie, name, NULL, ithread_wrapper, ivh,
-						 intr_priority(flags), flags, cookiep);
-	} else {
-		ivh = NULL;
-		errcode = intr_event_add_handler(ie, name, filt, NULL, arg,
-						 intr_priority(flags), flags, 
-						 cookiep);
-	}
+	errcode = intr_event_add_handler(ie, name, filt, handler, arg,
+	    intr_priority(flags), flags, cookiep);
 
-	if (errcode) {
-		if (ivh)
-			free(ivh, M_DEVBUF);
+	if (errcode)
 		return (errcode);
-	}
+
 	pil = (filt != NULL) ? PIL_FAST : PIL_ITHREAD;
 
 	intr_setup(pil, intr_fast, vec, intr_execute_handlers, iv);

Modified: stable/7/sys/sys/interrupt.h
==============================================================================
--- stable/7/sys/sys/interrupt.h	Tue May 19 19:27:07 2009	(r192405)
+++ stable/7/sys/sys/interrupt.h	Tue May 19 19:45:36 2009	(r192406)
@@ -63,6 +63,33 @@ struct intr_handler {
 
 /*
  * Describe an interrupt event.  An event holds a list of handlers.
+ * The 'pre_ithread', 'post_ithread', 'post_filter', and 'assign_cpu'
+ * hooks are used to invoke MD code for certain operations.
+ *
+ * The 'pre_ithread' hook is called when an interrupt thread for
+ * handlers without filters is scheduled.  It is responsible for
+ * ensuring that 1) the system won't be swamped with an interrupt
+ * storm from the associated source while the ithread runs and 2) the
+ * current CPU is able to receive interrupts from other interrupt
+ * sources.  The first is usually accomplished by disabling
+ * level-triggered interrupts until the ithread completes.  The second
+ * is accomplished on some platforms by acknowledging the interrupt
+ * via an EOI.
+ *
+ * The 'post_ithread' hook is invoked when an ithread finishes.  It is
+ * responsible for ensuring that the associated interrupt source will
+ * trigger an interrupt when it is asserted in the future.  Usually
+ * this is implemented by enabling a level-triggered interrupt that
+ * was previously disabled via the 'pre_ithread' hook.
+ *
+ * The 'post_filter' hook is invoked when a filter handles an
+ * interrupt.  It is responsible for ensuring that the current CPU is
+ * able to receive interrupts again.  On some platforms this is done
+ * by acknowledging the interrupts via an EOI.
+ *
+ * The 'assign_cpu' hook is used to bind an interrupt source to a
+ * specific CPU.  If the interrupt cannot be bound, this function may
+ * return an error.
  */
 struct intr_event {
 	TAILQ_ENTRY(intr_event) ie_list;
@@ -72,9 +99,9 @@ struct intr_event {
 	struct mtx	ie_lock;
 	void		*ie_source;	/* Cookie used by MD code. */
 	struct intr_thread *ie_thread;	/* Thread we are connected to. */
-	void		(*ie_disable)(void *);
-	void		(*ie_enable)(void *);
-	void		(*ie_eoi)(void *);
+	void		(*ie_pre_ithread)(void *);
+	void		(*ie_post_ithread)(void *);
+	void		(*ie_post_filter)(void *);
 	int		(*ie_assign_cpu)(void *, u_char);
 	int		ie_flags;
 	int		ie_count;	/* Loop counter. */
@@ -118,29 +145,19 @@ extern char 	intrnames[];	/* string tabl
 #ifdef DDB
 void	db_dump_intr_event(struct intr_event *ie, int handlers);
 #endif
-#ifdef INTR_FILTER
-int     intr_filter_loop(struct intr_event *ie, struct trapframe *frame, 
-			 struct intr_thread **ithd);
-int     intr_event_handle(struct intr_event *ie, struct trapframe *frame);
-#endif
 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, void **cookiep);	    
 int	intr_event_bind(struct intr_event *ie, u_char cpu);
 int	intr_event_create(struct intr_event **event, void *source,
-	    int flags, void (*disable)(void *), void (*enable)(void *),
-	    void (*eoi)(void *), int (*assign_cpu)(void *, u_char),
-	    const char *fmt, ...)
+	    int flags, void (*pre_ithread)(void *),
+	    void (*post_ithread)(void *), void (*post_filter)(void *),
+	    int (*assign_cpu)(void *, u_char), const char *fmt, ...)
 	    __printflike(8, 9);
 int	intr_event_destroy(struct intr_event *ie);
+int	intr_event_handle(struct intr_event *ie, struct trapframe *frame);
 int	intr_event_remove_handler(void *cookie);
-#ifndef INTR_FILTER
-int	intr_event_schedule_thread(struct intr_event *ie);
-#else
-int	intr_event_schedule_thread(struct intr_event *ie,
-	    struct intr_thread *ithd);
-#endif
 void	*intr_handler_source(void *cookie);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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