Date: Sat, 10 Jun 2006 11:53:56 GMT From: Paolo Pisati <piso@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 98908 for review Message-ID: <200606101153.k5ABruNr022430@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=98908 Change 98908 by piso@piso_newluxor on 2006/06/10 11:53:48 Fix support for multiple fast handlers: not tested though. While here, refactor&cleanup a bit the code (rename struct ppc_intr_handler variables to ppc_ih, and struct intr_handler vars to ih, etcetc). Reviewed by: Awaiting for Peter Grehan review Affected files ... .. //depot/projects/soc2006/intr_filter/powerpc/include/intr_machdep.h#2 edit .. //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#2 edit Differences ... ==== //depot/projects/soc2006/intr_filter/powerpc/include/intr_machdep.h#2 (text+ko) ==== @@ -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; ==== //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#2 (text+ko) ==== @@ -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); @@ -110,26 +108,26 @@ } static void -intrcnt_updatename(struct ppc_intr_handler *ih) +intrcnt_updatename(struct ppc_intr_handler *ppc_ih) { - intrcnt_setname(ih->ih_event->ie_fullname, ih->ih_index); + intrcnt_setname(ppc_ih->ih_event->ie_fullname, ppc_ih->ih_index); } static void -intrcnt_register(struct ppc_intr_handler *ih) +intrcnt_register(struct ppc_intr_handler *ppc_ih) { char straystr[MAXCOMLEN + 1]; - KASSERT(ih->ih_event != NULL, + KASSERT(ppc_ih->ih_event != NULL, ("%s: ppc_intr_handler with no event", __func__)); - ih->ih_index = intrcnt_index; + ppc_ih->ih_index = intrcnt_index; intrcnt_index += 2; - snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ih->ih_irq); - intrcnt_updatename(ih); - ih->ih_count = &intrcnt[ih->ih_index]; - intrcnt_setname(straystr, ih->ih_index + 1); - ih->ih_straycount = &intrcnt[ih->ih_index + 1]; + snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ppc_ih->ih_irq); + intrcnt_updatename(ppc_ih); + ppc_ih->ih_count = &intrcnt[ppc_ih->ih_index]; + intrcnt_setname(straystr, ppc_ih->ih_index + 1); + ppc_ih->ih_straycount = &intrcnt[ppc_ih->ih_index + 1]; } void @@ -139,10 +137,9 @@ 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, @@ -150,14 +147,9 @@ 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,38 +167,21 @@ 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) { - struct ppc_intr_handler *ih; + struct ppc_intr_handler *ppc_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 * handlers on the same IRQ at the same time. */ - ih = &intr_handlers[irq]; + ppc_ih = &intr_handlers[irq]; mtx_lock_spin(&intr_table_lock); - event = ih->ih_event; + event = ppc_ih->ih_event; mtx_unlock_spin(&intr_table_lock); if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, @@ -216,103 +191,83 @@ mtx_lock_spin(&intr_table_lock); - if (ih->ih_event == NULL) { - ih->ih_event = event; - created_event++; + if (ppc_ih->ih_event == NULL) { + ppc_ih->ih_event = event; mtx_unlock_spin(&intr_table_lock); } else { orphan = event; - event = ih->ih_event; + event = ppc_ih->ih_event; mtx_unlock_spin(&intr_table_lock); intr_event_destroy(orphan); } } - /* 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); - error = 0; - } - if (error) return (error); - if (flags & INTR_FAST) - intr_setup(irq, handler, arg, flags); + intrcnt_register(ppc_ih); - intrcnt_register(ih); - return (0); } int inthand_remove(u_int irq, void *cookie) { - struct ppc_intr_handler *ih; - int error; + + return(intr_event_remove_handler(cookie)); +} - error = intr_event_remove_handler(cookie); +void +intr_handle(u_int irq) +{ + struct ppc_intr_handler *ppc_ih = &intr_handlers[irq]; + struct intr_event *ie = ppc_ih->ih_event; + struct intr_handler *ih; + int error, thread; - if (error == 0) { - ih = &intr_handlers[irq]; + if (ie == NULL) { + intr_stray_handler(ppc_ih); + return; + } - mtx_lock_spin(&intr_table_lock); + atomic_add_long(ppc_ih->ih_count, 1); - if (ih->ih_event == NULL) { - intr_setup(irq, intr_stray_handler, ih, 0); - } else { - intr_setup(irq, sched_ithd, ih, 0); + critical_enter(); + /* Execute fast interrupt handlers directly. */ + thread = 0; + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { + if (!(ih->ih_flags & IH_FAST)) { + thread = 1; + continue; } - - mtx_unlock_spin(&intr_table_lock); + CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__, + ih->ih_handler, ih->ih_argument); + ih->ih_handler(ih->ih_argument); } + critical_exit(); + + /* Schedule a heavyweight interrupt process. */ + if (thread) + error = intr_event_schedule_thread(ie); - return (error); + if (error == EINVAL) + intr_stray_handler(ppc_ih); } -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); - - /* XXX wrong thing when using pre-emption ? */ - if ((intr_handlers[irq].ih_flags & INTR_FAST) != 0) - irq_enable(irq); -} - static void intr_stray_handler(void *cookie) { - struct ppc_intr_handler *ih; + struct ppc_intr_handler *ppc_ih = cookie; - ih = (struct ppc_intr_handler *)cookie; + if (*intr_handlers[ppc_ih->ih_irq].ih_straycount < MAX_STRAY_LOG) { + printf("stray irq %d\n", ppc_ih->ih_irq); - if (*intr_handlers[ih->ih_irq].ih_straycount < MAX_STRAY_LOG) { - printf("stray irq %d\n", ih->ih_irq); - - atomic_add_long(intr_handlers[ih->ih_irq].ih_straycount, 1); - if (*intr_handlers[ih->ih_irq].ih_straycount >= MAX_STRAY_LOG) + atomic_add_long(intr_handlers[ppc_ih->ih_irq].ih_straycount, 1); + if (*intr_handlers[ppc_ih->ih_irq].ih_straycount >= MAX_STRAY_LOG) printf("got %d stray irq %d's: not logging anymore\n", - MAX_STRAY_LOG, ih->ih_irq); + MAX_STRAY_LOG, ppc_ih->ih_irq); } } -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); -}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606101153.k5ABruNr022430>