PERFORCE change 115615 for review
Paolo Pisati
piso at FreeBSD.org
Fri Mar 9 17:01:50 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=115615
Change 115615 by piso at 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);
More information about the p4-projects
mailing list