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 [email protected], 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;
}