diff options
author | Gordon Willem Klok <gwk@cvs.openbsd.org> | 2009-06-06 20:37:46 +0000 |
---|---|---|
committer | Gordon Willem Klok <gwk@cvs.openbsd.org> | 2009-06-06 20:37:46 +0000 |
commit | 9fbc0a3e0a7f11f0c75620a563a682d72bee3867 (patch) | |
tree | 98ba179d4f0b4a6155da0e0cdfd6571dfdb90ac6 /sys/arch | |
parent | e6a95b2fa50e7bafb62c6623e2067e6fbf704b1e (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.c | 9 | ||||
-rw-r--r-- | sys/arch/i386/i386/mp_setperf.c | 10 |
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; |