Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Mar 2007 16:19:56 GMT
From:      Paolo Pisati <piso@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 115612 for review
Message-ID:  <200703091619.l29GJuu6076400@repoman.freebsd.org>

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

Change 115612 by piso@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)



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