Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/x86 avoid a failure of interrupt affinity when ...



details:   https://anonhg.NetBSD.org/src/rev/064ff0f49270
branches:  trunk
changeset: 819069:064ff0f49270
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Wed Nov 16 07:13:01 2016 +0000

description:
avoid a failure of interrupt affinity when the interrupt is pending.

pointed out and reviewed by ozaki-r@n.o, thanks.

diffstat:

 sys/arch/x86/x86/intr.c |  22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)

diffs (95 lines):

diff -r 2c686d05ea68 -r 064ff0f49270 sys/arch/x86/x86/intr.c
--- a/sys/arch/x86/x86/intr.c   Wed Nov 16 02:03:30 2016 +0000
+++ b/sys/arch/x86/x86/intr.c   Wed Nov 16 07:13:01 2016 +0000
@@ -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 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 @@
         * 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 @@
        int err;
        int pin;
 
+       KASSERT(mutex_owned(&intr_distribute_lock));
        KASSERT(mutex_owned(&cpu_lock));
 
        /* XXX
@@ -1921,12 +1926,8 @@
 
        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 @@
        struct intrsource *isp;
        int slot;
 
+       KASSERT(mutex_owned(&intr_distribute_lock));
        KASSERT(mutex_owned(&cpu_lock));
 
        if (ih == NULL)
@@ -2140,9 +2142,11 @@
        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 @@
        int error;
        struct intrhand *ih;
 
+       mutex_enter(&intr_distribute_lock);
        mutex_enter(&cpu_lock);
 
        ih = intr_get_handler(intrid);
@@ -2168,6 +2173,7 @@
 
  out:
        mutex_exit(&cpu_lock);
+       mutex_exit(&intr_distribute_lock);
        return error;
 }
 



Home | Main Index | Thread Index | Old Index