From owner-p4-projects@FreeBSD.ORG Sat Jun 10 16:35:37 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 78C2F16A6AB; Sat, 10 Jun 2006 16:35:37 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3E1EC16A62E for ; Sat, 10 Jun 2006 16:35:37 +0000 (UTC) (envelope-from piso@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D4FA846AC0 for ; Sat, 10 Jun 2006 11:56:01 +0000 (GMT) (envelope-from piso@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k5ABruKj022433 for ; Sat, 10 Jun 2006 11:53:56 GMT (envelope-from piso@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k5ABruNr022430 for perforce@freebsd.org; Sat, 10 Jun 2006 11:53:56 GMT (envelope-from piso@freebsd.org) Date: Sat, 10 Jun 2006 11:53:56 GMT Message-Id: <200606101153.k5ABruNr022430@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to piso@freebsd.org using -f From: Paolo Pisati To: Perforce Change Reviews Cc: Subject: PERFORCE change 98908 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Jun 2006 16:35:37 -0000 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 #include #include +#include #include #include #include @@ -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); -}