Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Dec 2006 16:00:01 +0100
From:      Paolo Pisati <piso@freebsd.org>
To:        powerpc@freebsd.org
Cc:        Peter Grehan <grehan@freebsd.org>
Subject:   [patch] Shared interrupts with fast handlers
Message-ID:  <20061204150001.GA45877@tin.it>

next in thread | raw e-mail | index | archive | help

--xHFwDpU9dbj6ez1V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi list,

attached is my patch to let ppc share different fast handlers
on the same irq line.

It's slightly different from the patch i sent to Peter back then, and
form the code in my p4 tree, with much _less_ code churn.

If Peter/Marcel/anyone can test it, and i works, please feel free
to commit it.

Thanks.
-- 

Paolo

Piso's first law: nothing works as expected!

--xHFwDpU9dbj6ez1V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="intr_machdep.powerpc.patch"

--- sys/powerpc/include/intr_machdep.h.orig	Sun Dec  3 17:50:52 2006
+++ sys/powerpc/include/intr_machdep.h	Mon Dec  4 12:46:30 2006
@@ -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;
--- sys/powerpc/powerpc/intr_machdep.c.orig	Sun Dec  3 17:50:52 2006
+++ sys/powerpc/powerpc/intr_machdep.c	Mon Dec  4 15:13:13 2006
@@ -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);
@@ -139,25 +137,18 @@
 	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,
 	    M_NOWAIT|M_ZERO);
 	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,22 +166,6 @@
 	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)
@@ -198,7 +173,6 @@
 	struct	ppc_intr_handler *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
@@ -218,7 +192,6 @@
 
 		if (ih->ih_event == NULL) {
 			ih->ih_event = event;
-			created_event++;
 			mtx_unlock_spin(&intr_table_lock);
 		} else {
 			orphan = event;
@@ -228,21 +201,12 @@
 		}
 	}
 
-	/* 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);
-
 	if (error)
 		return (error);
 
-	if (flags & INTR_FAST)
-		intr_setup(irq, handler, arg, flags);
-
 	intrcnt_register(ih);
 
 	return (0);
@@ -251,37 +215,42 @@
 int
 inthand_remove(u_int irq, void *cookie)
 {
-	struct	ppc_intr_handler *ih;
-	int	error;
-
-	error = intr_event_remove_handler(cookie);
-
-	if (error == 0) {
-		ih = &intr_handlers[irq];
-
-		mtx_lock_spin(&intr_table_lock);
-
-		if (ih->ih_event == NULL) {
-			intr_setup(irq, intr_stray_handler, ih, 0);
-		} else {
-			intr_setup(irq, sched_ithd, ih, 0);
-		}
-
-		mtx_unlock_spin(&intr_table_lock);
-	}
-
-	return (error);
+	return (intr_event_remove_handler(cookie));
 }
 
 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);
+	struct ppc_intr_handler *ppc_ih = &intr_handlers[irq];
+	struct intr_event *ie = ppc_ih->ih_event;
+	struct intr_handler *ih;
+	int error = 0, thread;
+
+	if (ie == NULL) {
+		intr_stray_handler(ppc_ih);
+		return;
+	}
+  
+	atomic_add_long(ppc_ih->ih_count, 1);
+
+	/* Execute fast interrupt handlers directly. */
+	thread = 0;
+	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
+		if (!(ih->ih_flags & IH_FAST)) {
+			thread = 1;
+			continue;
+		}
+		CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
+		    ih->ih_handler, ih->ih_argument);
+		ih->ih_handler(ih->ih_argument);
+	}
+
+	/* Schedule a heavyweight interrupt process. */
+	if (thread)
+		error = intr_event_schedule_thread(ie);
 
-	/* XXX wrong thing when using pre-emption ? */
-	if ((intr_handlers[irq].ih_flags & INTR_FAST) != 0)
-		irq_enable(irq);
+	if (error == EINVAL)
+		intr_stray_handler(ppc_ih);
 }
 
 static void
@@ -301,16 +270,3 @@
 	}
 }
 
-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);
-}

--xHFwDpU9dbj6ez1V--



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