Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Mar 2007 17:01:49 GMT
From:      Paolo Pisati <piso@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 115615 for review
Message-ID:  <200703091701.l29H1nCN092201@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=115615

Change 115615 by piso@piso_newluxor on 2007/03/09 17:01:12

	Bring back old MD interrupt handling code, merge it with new
	interrupt filtering code, and appropriately #ifdef ... #endif 
	both worlds.

Affected files ...

.. //depot/projects/soc2006/intr_filter/arm/arm/intr.c#23 edit
.. //depot/projects/soc2006/intr_filter/ia64/ia64/interrupt.c#26 edit
.. //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#31 edit
.. //depot/projects/soc2006/intr_filter/sparc64/sparc64/intr_machdep.c#26 edit
.. //depot/projects/soc2006/intr_filter/sun4v/sun4v/intr_machdep.c#11 edit

Differences ...

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

@@ -59,7 +59,9 @@
 
 void	arm_handler_execute(struct trapframe *, int);
 
+#ifdef INTR_FILTER
 static void intr_disab_eoi_src(void *arg);
+#endif
 
 extern struct bus_space i80321_bs_tag;
 
@@ -74,9 +76,14 @@
 		return;
 	event = intr_events[irq];
 	if (event == NULL) {
+#ifdef INTR_FILTER
 		error = intr_event_create(&event, (void *)irq, 0,
 		    (void (*)(void *))arm_unmask_irq, NULL,
 		    intr_disab_eoi_src, "intr%d:", irq);
+#else
+		error = intr_event_create(&event, (void *)irq, 0,
+		    (void (*)(void *))arm_unmask_irq, "intr%d:", irq);
+#endif
 		if (error)
 			return;
 		intr_events[irq] = event;
@@ -105,6 +112,7 @@
 {
 }
 
+#ifdef INTR_FILTER
 static void
 intr_disab_eoi_src(void *arg)
 {
@@ -127,3 +135,40 @@
 		intr_event_handle(event, frame);
 	}
 }
+#else
+void
+arm_handler_execute(struct trapframe *frame, int irqnb)
+{
+	struct intr_event *event;
+	struct intr_handler *ih;
+	struct thread *td = curthread;
+	int i, thread;
+
+	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 = 0;
+		TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
+			if (ih->ih_filter == NULL)
+				thread = 1;
+			else
+				ih->ih_filter(ih->ih_argument ?
+				    ih->ih_argument : frame);
+		}
+
+		/* Schedule thread if needed. */
+		if (thread)
+			intr_event_schedule_thread(event);
+		else
+			arm_unmask_irq(i);
+	}
+	td->td_intr_nesting_level--;
+}
+#endif

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

@@ -77,7 +77,9 @@
 #endif
 
 volatile int mc_expected, mc_received;
+#ifdef INTR_FILTER
 static void intr_eoi_src(void *arg);
+#endif
 
 static void 
 dummy_perf(unsigned long vector, struct trapframe *tf)  
@@ -320,9 +322,14 @@
 			memset(intrname, ' ', INTRNAME_LEN - 1);
 			bcopy(name, intrname, strlen(name));
 		}
+#ifdef INTR_FILTER
 		errcode = intr_event_create(&i->event, (void *)vector, 0,
 		    (void (*)(void *))ia64_send_eoi, intr_eoi_src, 
 		    NULL, "intr:");
+#else
+		errcode = intr_event_create(&i->event, (void *)vector, 0,
+		    (void (*)(void *))ia64_send_eoi, "intr:");
+#endif
 		if (errcode) {
 			free(i, M_DEVBUF);
 			return errcode;
@@ -349,6 +356,7 @@
 	return (intr_event_remove_handler(cookie));
 }
 
+#ifdef INTR_FILTER
 static void
 intr_eoi_src(void *arg)
 {
@@ -375,6 +383,59 @@
 	if (intr_event_handle(i->event, frame) != 0)
 		panic("Interrupt vector without an event\n");
 }
+#else
+void
+ia64_dispatch_intr(void *frame, unsigned long vector)
+{
+	struct ia64_intr *i;
+	struct intr_event *ie;			/* our interrupt event */
+	struct intr_handler *ih;
+	int error, thread;
+
+	/*
+	 * Find the interrupt thread for this vector.
+	 */
+	i = ia64_intrs[vector];
+	if (i == NULL)
+		return;			/* no event for this vector */
+
+	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();
+	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);
+		ih->ih_filter(ih->ih_argument);
+	}
+	critical_exit();
+
+	if (thread) {
+		error = intr_event_schedule_thread(ie);
+		KASSERT(error == 0, ("got an impossible stray interrupt"));
+	} else
+		ia64_send_eoi(vector);
+}
+#endif
 
 #ifdef DDB
 

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

@@ -96,7 +96,9 @@
 static int intrcnt_index;
 
 static void (*irq_enable)(uintptr_t);
+#ifdef INTR_FILTER
 static void intr_eoi_src(void *arg);
+#endif
 
 static void
 intrcnt_setname(const char *name, int index)
