PERFORCE change 115612 for review
Paolo Pisati
piso at FreeBSD.org
Fri Mar 9 16:19:57 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=115612
Change 115612 by piso at piso_newluxor on 2007/03/09 16:18:59
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/amd64/amd64/intr_machdep.c#28 edit
Differences ...
==== //depot/projects/soc2006/intr_filter/amd64/amd64/intr_machdep.c#28 (text+ko) ====
@@ -74,9 +74,11 @@
static struct mtx intr_table_lock;
static STAILQ_HEAD(, pic) pics;
+#ifdef INTR_FILTER
static void intr_eoi_src(void *arg);
static void intr_disab_eoi_src(void *arg);
static void intr_event_stray(void *cookie);
+#endif
#ifdef SMP
static int assign_cpu;
@@ -138,9 +140,14 @@
vector = isrc->is_pic->pic_vector(isrc);
if (interrupt_sources[vector] != NULL)
return (EEXIST);
+#ifdef INTR_FILTER
error = intr_event_create(&isrc->is_event, isrc, 0,
(mask_fn)isrc->is_pic->pic_enable_source,
intr_eoi_src, intr_disab_eoi_src, "irq%d:", vector);
+#else
+ error = intr_event_create(&isrc->is_event, isrc, 0,
+ (mask_fn)isrc->is_pic->pic_enable_source, "irq%d:", vector);
+#endif
if (error)
return (error);
mtx_lock_spin(&intr_table_lock);
@@ -217,6 +224,7 @@
return (isrc->is_pic->pic_config_intr(isrc, trig, pol));
}
+#ifdef INTR_FILTER
void
intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
{
@@ -286,6 +294,94 @@
isrc = arg;
isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
}
+#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;
+
+ 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_LAZY_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;
+
+ /*
+ * For stray interrupts, mask and EOI the source, bump the
+ * stray count, and log the condition.
+ */
+ if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers)) {
+ 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", vector);
+ else if (*isrc->is_straycount == MAX_STRAY_LOG)
+ 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++;
+ 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)
+ ih->ih_filter(frame);
+ else
+ ih->ih_filter(ih->ih_argument);
+ }
+
+ /*
+ * 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);
+ critical_exit();
+
+ /* Schedule the ithread if needed. */
+ if (thread) {
+ error = intr_event_schedule_thread(ie);
+ KASSERT(error == 0, ("bad stray interrupt"));
+ }
+ td->td_intr_nesting_level--;
+}
+#endif
void
intr_resume(void)
More information about the p4-projects
mailing list