Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/acpi Add a per ACPI CPU mutex for C-states. Protect ...
details: https://anonhg.NetBSD.org/src/rev/9db3f6d86df4
branches: trunk
changeset: 756721:9db3f6d86df4
user: jruoho <jruoho%NetBSD.org@localhost>
date: Thu Jul 29 22:42:58 2010 +0000
description:
Add a per ACPI CPU mutex for C-states. Protect the _CST update with this:
when the idle-information is being updated (e.g. due acpiacad(4) events),
we can not enter the idle-loop. The lock must run at the same priority
(IPL_NONE) as ACPICA's mutexes obtained via AcpiOsCreateMutex() a.k.a.
AcpiOsCreateSemaphore(). Also check want_resched as the first thing and
clarify the suspend/resume path.
There is still one race condition identified: when the driver is loaded as a
module, we must gracefully kick all CPUs out from the ACPI idle-loop upon
detachment.
diffstat:
sys/dev/acpi/acpi_cpu.c | 9 +++++-
sys/dev/acpi/acpi_cpu.h | 6 +++-
sys/dev/acpi/acpi_cpu_cstate.c | 55 ++++++++++++++++++++++++++++-------------
3 files changed, 48 insertions(+), 22 deletions(-)
diffs (200 lines):
diff -r 4bdc9337ddc1 -r 9db3f6d86df4 sys/dev/acpi/acpi_cpu.c
--- a/sys/dev/acpi/acpi_cpu.c Thu Jul 29 18:36:34 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu.c Thu Jul 29 22:42:58 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.c,v 1.8 2010/07/26 15:14:33 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.c,v 1.9 2010/07/29 22:42:58 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.8 2010/07/26 15:14:33 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.9 2010/07/29 22:42:58 jruoho Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -114,6 +114,7 @@
KASSERT(acpicpu_sc != NULL);
sc->sc_dev = self;
+ sc->sc_cold = false;
sc->sc_iot = aa->aa_iot;
sc->sc_node = aa->aa_node;
sc->sc_cpuid = acpicpu_id(sc->sc_object.ao_procid);
@@ -468,6 +469,8 @@
{
struct acpicpu_softc *sc = device_private(self);
+ sc->sc_cold = true;
+
if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
(void)acpicpu_cstate_suspend(self);
@@ -479,6 +482,8 @@
{
struct acpicpu_softc *sc = device_private(self);
+ sc->sc_cold = false;
+
if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
(void)acpicpu_cstate_resume(self);
diff -r 4bdc9337ddc1 -r 9db3f6d86df4 sys/dev/acpi/acpi_cpu.h
--- a/sys/dev/acpi/acpi_cpu.h Thu Jul 29 18:36:34 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu.h Thu Jul 29 22:42:58 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.h,v 1.6 2010/07/27 05:11:32 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.h,v 1.7 2010/07/29 22:42:58 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -120,14 +120,16 @@
struct acpicpu_softc {
device_t sc_dev;
struct acpi_devnode *sc_node;
+ struct acpicpu_object sc_object;
struct acpicpu_cstate sc_cstate[ACPI_C_STATE_COUNT];
- struct acpicpu_object sc_object;
+ kmutex_t sc_cstate_mtx;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
uint32_t sc_sleep;
uint32_t sc_cpuid;
uint32_t sc_cap;
uint32_t sc_flags;
+ bool sc_cold;
};
/*
diff -r 4bdc9337ddc1 -r 9db3f6d86df4 sys/dev/acpi/acpi_cpu_cstate.c
--- a/sys/dev/acpi/acpi_cpu_cstate.c Thu Jul 29 18:36:34 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu_cstate.c Thu Jul 29 22:42:58 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_cstate.c,v 1.11 2010/07/27 05:11:33 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_cstate.c,v 1.12 2010/07/29 22:42:58 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,13 +27,14 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.11 2010/07/27 05:11:33 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.12 2010/07/29 22:42:58 jruoho Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/once.h>
+#include <sys/mutex.h>
#include <sys/timetc.h>
#include <dev/pci/pcivar.h>
@@ -63,7 +64,6 @@
static void acpicpu_cstate_idle_enter(struct acpicpu_softc *,int);
extern struct acpicpu_softc **acpicpu_sc;
-extern int acpi_suspended;
/*
* XXX: The local APIC timer (as well as TSC) is typically
@@ -101,6 +101,8 @@
acpicpu_cstate_quirks(sc);
acpicpu_cstate_attach_print(sc);
+
+ mutex_init(&sc->sc_cstate_mtx, MUTEX_DEFAULT, IPL_NONE);
}
void
@@ -175,9 +177,19 @@
int
acpicpu_cstate_detach(device_t self)
{
+ struct acpicpu_softc *sc = device_private(self);
static ONCE_DECL(once_detach);
+ int rv;
+
+ rv = RUN_ONCE(&once_detach, acpicpu_md_idle_stop);
- return RUN_ONCE(&once_detach, acpicpu_md_idle_stop);
+ if (rv != 0)
+ return rv;
+
+ sc->sc_flags &= ~ACPICPU_FLAG_C;
+ mutex_destroy(&sc->sc_cstate_mtx);
+
+ return 0;
}
int
@@ -241,9 +253,9 @@
return;
}
- (void)acpicpu_md_idle_stop();
+ mutex_enter(&sc->sc_cstate_mtx);
(void)acpicpu_cstate_cst(sc);
- (void)acpicpu_md_idle_start();
+ mutex_exit(&sc->sc_cstate_mtx);
}
static ACPI_STATUS
@@ -702,6 +714,9 @@
struct acpicpu_softc *sc;
int state;
+ if (__predict_false(ci->ci_want_resched) != 0)
+ return;
+
acpi_md_OsDisableInterrupt();
KASSERT(acpicpu_sc != NULL);
@@ -710,20 +725,19 @@
sc = acpicpu_sc[ci->ci_cpuid];
- /*
- * If all CPUs do not have their ACPI counterparts, the softc
- * may be NULL. In this case fall back to normal C1 with HALT.
- */
- if (__predict_false(sc == NULL)) {
- acpicpu_md_idle_enter(ACPICPU_C_STATE_HALT, ACPI_STATE_C1);
- return;
- }
+ if (__predict_false(sc == NULL))
+ goto halt;
+
+ if (__predict_false(sc->sc_cold != false))
+ goto halt;
- if (__predict_false(acpi_suspended != 0)) {
- acpicpu_md_idle_enter(ACPICPU_C_STATE_HALT, ACPI_STATE_C1);
- return;
- }
+ if (__predict_false((sc->sc_flags & ACPICPU_FLAG_C) == 0))
+ goto halt;
+ if (__predict_false(mutex_tryenter(&sc->sc_cstate_mtx) == 0))
+ goto halt;
+
+ mutex_exit(&sc->sc_cstate_mtx);
state = acpicpu_cstate_latency(sc);
/*
@@ -780,6 +794,11 @@
if ((sc->sc_flags & ACPICPU_FLAG_C_ARB) != 0)
(void)AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 0);
+
+ return;
+
+halt:
+ acpicpu_md_idle_enter(ACPICPU_C_STATE_HALT, ACPI_STATE_C1);
}
static void
Home |
Main Index |
Thread Index |
Old Index