Date: Fri, 9 Mar 2007 17:01:49 GMT From: Paolo Pisati <piso@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 115615 for review Message-ID: <200703091701.l29H1nCN092201@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=115615 Change 115615 by piso@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703091701.l29H1nCN092201>