From owner-p4-projects@FreeBSD.ORG Mon Aug 21 14:08:29 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 CD0D316A4E9; Mon, 21 Aug 2006 14:08:28 +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 A838B16A4E6 for ; Mon, 21 Aug 2006 14:08:28 +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 545D643D53 for ; Mon, 21 Aug 2006 14:08:28 +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 k7LE8SQX096471 for ; Mon, 21 Aug 2006 14:08:28 GMT (envelope-from piso@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7LE8RX2096468 for perforce@freebsd.org; Mon, 21 Aug 2006 14:08:27 GMT (envelope-from piso@freebsd.org) Date: Mon, 21 Aug 2006 14:08:27 GMT Message-Id: <200608211408.k7LE8RX2096468@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 104687 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: Mon, 21 Aug 2006 14:08:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=104687 Change 104687 by piso@piso_newluxor on 2006/08/21 14:07:35 Fill the missing MD bits for stray detection: the low level ie_enable() and ie_pending() are still missing for archs !i386 and !amd64, but someone with knowlegde of the different interrupt controllers could write them very quickly. Looks like arm doesn't have any mutex to protect the global interrupt event table... Affected files ... .. //depot/projects/soc2006/intr_filter/amd64/amd64/intr_machdep.c#7 edit .. //depot/projects/soc2006/intr_filter/arm/arm/intr.c#6 edit .. //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#13 edit .. //depot/projects/soc2006/intr_filter/ia64/ia64/interrupt.c#7 edit .. //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#8 edit .. //depot/projects/soc2006/intr_filter/sparc64/sparc64/intr_machdep.c#8 edit Differences ... ==== //depot/projects/soc2006/intr_filter/amd64/amd64/intr_machdep.c#7 (text+ko) ==== @@ -63,6 +63,8 @@ static struct intsrc *interrupt_sources[NUM_IO_INTS]; static struct mtx intr_table_lock; +extern struct callout stray_callout_handle; + #ifdef SMP static int assign_cpu; @@ -168,6 +170,22 @@ return (isrc->is_pic->pic_config_intr(isrc, trig, pol)); } +/* Stray detection MD code */ +static struct intr_event * +walk_intr_src(void) { + struct intsrc *isrc; + static int i = 0; + + for (; iis_event != NULL) + return (isrc->is_event); + } + i = 0; + return (NULL); +} + void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) { @@ -235,6 +253,15 @@ isrc->is_pic->pic_disable_source(isrc, PIC_EOI); critical_exit(); + /* Interrupt storm logic */ + if (thread & FILTER_STRAY) { + printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name); + ie->ie_count = INT_MAX; + mtx_lock_spin(&intr_table_lock); + callout_reset(&stray_callout_handle, hz, &stray_detection, &walk_intr_src); + mtx_unlock_spin(&intr_table_lock); + } + /* Schedule the ithread if needed. */ if (thread & FILTER_SCHEDULE_THREAD) { error = intr_event_schedule_thread(ie); @@ -319,6 +346,7 @@ intrcnt_setname("???", 0); intrcnt_index = 1; mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); + callout_init_mtx(&stray_callout_handle, &intr_table_lock, 0); } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL) ==== //depot/projects/soc2006/intr_filter/arm/arm/intr.c#6 (text+ko) ==== @@ -55,6 +55,8 @@ static int intrcnt_index = 0; static int last_printed = 0; +extern struct callout stray_callout_handle; + void arm_handler_execute(struct trapframe *, int); void @@ -98,6 +100,22 @@ { } +/* Stray detection MD code */ +static struct intr_event * +walk_intr_events(void) { + struct intr_event *ie; + static int i = 0; + + for (; iie_enable == NULL || event->ie_pending == NULL) + printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n"); + else { + printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", event->ie_name); + event->ie_count = INT_MAX; + // XXX missing callout_init_mtx(&stray_callout_handle, ...); + callout_reset(&stray_callout_handle, hz, + &stray_detection, &walk_intr_events); + } + } + // XXX eoi & mask intr not verified. /* Schedule thread if needed. */ if (thread & FILTER_SCHEDULE_THREAD) ==== //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#13 (text+ko) ==== @@ -186,7 +186,7 @@ for (; iis_event != NULL) return (isrc->is_event); } i = 0; ==== //depot/projects/soc2006/intr_filter/ia64/ia64/interrupt.c#7 (text+ko) ==== @@ -255,8 +255,11 @@ volatile long *cntp; /* interrupt counter */ }; +#define IA64_NUMI 256 static struct mtx ia64_intrs_lock; -static struct ia64_intr *ia64_intrs[256]; +static struct ia64_intr *ia64_intrs[IA64_NUMI]; + +extern struct callout stray_callout_handle; extern struct sapic *ia64_sapics[]; extern int ia64_sapic_count; @@ -266,6 +269,7 @@ { mtx_init(&ia64_intrs_lock, "intr table", NULL, MTX_SPIN); + callout_init_mtx(&stray_callout_handle, &ia64_intrs_lock, 0); } SYSINIT(ithds_init, SI_SUB_INTR, SI_ORDER_SECOND, ithds_init, NULL); @@ -347,6 +351,22 @@ return (intr_event_remove_handler(cookie)); } +/* Stray detection MD code */ +static struct intr_event * +walk_intr_ia64(void) { + struct ia64_intr *ia64_i; + static int i = 0; + + for (; ievent != NULL) + return (ia64_i->event); + } + i = 0; + return (NULL); +} + void ia64_dispatch_intr(void *frame __unused, unsigned long vector) { @@ -383,6 +403,20 @@ thread = intr_filter_loop(ie, NULL); critical_exit(); + /* Interrupt storm logic */ + if (thread & FILTER_STRAY) { + if (ie->ie_enable == NULL || ie->ie_pending == NULL) + printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n"); + else { + printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name); + ie->ie_count = INT_MAX; + mtx_lock_spin(&ia64_intrs_lock); + callout_reset(&stray_callout_handle, hz, + &stray_detection, &walk_intr_ia64); + mtx_unlock_spin(&ia64_intrs_lock); + } + } + // XXX eoi & mask intr not verified. if (thread & FILTER_SCHEDULE_THREAD) { error = intr_event_schedule_thread(ie); ==== //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#8 (text+ko) ==== @@ -88,6 +88,8 @@ static struct mtx intr_table_lock; +extern struct callout stray_callout_handle; + extern int extint, extsize; extern u_long extint_call; @@ -165,6 +167,7 @@ irq_disable = irq_d; mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); + callout_init_mtx(&stray_callout_handle, &intr_table_lock, 0); } int @@ -223,6 +226,22 @@ return(intr_event_remove_handler(cookie)); } +/* Stray detection MD code */ +static struct intr_event * +walk_intr_ppc(void) { + struct ppc_intr_handler *ppc; + static int i = 0; + + for (; iih_event != NULL) + return (ppc->ih_event); + } + i = 0; + return (NULL); +} + void intr_handle(u_int irq) { @@ -243,6 +262,20 @@ thread = intr_filter_loop(ie, NULL); critical_exit(); + /* Interrupt storm logic */ + if (thread & FILTER_STRAY) { + if (ie->ie_enable == NULL || ie->ie_pending == NULL) + printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n"); + else { + printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name); + ie->ie_count = INT_MAX; + mtx_lock_spin(&intr_table_lock); + callout_reset(&stray_callout_handle, hz, + &stray_detection, &walk_intr_ppc); + mtx_unlock_spin(&intr_table_lock); + } + } + // XXX eoi & mask intr not verified. /* Schedule a heavyweight interrupt process. */ if (thread & FILTER_SCHEDULE_THREAD) ==== //depot/projects/soc2006/intr_filter/sparc64/sparc64/intr_machdep.c#8 (text+ko) ==== @@ -103,6 +103,8 @@ /* protect the intr_vectors table */ static struct mtx intr_table_lock; +extern struct callout stray_callout_handle; + static void intr_execute_handlers(void *); static void intr_stray_level(struct trapframe *); static void intr_stray_vector(void *); @@ -228,8 +230,25 @@ { mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); + callout_init_mtx(&stray_callout_handle, &intr_table_lock, 0); } +/* Stray detection MD code */ +static struct intr_event * +walk_intr_sparc64(void) { + struct intr_vector *iv; + static int i = 0; + + for (; iiv_event != NULL) + return (iv->iv_event); + } + i = 0; + return (NULL); +} + static void intr_execute_handlers(void *cookie) { @@ -247,6 +266,20 @@ /* Execute fast interrupt handlers directly. */ thread = intr_filter_loop(ie, NULL); + /* Interrupt storm logic */ + if (thread & FILTER_STRAY) { + if (ie->ie_enable == NULL || ie->ie_pending == NULL) + printf("Interrupt stray detection not ready yet: check ie_enable and ie_pending\n"); + else { + printf("Interrupt stray detected on \"%s\"; throttling interrupt source\n", ie->ie_name); + ie->ie_count = INT_MAX; + mtx_lock_spin(&intr_table_lock); + callout_reset(&stray_callout_handle, hz, + &stray_detection, &walk_intr_sparc64); + mtx_unlock_spin(&intr_table_lock); + } + } + // XXX eoi & mask intr not verified. /* Schedule a heavyweight interrupt process. */ if (thread & FILTER_SCHEDULE_THREAD)