---------------------------------------------------------------------- r14917: kmacy | 2008-04-12 01:46:54 -0700 fix WITNESS panic by converting intr_table_lock to sx lock and breaking spin lock out in to a separate lock ---------------------------------------------------------------------- === local/IPSO_Oplin_integration/sys/i386/i386/intr_machdep.c ================================================================== --- local/IPSO_Oplin_integration/sys/i386/i386/intr_machdep.c (revision 14916) +++ local/IPSO_Oplin_integration/sys/i386/i386/intr_machdep.c (revision 14917) @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -69,8 +70,9 @@ static int intrcnt_index; static struct intsrc *interrupt_sources[NUM_IO_INTS]; -static struct mtx intr_table_lock; +static struct sx intr_table_lock; static struct mtx intr_live_lock; +static struct mtx intrcnt_lock; static STAILQ_HEAD(, pic) pics; #ifdef SMP @@ -156,14 +158,14 @@ { int error; - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); if (intr_pic_registered(pic)) error = EBUSY; else { STAILQ_INSERT_TAIL(&pics, pic, pics); error = 0; } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); return (error); } @@ -185,16 +187,16 @@ (mask_fn)isrc->is_pic->pic_enable_source, "irq%d:", vector); if (error) return (error); - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); if (interrupt_sources[vector] != NULL) { - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); intr_event_destroy(isrc->is_event); return (EEXIST); } intrcnt_register(isrc); interrupt_sources[vector] = isrc; isrc->is_enabled = 0; - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); return (0); } @@ -225,7 +227,7 @@ idx = vector >> INTR_IDX_SHIFT; mask = 1 << (vector & INTR_BIT_MASK); - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); if (flags & (INTR_TYPE_CLK | INTR_TYPE_TTY | INTR_DIRECT)) { /* @@ -247,10 +249,10 @@ if (assign_cpu) intr_assign_next_cpu(isrc); #endif - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); isrc->is_pic->pic_enable_intr(isrc); } else - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); isrc->is_pic->pic_enable_source(isrc); } return (error); @@ -712,12 +714,12 @@ { struct pic *pic; - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); STAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_resume != NULL) pic->pic_resume(pic); } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); } void @@ -725,12 +727,12 @@ { struct pic *pic; - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); STAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_suspend != NULL) pic->pic_suspend(pic); } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); } static void @@ -755,6 +757,8 @@ /* mtx_assert(&intr_table_lock, MA_OWNED); */ KASSERT(is->is_event != NULL, ("%s: isrc with no event", __func__)); + + mtx_lock_spin(&intrcnt_lock); is->is_index = intrcnt_index; intrcnt_index += 2; snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", @@ -763,17 +767,18 @@ is->is_count = &intrcnt[is->is_index]; intrcnt_setname(straystr, is->is_index + 1); is->is_straycount = &intrcnt[is->is_index + 1]; + mtx_unlock_spin(&intrcnt_lock); } void intrcnt_add(const char *name, u_long **countp) { - mtx_lock_spin(&intr_table_lock); + mtx_lock_spin(&intrcnt_lock); *countp = &intrcnt[intrcnt_index]; intrcnt_setname(name, intrcnt_index); intrcnt_index++; - mtx_unlock_spin(&intr_table_lock); + mtx_unlock_spin(&intrcnt_lock); } static void @@ -784,8 +789,9 @@ intrcnt_setname("???", 0); intrcnt_index = 1; STAILQ_INIT(&pics); - mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); + sx_init(&intr_table_lock, "intr sources"); mtx_init(&intr_live_lock, "intr live", NULL, MTX_SPIN); + mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN); for (idx = 0; idx < INTR_ARR_LEN; idx++) { intr_live_mask_proto[idx] = ~0; @@ -1149,14 +1155,14 @@ return; /* Round-robin assign a CPU to each enabled source. */ - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); assign_cpu = 1; for (i = 0; i < NUM_IO_INTS; i++) { isrc = interrupt_sources[i]; if (isrc != NULL && isrc->is_enabled) intr_assign_next_cpu(isrc); } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); } SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs, NULL) #endif