@@ -153,9 +155,14 @@
 		i = malloc(sizeof(*i), M_INTR, M_NOWAIT);
 		if (i == NULL)
 			return (ENOMEM);
+#ifdef INTR_FILTER
 		error = intr_event_create(&i->event, (void *)irq, 0,
 		    (void (*)(void *))irq_enable, intr_eoi_src, 
 		    NULL, "irq%d:", irq);
+#else
+		error = intr_event_create(&i->event, (void *)irq, 0,
+		    (void (*)(void *))irq_enable, "irq%d:", irq);
+#endif
 		if (error) {
 			free(i, M_INTR);
 			return (error);
@@ -194,6 +201,7 @@
 	return (intr_event_remove_handler(cookie));
 }
 
+#ifdef INTR_FILTER
 static void
 stray_int(u_int irq)
 {
@@ -237,3 +245,60 @@
 	if (intr_event_handle(ie, NULL) != 0)
 		stray_int(irq);
 }
+#else
+void
+intr_handle(u_int irq)
+{
+	struct ppc_intr *i;
+	struct intr_event *ie;
+	struct intr_handler *ih;
+	int error, sched;
+
+	i = ppc_intrs[irq];
+	if (i == NULL)
+		goto stray;
+
+	atomic_add_long(i->cntp, 1);
+
+	ie = i->event;
+	KASSERT(ie != NULL, ("%s: interrupt without an event", __func__));
+
+	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.
+	 */
+	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);
+		ih->ih_filter(ih->ih_argument);
+	}
+	critical_exit();
+
+	if (sched) {
+		error = intr_event_schedule_thread(ie);
+		KASSERT(error == 0, ("%s: impossible stray interrupt",
+		    __func__));
+	} else
+		irq_enable(irq);
+	return;
+
+stray:
+	atomic_add_long(&intrcnt[0], 1);
+	if (intrcnt[0] <= MAX_STRAY_LOG) {
+		printf("stray irq %d\n", irq);
+		if (intrcnt[0] >= MAX_STRAY_LOG) {
+			printf("got %d stray interrupts, not logging anymore\n",
+			       MAX_STRAY_LOG);
+		}
+	}
+}
+#endif

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

@@ -231,6 +231,7 @@
 	mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN);
 }
 
+#ifdef INTR_FILTER
 static void
 intr_execute_handlers(void *cookie)
 {
@@ -242,6 +243,46 @@
 	if (intr_event_handle(ie, NULL) != 0)
 		intr_stray_vector(iv);
 }
+#else
+static void
+intr_execute_handlers(void *cookie)
+{
+	struct intr_vector *iv;
+	struct intr_event *ie;
+	struct intr_handler *ih;
+	int error, thread;
+
+	iv = cookie;
+	ie = iv->iv_event;
+	if (ie == NULL) {
+		intr_stray_vector(iv);
+		return;
+	}
+
+	/* Execute fast interrupt handlers directly. */
+	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);
+		ih->ih_filter(ih->ih_argument);
+	}
+
+	/* 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;
+	if (error == EINVAL)
+		intr_stray_vector(iv);
+}
+#endif
 
 int
 inthand_add(const char *name, int vec, driver_filter_t *filt, 
@@ -261,8 +302,13 @@
 	ie = iv->iv_event;
 	mtx_unlock_spin(&intr_table_lock);
 	if (ie == NULL) {
+#ifdef INTR_FILTER
 		errcode = intr_event_create(&ie, (void *)(intptr_t)vec, 0,
 		    NULL, NULL, NULL, "vec%d:", vec);
+#else
+		errcode = intr_event_create(&ie, (void *)(intptr_t)vec, 0,
+		    NULL, "vec%d:", vec);
+#endif
 		if (errcode)
 			return (errcode);
 		mtx_lock_spin(&intr_table_lock);

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

@@ -275,7 +275,8 @@
 
 }
 SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL);
-#if 0
+
+#ifndef INTR_FILTER
 static void
 intr_execute_handlers(void *cookie)
 {
@@ -313,8 +314,7 @@
 			hv_intr_setstate(iv->iv_vec, HV_INTR_IDLE_STATE);
 	}
 }
-#endif
-
+#else
 static void
 intr_execute_handlers(void *cookie)
 {
@@ -332,6 +332,7 @@
 	 * hv_intr_setstate(iv->iv_vec, HV_INTR_IDLE_STATE);
 	 */
 }
+#endif
 
 int
 inthand_add(const char *name, int vec, driver_filter_t *filt,
@@ -353,9 +354,13 @@
 	ie = iv->iv_event;
 	mtx_unlock_spin(&intr_table_lock);
 	if (ie == NULL) {
+#ifdef INTR_FILTER
 		errcode = intr_event_create(&ie, (void *)(intptr_t)vec, 0,
-		    NULL, NULL, NULL, "vec%d:",
-		    vec);
+		    NULL, NULL, NULL, "vec%d:", vec);
+#else
+		errcode = intr_event_create(&ie, (void *)(intptr_t)vec, 0,
+		    NULL, "vec%d:", vec);
+#endif
 		if (errcode)
 			return (errcode);
 		mtx_lock_spin(&intr_table_lock);



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