PERFORCE change 98908 for review

Paolo Pisati piso at FreeBSD.org
Sat Jun 10 16:35:37 UTC 2006


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

Change 98908 by piso at piso_newluxor on 2006/06/10 11:53:48

	Fix support for multiple fast handlers: not tested though.
	While here, refactor&cleanup a bit the code (rename 
	struct ppc_intr_handler variables to ppc_ih, and 
	struct intr_handler vars to ih, etcetc).
	
	Reviewed by:	Awaiting for Peter Grehan review

Affected files ...

.. //depot/projects/soc2006/intr_filter/powerpc/include/intr_machdep.h#2 edit
.. //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#2 edit

Differences ...

==== //depot/projects/soc2006/intr_filter/powerpc/include/intr_machdep.h#2 (text+ko) ====

@@ -33,11 +33,8 @@
 struct intr_event;
 
 struct ppc_intr_handler {
-	ih_func_t	*ih_func;
-	void		*ih_arg;
 	struct		intr_event *ih_event;
 	u_int		ih_irq;
-	u_int		ih_flags;
 	u_int 		ih_index;
 	u_long 		*ih_count;
 	u_long 		*ih_straycount;

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

@@ -66,6 +66,7 @@
 #include <sys/queue.h>
 #include <sys/bus.h>
 #include <sys/interrupt.h>
+#include <sys/ktr.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
@@ -82,10 +83,8 @@
 
 MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data");
 
-static int	intr_initialized = 0;
-
 static u_int		intr_nirq;
-static struct		ppc_intr_handler *intr_handlers;
+static struct		ppc_intr_handler *intr_handlers = NULL;
 
 static struct		mtx intr_table_lock;
 
@@ -94,7 +93,6 @@
 
 static int 		intrcnt_index;
 static ih_func_t	intr_stray_handler;
-static ih_func_t	sched_ithd;
 
 static void		(*irq_enable)(uintptr_t);
 static void		(*irq_disable)(uintptr_t);
@@ -110,26 +108,26 @@
 }
 
 static void
-intrcnt_updatename(struct ppc_intr_handler *ih)
+intrcnt_updatename(struct ppc_intr_handler *ppc_ih)
 {
-	intrcnt_setname(ih->ih_event->ie_fullname, ih->ih_index);
+	intrcnt_setname(ppc_ih->ih_event->ie_fullname, ppc_ih->ih_index);
 }
 
 static void
-intrcnt_register(struct ppc_intr_handler *ih)
+intrcnt_register(struct ppc_intr_handler *ppc_ih)
 {
 	char straystr[MAXCOMLEN + 1];
 
-	KASSERT(ih->ih_event != NULL,
+	KASSERT(ppc_ih->ih_event != NULL,
 		("%s: ppc_intr_handler with no event", __func__));
 
-	ih->ih_index = intrcnt_index;
+	ppc_ih->ih_index = intrcnt_index;
 	intrcnt_index += 2;
-	snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ih->ih_irq);
-	intrcnt_updatename(ih);
-	ih->ih_count = &intrcnt[ih->ih_index];
-	intrcnt_setname(straystr, ih->ih_index + 1);
-	ih->ih_straycount = &intrcnt[ih->ih_index + 1];
+	snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ppc_ih->ih_irq);
+	intrcnt_updatename(ppc_ih);
+	ppc_ih->ih_count = &intrcnt[ppc_ih->ih_index];
+	intrcnt_setname(straystr, ppc_ih->ih_index + 1);
+	ppc_ih->ih_straycount = &intrcnt[ppc_ih->ih_index + 1];
 }
 
 void
@@ -139,10 +137,9 @@
 	int		i;
 	u_int32_t	msr;
 
-	if (intr_initialized != 0)
+	if (intr_handlers != NULL)
 		panic("intr_init: interrupts intialized twice\n");
 
-	intr_initialized++;
 
 	intr_nirq = nirq;
 	intr_handlers = malloc(nirq * sizeof(struct ppc_intr_handler), M_INTR,
@@ -150,14 +147,9 @@
 	if (intr_handlers == NULL)
 		panic("intr_init: unable to allocate interrupt handler array");
 
-	for (i = 0; i < nirq; i++) {
-		intr_handlers[i].ih_func = intr_stray_handler;
-		intr_handlers[i].ih_arg = &intr_handlers[i];
-		intr_handlers[i].ih_irq = i;
-		intr_handlers[i].ih_flags = 0;
-		/* mux all initial stray irqs onto same count... */
+	/* mux all initial stray irqs onto same count... */
+	for (i = 0; i < nirq; i++)
 		intr_handlers[i].ih_straycount = &intrcnt[0];
-	}
 
 	intrcnt_setname("???", 0);
 	intrcnt_index = 1;
@@ -175,38 +167,21 @@
 	mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN);
 }
 
