commit 4e5e7e16e476fd728975f72fe906edeaab97f5fa Author: Andriy Gapon Date: Wed Mar 6 09:26:59 2013 +0200 [requirement] turn intr_table_lock and msi_lock into spinlocks... so that they can be acquired after smp_ipi_mtx (smp rendezvous lock). Also fix up witness predefined spinlock order to account for the above. While there, fix order for "entropy harvest mutex" which is passed as a parameter to msleep_spin. diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 1da091a..65c301b 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -646,18 +646,19 @@ static struct witness_order_list_entry order_lists[] = { { "pmc-per-proc", &lock_class_mtx_spin }, #endif { "process slock", &lock_class_mtx_spin }, + { "entropy harvest mutex", &lock_class_mtx_spin }, { "sleepq chain", &lock_class_mtx_spin }, { "umtx lock", &lock_class_mtx_spin }, { "rm_spinlock", &lock_class_mtx_spin }, { "turnstile chain", &lock_class_mtx_spin }, { "turnstile lock", &lock_class_mtx_spin }, - { "sched lock", &lock_class_mtx_spin }, - { "td_contested", &lock_class_mtx_spin }, - { "callout", &lock_class_mtx_spin }, - { "entropy harvest mutex", &lock_class_mtx_spin }, #ifdef SMP { "smp rendezvous", &lock_class_mtx_spin }, #endif + { "intr sources", &lock_class_mtx_spin }, + { "sched lock", &lock_class_mtx_spin }, + { "callout", &lock_class_mtx_spin }, + { "td_contested", &lock_class_mtx_spin }, #ifdef __powerpc__ { "tlb0", &lock_class_mtx_spin }, #endif diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c index e21635f..122c07b 100644 --- a/sys/x86/x86/intr_machdep.c +++ b/sys/x86/x86/intr_machdep.c @@ -120,14 +120,14 @@ intr_register_pic(struct pic *pic) { int error; - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); if (intr_pic_registered(pic)) error = EBUSY; else { TAILQ_INSERT_TAIL(&pics, pic, pics); error = 0; } - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); return (error); } @@ -151,16 +151,16 @@ intr_register_source(struct intsrc *isrc) vector); if (error) return (error); - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); if (interrupt_sources[vector] != NULL) { - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); intr_event_destroy(isrc->is_event); return (EEXIST); } intrcnt_register(isrc); interrupt_sources[vector] = isrc; isrc->is_handlers = 0; - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); return (0); } @@ -184,14 +184,14 @@ intr_add_handler(const char *name, int vector, driver_filter_t filter, error = intr_event_add_handler(isrc->is_event, name, filter, handler, arg, intr_priority(flags), flags, cookiep); if (error == 0) { - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); intrcnt_updatename(isrc); isrc->is_handlers++; if (isrc->is_handlers == 1) { isrc->is_pic->pic_enable_intr(isrc); isrc->is_pic->pic_enable_source(isrc); } - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); } return (error); } @@ -205,14 +205,14 @@ intr_remove_handler(void *cookie) isrc = intr_handler_source(cookie); error = intr_event_remove_handler(cookie); if (error == 0) { - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); isrc->is_handlers--; if (isrc->is_handlers == 0) { isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI); isrc->is_pic->pic_disable_intr(isrc); } intrcnt_updatename(isrc); - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); } return (error); } @@ -286,12 +286,12 @@ intr_resume(void) #ifndef DEV_ATPIC atpic_reset(); #endif - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); TAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_resume != NULL) pic->pic_resume(pic); } - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); } void @@ -299,12 +299,12 @@ intr_suspend(void) { struct pic *pic; - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); TAILQ_FOREACH_REVERSE(pic, &pics, pics_head, pics) { if (pic->pic_suspend != NULL) pic->pic_suspend(pic); } - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); } static int @@ -320,9 +320,9 @@ intr_assign_cpu(void *arg, u_char cpu) */ if (assign_cpu && cpu != NOCPU) { isrc = arg; - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); error = isrc->is_pic->pic_assign_cpu(isrc, cpu_apic_ids[cpu]); - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); } else error = 0; return (error); @@ -382,7 +382,7 @@ intr_init(void *dummy __unused) intrcnt_setname("???", 0); intrcnt_index = 1; TAILQ_INIT(&pics); - mtx_init(&intr_table_lock, "intr sources", NULL, MTX_DEF); + mtx_init(&intr_table_lock, "intr sources", NULL, MTX_SPIN); mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN); } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); @@ -530,7 +530,7 @@ intr_shuffle_irqs(void *arg __unused) return; /* Round-robin assign a CPU to each enabled source. */ - mtx_lock(&intr_table_lock); + mtx_lock_spin(&intr_table_lock); assign_cpu = 1; for (i = 0; i < NUM_IO_INTS; i++) { isrc = interrupt_sources[i]; @@ -551,7 +551,7 @@ intr_shuffle_irqs(void *arg __unused) } } - mtx_unlock(&intr_table_lock); + mtx_unlock_spin(&intr_table_lock); } SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs, NULL); diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c index 381f097..7b8017d 100644 --- a/sys/x86/x86/msi.c +++ b/sys/x86/x86/msi.c @@ -286,7 +286,7 @@ msi_init(void) msi_enabled = 1; intr_register_pic(&msi_pic); - mtx_init(&msi_lock, "msi", NULL, MTX_DEF); + mtx_init(&msi_lock, "msi", NULL, MTX_SPIN); } static void @@ -295,14 +295,14 @@ msi_create_source(void) struct msi_intsrc *msi; u_int irq; - mtx_lock(&msi_lock); + mtx_lock_spin(&msi_lock); if (msi_last_irq >= NUM_MSI_INTS) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return; } irq = msi_last_irq + FIRST_MSI_INT; msi_last_irq++; - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); msi = malloc(sizeof(struct msi_intsrc), M_MSI, M_WAITOK | M_ZERO); msi->msi_intsrc.is_pic = &msi_pic; @@ -329,7 +329,7 @@ msi_alloc(device_t dev, int count, int maxcount, int *irqs) else mirqs = NULL; again: - mtx_lock(&msi_lock); + mtx_lock_spin(&msi_lock); /* Try to find 'count' free IRQs. */ cnt = 0; @@ -353,11 +353,11 @@ again: if (cnt < count) { /* If we would exceed the max, give up. */ if (i + (count - cnt) > FIRST_MSI_INT + NUM_MSI_INTS) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); free(mirqs, M_MSI); return (ENXIO); } - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); /* We need count - cnt more sources. */ while (cnt < count) { @@ -374,7 +374,7 @@ again: cpu = intr_next_cpu(); vector = apic_alloc_vectors(cpu, irqs, count, maxcount); if (vector == 0) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); free(mirqs, M_MSI); return (ENOSPC); } @@ -399,7 +399,7 @@ again: if (count > 1) bcopy(irqs, mirqs, count * sizeof(*mirqs)); fsrc->msi_irqs = mirqs; - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (0); } @@ -410,22 +410,22 @@ msi_release(int *irqs, int count) struct msi_intsrc *msi, *first; int i; - mtx_lock(&msi_lock); + mtx_lock_spin(&msi_lock); first = (struct msi_intsrc *)intr_lookup_source(irqs[0]); if (first == NULL) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENOENT); } /* Make sure this isn't an MSI-X message. */ if (first->msi_msix) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (EINVAL); } /* Make sure this message is allocated to a group. */ if (first->msi_first == NULL) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENXIO); } @@ -434,7 +434,7 @@ msi_release(int *irqs, int count) * the entire group. */ if (first->msi_first != first || first->msi_count != count) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (EINVAL); } KASSERT(first->msi_dev != NULL, ("unowned group")); @@ -460,7 +460,7 @@ msi_release(int *irqs, int count) free(first->msi_irqs, M_MSI); first->msi_irqs = NULL; - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (0); } @@ -469,16 +469,16 @@ msi_map(int irq, uint64_t *addr, uint32_t *data) { struct msi_intsrc *msi; - mtx_lock(&msi_lock); + mtx_lock_spin(&msi_lock); msi = (struct msi_intsrc *)intr_lookup_source(irq); if (msi == NULL) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENOENT); } /* Make sure this message is allocated to a device. */ if (msi->msi_dev == NULL) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENXIO); } @@ -489,7 +489,7 @@ msi_map(int irq, uint64_t *addr, uint32_t *data) */ if (!msi->msi_msix) { if (msi->msi_first == NULL) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENXIO); } msi = msi->msi_first; @@ -497,7 +497,7 @@ msi_map(int irq, uint64_t *addr, uint32_t *data) *addr = INTEL_ADDR(msi); *data = INTEL_DATA(msi); - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (0); } @@ -512,7 +512,7 @@ msix_alloc(device_t dev, int *irq) return (ENXIO); again: - mtx_lock(&msi_lock); + mtx_lock_spin(&msi_lock); /* Find a free IRQ. */ for (i = FIRST_MSI_INT; i < FIRST_MSI_INT + NUM_MSI_INTS; i++) { @@ -531,10 +531,10 @@ again: if (msi == NULL) { /* If we would exceed the max, give up. */ if (i + 1 > FIRST_MSI_INT + NUM_MSI_INTS) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENXIO); } - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); /* Create a new source. */ msi_create_source(); @@ -545,7 +545,7 @@ again: cpu = intr_next_cpu(); vector = apic_alloc_vector(cpu, i); if (vector == 0) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENOSPC); } if (bootverbose) @@ -563,7 +563,7 @@ again: msi->msi_irqs = NULL; KASSERT(msi->msi_intsrc.is_handlers == 0, ("dead MSI-X has handlers")); - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); *irq = i; return (0); @@ -574,16 +574,16 @@ msix_release(int irq) { struct msi_intsrc *msi; - mtx_lock(&msi_lock); + mtx_lock_spin(&msi_lock); msi = (struct msi_intsrc *)intr_lookup_source(irq); if (msi == NULL) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (ENOENT); } /* Make sure this is an MSI-X message. */ if (!msi->msi_msix) { - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (EINVAL); } @@ -598,6 +598,6 @@ msix_release(int irq) msi->msi_count = 0; msi->msi_maxcount = 0; - mtx_unlock(&msi_lock); + mtx_unlock_spin(&msi_lock); return (0); }