summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorGordon Willem Klok <gwk@cvs.openbsd.org>2009-06-06 20:37:46 +0000
committerGordon Willem Klok <gwk@cvs.openbsd.org>2009-06-06 20:37:46 +0000
commit9fbc0a3e0a7f11f0c75620a563a682d72bee3867 (patch)
tree98ba179d4f0b4a6155da0e0cdfd6571dfdb90ac6 /sys/arch
parente6a95b2fa50e7bafb62c6623e2067e6fbf704b1e (diff)
Disable interrupts durring the lock step frequency/voltage change. Generic
IPIs are handled without blocking interrupts. This solves the random lockups people have been seeing with apmd -C, thanks to marco@ for showing me how to reliably recreate this hang, and claudio@ for telling me it was also affecting his Athlon64 machine so I stopped chasing bugs in est. ok oga@, weingart@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/amd64/mp_setperf.c9
-rw-r--r--sys/arch/i386/i386/mp_setperf.c10
2 files changed, 15 insertions, 4 deletions
diff --git a/sys/arch/amd64/amd64/mp_setperf.c b/sys/arch/amd64/amd64/mp_setperf.c
index 80f0a06de96..4484dc0676b 100644
--- a/sys/arch/amd64/amd64/mp_setperf.c
+++ b/sys/arch/amd64/amd64/mp_setperf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mp_setperf.c,v 1.1 2007/05/06 03:37:08 gwk Exp $ */
+/* $OpenBSD: mp_setperf.c,v 1.2 2009/06/06 20:37:45 gwk Exp $ */
/*
* Copyright (c) 2007 Gordon Willem Klok <gwk@openbsd.org>
*
@@ -50,6 +50,7 @@ mp_setperf(int level)
if (mp_setperf_state == MP_SETPERF_STEADY) {
mtx_enter(&setperf_mp_mutex);
+ disable_intr();
mp_perflevel = level;
curcpu()->ci_setperf_state = CI_SETPERF_INTRANSIT;
@@ -95,6 +96,7 @@ mp_setperf(int level)
DELAY(2);
curcpu()->ci_setperf_state = CI_SETPERF_READY;
mp_setperf_state = MP_SETPERF_STEADY; /* restore normallity */
+ enable_intr();
mtx_leave(&setperf_mp_mutex);
}
@@ -104,6 +106,8 @@ void
x86_setperf_ipi(struct cpu_info *ci)
{
+ disable_intr();
+
if (ci->ci_setperf_state == CI_SETPERF_SHOULDSTOP)
ci->ci_setperf_state = CI_SETPERF_INTRANSIT;
@@ -117,6 +121,8 @@ x86_setperf_ipi(struct cpu_info *ci)
while (mp_setperf_state != MP_SETPERF_FINISH)
;
ci->ci_setperf_state = CI_SETPERF_READY;
+
+ enable_intr();
}
void
@@ -125,7 +131,6 @@ mp_setperf_init()
CPU_INFO_ITERATOR cii;
struct cpu_info *ci;
-
if (!cpu_setperf)
return;
ul_setperf = cpu_setperf;
diff --git a/sys/arch/i386/i386/mp_setperf.c b/sys/arch/i386/i386/mp_setperf.c
index af272b3485c..c325f07732f 100644
--- a/sys/arch/i386/i386/mp_setperf.c
+++ b/sys/arch/i386/i386/mp_setperf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mp_setperf.c,v 1.2 2007/05/01 04:18:32 gwk Exp $ */
+/* $OpenBSD: mp_setperf.c,v 1.3 2009/06/06 20:37:45 gwk Exp $ */
/*
* Copyright (c) 2007 Gordon Willem Klok <gwk@openbsd.org>
*
@@ -50,6 +50,8 @@ mp_setperf(int level)
if (mp_setperf_state == MP_SETPERF_STEADY) {
mtx_enter(&setperf_mp_mutex);
+ disable_intr();
+
mp_perflevel = level;
curcpu()->ci_setperf_state = CI_SETPERF_INTRANSIT;
@@ -95,6 +97,7 @@ mp_setperf(int level)
DELAY(2);
curcpu()->ci_setperf_state = CI_SETPERF_READY;
mp_setperf_state = MP_SETPERF_STEADY; /* restore normallity */
+ enable_intr();
mtx_leave(&setperf_mp_mutex);
}
@@ -104,6 +107,8 @@ void
i386_setperf_ipi(struct cpu_info *ci)
{
+ disable_intr();
+
if (ci->ci_setperf_state == CI_SETPERF_SHOULDSTOP)
ci->ci_setperf_state = CI_SETPERF_INTRANSIT;
@@ -117,6 +122,8 @@ i386_setperf_ipi(struct cpu_info *ci)
while (mp_setperf_state != MP_SETPERF_FINISH)
;
ci->ci_setperf_state = CI_SETPERF_READY;
+
+ enable_intr();
}
void
@@ -125,7 +132,6 @@ mp_setperf_init()
CPU_INFO_ITERATOR cii;
struct cpu_info *ci;
-
if (!cpu_setperf)
return;
ul_setperf = cpu_setperf;