-void
-intr_setup(u_int irq, ih_func_t *ihf, void *iha, u_int flags)
-{
-	u_int32_t	msr;
-
-	msr = mfmsr();
-	mtmsr(msr & ~PSL_EE);
-
-	intr_handlers[irq].ih_func = ihf;
-	intr_handlers[irq].ih_arg = iha;
-	intr_handlers[irq].ih_irq = irq;
-	intr_handlers[irq].ih_flags = flags;
-
-	mtmsr(msr);
-}
-
 int
 inthand_add(const char *name, u_int irq, void (*handler)(void *), void *arg,
     int flags, void **cookiep)
 {
-	struct	ppc_intr_handler *ih;
+	struct	ppc_intr_handler *ppc_ih;
 	struct	intr_event *event, *orphan;
 	int	error = 0;
-	int	created_event = 0;
 
 	/*
 	 * Work around a race where more than one CPU may be registering
 	 * handlers on the same IRQ at the same time.
 	 */
-	ih = &intr_handlers[irq];
+	ppc_ih = &intr_handlers[irq];
 	mtx_lock_spin(&intr_table_lock);
-	event = ih->ih_event;
+	event = ppc_ih->ih_event;
 	mtx_unlock_spin(&intr_table_lock);
 	if (event == NULL) {
 		error = intr_event_create(&event, (void *)irq, 0,
@@ -216,103 +191,83 @@
 
 		mtx_lock_spin(&intr_table_lock);
 
-		if (ih->ih_event == NULL) {
-			ih->ih_event = event;
-			created_event++;
+		if (ppc_ih->ih_event == NULL) {
+			ppc_ih->ih_event = event;
 			mtx_unlock_spin(&intr_table_lock);
 		} else {
 			orphan = event;
-			event = ih->ih_event;
+			event = ppc_ih->ih_event;
 			mtx_unlock_spin(&intr_table_lock);
 			intr_event_destroy(orphan);
 		}
 	}
 
-	/* XXX: Should probably fix support for multiple FAST. */
-	if (flags & INTR_FAST)
-		flags |= INTR_EXCL;
 	error = intr_event_add_handler(event, name, handler, arg,
 	    intr_priority(flags), flags, cookiep);
-
-	if ((flags & INTR_FAST) == 0 || error) {
-		intr_setup(irq, sched_ithd, ih, flags);
-		error = 0;
-	}
-
 	if (error)
 		return (error);
 
-	if (flags & INTR_FAST)
-		intr_setup(irq, handler, arg, flags);
+	intrcnt_register(ppc_ih);
 
-	intrcnt_register(ih);
-
 	return (0);
 }
 
 int
 inthand_remove(u_int irq, void *cookie)
 {
-	struct	ppc_intr_handler *ih;
-	int	error;
+
+	return(intr_event_remove_handler(cookie));
+}
 
-	error = intr_event_remove_handler(cookie);
+void
+intr_handle(u_int irq)
+{
+	struct ppc_intr_handler *ppc_ih = &intr_handlers[irq];
+	struct intr_event *ie = ppc_ih->ih_event;
+	struct intr_handler *ih;
+	int error, thread;
 
-	if (error == 0) {
-		ih = &intr_handlers[irq];
+	if (ie == NULL) {
+		intr_stray_handler(ppc_ih);
+		return;
+	}
 
-		mtx_lock_spin(&intr_table_lock);
+	atomic_add_long(ppc_ih->ih_count, 1);
 
-		if (ih->ih_event == NULL) {
-			intr_setup(irq, intr_stray_handler, ih, 0);
-		} else {
-			intr_setup(irq, sched_ithd, ih, 0);
+	critical_enter();
+	/* Execute fast interrupt handlers directly. */
+	thread = 0;
+	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
+		if (!(ih->ih_flags & IH_FAST)) {
+			thread = 1;
+			continue;
 		}
-
-		mtx_unlock_spin(&intr_table_lock);
+		CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
+		    ih->ih_handler, ih->ih_argument);
+		ih->ih_handler(ih->ih_argument);
 	}
+	critical_exit();
+	
+	/* Schedule a heavyweight interrupt process. */
+	if (thread)
+		error = intr_event_schedule_thread(ie);
 
-	return (error);
+	if (error == EINVAL)
+		intr_stray_handler(ppc_ih);
 }
 
-void
-intr_handle(u_int irq)
-{
-	atomic_add_long(intr_handlers[irq].ih_count, 1);
-	intr_handlers[irq].ih_func(intr_handlers[irq].ih_arg);
-
-	/* XXX wrong thing when using pre-emption ? */
-	if ((intr_handlers[irq].ih_flags & INTR_FAST) != 0)
-		irq_enable(irq);
-}
-
 static void
 intr_stray_handler(void *cookie)
 {
-	struct	ppc_intr_handler *ih;
+	struct	ppc_intr_handler *ppc_ih = cookie;
 
-	ih = (struct ppc_intr_handler *)cookie;
+	if (*intr_handlers[ppc_ih->ih_irq].ih_straycount < MAX_STRAY_LOG) {
+		printf("stray irq %d\n", ppc_ih->ih_irq);
 
-	if (*intr_handlers[ih->ih_irq].ih_straycount < MAX_STRAY_LOG) {
-		printf("stray irq %d\n", ih->ih_irq);
-
-		atomic_add_long(intr_handlers[ih->ih_irq].ih_straycount, 1);
-		if (*intr_handlers[ih->ih_irq].ih_straycount >= MAX_STRAY_LOG)
+		atomic_add_long(intr_handlers[ppc_ih->ih_irq].ih_straycount, 1);
+		if (*intr_handlers[ppc_ih->ih_irq].ih_straycount >= MAX_STRAY_LOG)
 			printf("got %d stray irq %d's: not logging anymore\n",
-			       MAX_STRAY_LOG, ih->ih_irq);
+			       MAX_STRAY_LOG, ppc_ih->ih_irq);
 	}
 }
 
-static void
-sched_ithd(void *cookie)
-{
-	struct	ppc_intr_handler *ih;
-	int	error;
-
-	ih = (struct ppc_intr_handler *)cookie;
-
-	error = intr_event_schedule_thread(ih->ih_event);
-
-	if (error == EINVAL)
-		intr_stray_handler(ih);
-}


More information about the p4-projects mailing list