Date: Thu, 3 Aug 2006 13:22:50 GMT From: Paolo Pisati <piso@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 103113 for review Message-ID: <200608031322.k73DModt029697@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103113 Change 103113 by piso@piso_newluxor on 2006/08/03 13:22:23 First implementation of interrupt storm logic for filters: in case an interrupt come, and no filters claim it (and we don't have any ithread_only handler on that line), throttle the line (mask the interrupt and mark the source) and kick off a timeout once per second. Timeout function (when called) will check all the interrupts: if any of these interrupt is marked, check if it is still pending else unmask/unmark the source. If the interrupt is still pending, call filters and if any of them claim the interrupt, unmask/unmark it. Else, if no filter claims the interrupt, increase the timeout threshold for next check. TODO: -The code is still MD, but i would like to make it MI. -we need tunable timeout tresholds (upper & lower). -filters are called with a NULL frame parameter, while some of them expect to receive a valid trapframe... -i should call callout_drain() but i can't find a place where to do that: i guess we don't do cleanup in this case, case if we need to drain the callout, it means we are shutting down the box, right? Affected files ... .. //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#8 edit Differences ... ==== //depot/projects/soc2006/intr_filter/i386/i386/intr_machdep.c#8 (text+ko) ==== @@ -45,6 +45,7 @@ #include <sys/lock.h> #include <sys/ktr.h> #include <sys/kernel.h> +#include <sys/limits.h> #include <sys/mutex.h> #include <sys/proc.h> #include <sys/syslog.h> @@ -63,6 +64,9 @@ static struct intsrc *interrupt_sources[NUM_IO_INTS]; static struct mtx intr_table_lock; +static struct callout callout_handle; +static int backoff = 1; + #ifdef SMP static int assign_cpu; @@ -165,6 +169,57 @@ return (isrc->is_pic->pic_config_intr(isrc, trig, pol)); } +static struct intsrc * +walk_intr_src(void) { + static int i = 0; + + for (; i<NUM_IO_INTS; i++) { + if (interrupt_sources[i] != NULL) + return (interrupt_sources[i]); + } + i = 0; + return (NULL); +} + +static void +stray_detection(void *arg __unused) +{ + struct intsrc *isrc; + struct intr_event *ie; + int thread; + + /* analyze all the interrupt sources... */ + while ((isrc = walk_intr_src()) != NULL) { + ie = isrc->is_event; + /* is this interrupt marked as being throttled? */ + if (ie != NULL && ie->ie_count == INT_MAX) { + /* and is the interrupt still pending? */ + if (isrc->is_pic->pic_source_pending(isrc)) { + /* + * yes, it's still pending: call filters... + */ + thread = intr_filter_loop(ie, NULL /* XXX frame */ ); + if (thread & FILTER_STRAY) { + /* + * no filter claimed the intr, + * backoff with a longer timeout + */ + backoff++; // XXX we need thresholds... + callout_reset(&callout_handle, hz*backoff, + &stray_detection, NULL); + continue; + } + } + /* + * a filter claimed the intr, or the intr was not + * pending anymore: unmask it + */ + ie->ie_count = 0; + isrc->is_pic->pic_enable_source(isrc); + } + } +} + void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) { @@ -225,6 +280,15 @@ isrc->is_pic->pic_disable_source(isrc, PIC_EOI); critical_exit(); + + /* Interrupt storm logic */ + if (thread & FILTER_STRAY) { + ie->ie_count = INT_MAX; + mtx_lock_spin(&intr_table_lock); + callout_reset(&callout_handle, hz, &stray_detection, NULL); + mtx_unlock_spin(&intr_table_lock); + } + /* Schedule the ithread if needed. */ if (thread & FILTER_SCHEDULE_THREAD) { error = intr_event_schedule_thread(ie); @@ -309,6 +373,8 @@ intrcnt_setname("???", 0); intrcnt_index = 1; mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); + callout_init_mtx(&callout_handle, &intr_table_lock, 0); + // XXX - we don't drain the callout... } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608031322.k73DModt029697>