Module Name: src Committed By: knakahara Date: Wed Nov 16 07:13:01 UTC 2016
Modified Files: src/sys/arch/x86/x86: intr.c Log Message: avoid a failure of interrupt affinity when the interrupt is pending. pointed out and reviewed by ozaki-r@n.o, thanks. To generate a diff of this commit: cvs rdiff -u -r1.94 -r1.95 src/sys/arch/x86/x86/intr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/x86/intr.c diff -u src/sys/arch/x86/x86/intr.c:1.94 src/sys/arch/x86/x86/intr.c:1.95 --- src/sys/arch/x86/x86/intr.c:1.94 Mon Jul 11 23:09:34 2016 +++ src/sys/arch/x86/x86/intr.c Wed Nov 16 07:13:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.94 2016/07/11 23:09:34 knakahara Exp $ */ +/* $NetBSD: intr.c,v 1.95 2016/11/16 07:13:01 knakahara Exp $ */ /*- * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -133,7 +133,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.94 2016/07/11 23:09:34 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.95 2016/11/16 07:13:01 knakahara Exp $"); #include "opt_intrdebug.h" #include "opt_multiprocessor.h" @@ -210,6 +210,8 @@ static void intr_calculatemasks(struct c static SIMPLEQ_HEAD(, intrsource) io_interrupt_sources = SIMPLEQ_HEAD_INITIALIZER(io_interrupt_sources); +static kmutex_t intr_distribute_lock; + #if NIOAPIC > 0 || NACPICA > 0 static int intr_scan_bus(int, int, intr_handle_t *); #if NPCI > 0 @@ -273,6 +275,8 @@ intr_default_setup(void) * Eventually might want to check if it's actually there. */ i8259_default_setup(); + + mutex_init(&intr_distribute_lock, MUTEX_DEFAULT, IPL_NONE); } /* @@ -1876,6 +1880,7 @@ intr_set_affinity(struct intrsource *isp int err; int pin; + KASSERT(mutex_owned(&intr_distribute_lock)); KASSERT(mutex_owned(&cpu_lock)); /* XXX @@ -1921,12 +1926,8 @@ intr_set_affinity(struct intrsource *isp pin = isp->is_pin; (*pic->pic_hwmask)(pic, pin); /* for ci_ipending check */ - if (oldci->ci_ipending & (1 << oldslot)) { - (*pic->pic_hwunmask)(pic, pin); - DPRINTF(("pin %d on cpuid %ld has pending interrupts.\n", - pin, oldci->ci_cpuid)); - return EBUSY; - } + while(oldci->ci_ipending & (1 << oldslot)) + (void)kpause("intrdist", false, 1, &cpu_lock); kpreempt_disable(); @@ -2116,6 +2117,7 @@ intr_distribute_locked(struct intrhand * struct intrsource *isp; int slot; + KASSERT(mutex_owned(&intr_distribute_lock)); KASSERT(mutex_owned(&cpu_lock)); if (ih == NULL) @@ -2140,9 +2142,11 @@ interrupt_distribute(void *cookie, const int error; struct intrhand *ih = cookie; + mutex_enter(&intr_distribute_lock); mutex_enter(&cpu_lock); error = intr_distribute_locked(ih, newset, oldset); mutex_exit(&cpu_lock); + mutex_exit(&intr_distribute_lock); return error; } @@ -2157,6 +2161,7 @@ interrupt_distribute_handler(const char int error; struct intrhand *ih; + mutex_enter(&intr_distribute_lock); mutex_enter(&cpu_lock); ih = intr_get_handler(intrid); @@ -2168,6 +2173,7 @@ interrupt_distribute_handler(const char out: mutex_exit(&cpu_lock); + mutex_exit(&intr_distribute_lock); return error; }