Module Name: src
Committed By: jruoho
Date: Mon Aug 23 16:20:45 UTC 2010
Modified Files:
src/sys/arch/x86/acpi: acpi_cpu_md.c
src/sys/arch/x86/include: machdep.h
src/sys/arch/x86/x86: x86_machdep.c
src/sys/dev/acpi: acpi_cpu.h acpi_cpu_cstate.c
Log Message:
Other entry points beyond x86_cpu_idle_halt() may use HLT as the
idle-mechanism. Send an IPI also for these in cpu_need_resched().
To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/x86/acpi/acpi_cpu_md.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/x86/include/machdep.h
cvs rdiff -u -r1.42 -r1.43 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/acpi/acpi_cpu.h
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/acpi/acpi_cpu_cstate.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/acpi/acpi_cpu_md.c
diff -u src/sys/arch/x86/acpi/acpi_cpu_md.c:1.30 src/sys/arch/x86/acpi/acpi_cpu_md.c:1.31
--- src/sys/arch/x86/acpi/acpi_cpu_md.c:1.30 Sun Aug 22 04:42:57 2010
+++ src/sys/arch/x86/acpi/acpi_cpu_md.c Mon Aug 23 16:20:44 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.30 2010/08/22 04:42:57 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.31 2010/08/23 16:20:44 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <[email protected]>
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.30 2010/08/22 04:42:57 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.31 2010/08/23 16:20:44 jruoho Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -248,14 +248,26 @@
}
int
-acpicpu_md_idle_start(void)
+acpicpu_md_idle_start(struct acpicpu_softc *sc)
{
const size_t size = sizeof(native_idle_text);
+ struct acpicpu_cstate *cs;
+ bool ipi = false;
+ int i;
- x86_disable_intr();
x86_cpu_idle_get(&native_idle, native_idle_text, size);
- x86_cpu_idle_set(acpicpu_cstate_idle, "acpi");
- x86_enable_intr();
+
+ for (i = 0; i < ACPI_C_STATE_COUNT; i++) {
+
+ cs = &sc->sc_cstate[i];
+
+ if (cs->cs_method == ACPICPU_C_STATE_HALT) {
+ ipi = true;
+ break;
+ }
+ }
+
+ x86_cpu_idle_set(acpicpu_cstate_idle, "acpi", ipi);
return 0;
}
@@ -264,10 +276,10 @@
acpicpu_md_idle_stop(void)
{
uint64_t xc;
+ bool ipi;
- x86_disable_intr();
- x86_cpu_idle_set(native_idle, native_idle_text);
- x86_enable_intr();
+ ipi = (native_idle != x86_cpu_idle_halt) ? false : true;
+ x86_cpu_idle_set(native_idle, native_idle_text, ipi);
/*
* Run a cross-call to ensure that all CPUs are
@@ -280,7 +292,8 @@
}
/*
- * The MD idle loop. Called with interrupts disabled.
+ * Called with interrupts disabled.
+ * Caller should enable interrupts after return.
*/
void
acpicpu_md_idle_enter(int method, int state)
@@ -294,7 +307,7 @@
x86_enable_intr();
x86_monitor(&ci->ci_want_resched, 0, 0);
- if (__predict_false(ci->ci_want_resched) != 0)
+ if (__predict_false(ci->ci_want_resched != 0))
return;
x86_mwait((state - 1) << 4, 0);
@@ -302,10 +315,8 @@
case ACPICPU_C_STATE_HALT:
- if (__predict_false(ci->ci_want_resched) != 0) {
- x86_enable_intr();
+ if (__predict_false(ci->ci_want_resched != 0))
return;
- }
x86_stihlt();
break;
Index: src/sys/arch/x86/include/machdep.h
diff -u src/sys/arch/x86/include/machdep.h:1.3 src/sys/arch/x86/include/machdep.h:1.4
--- src/sys/arch/x86/include/machdep.h:1.3 Sun Jul 18 09:29:12 2010
+++ src/sys/arch/x86/include/machdep.h Mon Aug 23 16:20:44 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.h,v 1.3 2010/07/18 09:29:12 jruoho Exp $ */
+/* $NetBSD: machdep.h,v 1.4 2010/08/23 16:20:44 jruoho Exp $ */
/*
* Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -36,7 +36,7 @@
void x86_cpu_idle_init(void);
void x86_cpu_idle_get(void (**)(void), char *, size_t);
-void x86_cpu_idle_set(void (*)(void), const char *);
+void x86_cpu_idle_set(void (*)(void), const char *, bool);
int initx86_parse_memmap(struct btinfo_memmap *, struct extent *);
int initx86_fake_memmap(struct extent *);
Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.42 src/sys/arch/x86/x86/x86_machdep.c:1.43
--- src/sys/arch/x86/x86/x86_machdep.c:1.42 Sun Jul 18 09:29:12 2010
+++ src/sys/arch/x86/x86/x86_machdep.c Mon Aug 23 16:20:45 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_machdep.c,v 1.42 2010/07/18 09:29:12 jruoho Exp $ */
+/* $NetBSD: x86_machdep.c,v 1.43 2010/08/23 16:20:45 jruoho Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.42 2010/07/18 09:29:12 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.43 2010/08/23 16:20:45 jruoho Exp $");
#include "opt_modular.h"
#include "opt_physmem.h"
@@ -63,6 +63,10 @@
#include <uvm/uvm_extern.h>
+void (*x86_cpu_idle)(void);
+static bool x86_cpu_idle_ipi;
+static char x86_cpu_idle_text[16];
+
int check_pa_acc(paddr_t, vm_prot_t);
/* --------------------------------------------------------------------- */
@@ -183,7 +187,7 @@
if (ci == cur)
return;
#ifndef XEN /* XXX review when Xen gets MP support */
- if (x86_cpu_idle == x86_cpu_idle_halt)
+ if (x86_cpu_idle_ipi != false)
x86_send_ipi(ci, 0);
#endif
return;
@@ -314,9 +318,6 @@
}
#endif /* __HAVE_PREEMPTION */
-void (*x86_cpu_idle)(void);
-static char x86_cpu_idle_text[16];
-
SYSCTL_SETUP(sysctl_machdep_cpu_idle, "sysctl machdep cpu_idle")
{
const struct sysctlnode *mnode, *node;
@@ -335,14 +336,15 @@
void
x86_cpu_idle_init(void)
{
+
#ifndef XEN
if ((cpu_feature[1] & CPUID2_MONITOR) == 0 ||
cpu_vendor == CPUVENDOR_AMD)
- x86_cpu_idle_set(x86_cpu_idle_halt, "halt");
+ x86_cpu_idle_set(x86_cpu_idle_halt, "halt", true);
else
- x86_cpu_idle_set(x86_cpu_idle_mwait, "mwait");
+ x86_cpu_idle_set(x86_cpu_idle_mwait, "mwait", false);
#else
- x86_cpu_idle_set(x86_cpu_idle_xen, "xen");
+ x86_cpu_idle_set(x86_cpu_idle_xen, "xen", false);
#endif
}
@@ -356,10 +358,11 @@
}
void
-x86_cpu_idle_set(void (*func)(void), const char *text)
+x86_cpu_idle_set(void (*func)(void), const char *text, bool ipi)
{
x86_cpu_idle = func;
+ x86_cpu_idle_ipi = ipi;
(void)strlcpy(x86_cpu_idle_text, text, sizeof(x86_cpu_idle_text));
}
Index: src/sys/dev/acpi/acpi_cpu.h
diff -u src/sys/dev/acpi/acpi_cpu.h:1.22 src/sys/dev/acpi/acpi_cpu.h:1.23
--- src/sys/dev/acpi/acpi_cpu.h:1.22 Sat Aug 21 06:45:50 2010
+++ src/sys/dev/acpi/acpi_cpu.h Mon Aug 23 16:20:45 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.h,v 1.22 2010/08/21 06:45:50 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.h,v 1.23 2010/08/23 16:20:45 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <[email protected]>
@@ -240,7 +240,7 @@
uint32_t acpicpu_md_cap(void);
uint32_t acpicpu_md_quirks(void);
uint32_t acpicpu_md_cpus_running(void);
-int acpicpu_md_idle_start(void);
+int acpicpu_md_idle_start(struct acpicpu_softc *);
int acpicpu_md_idle_stop(void);
void acpicpu_md_idle_enter(int, int);
int acpicpu_md_pstate_start(void);
Index: src/sys/dev/acpi/acpi_cpu_cstate.c
diff -u src/sys/dev/acpi/acpi_cpu_cstate.c:1.32 src/sys/dev/acpi/acpi_cpu_cstate.c:1.33
--- src/sys/dev/acpi/acpi_cpu_cstate.c:1.32 Sun Aug 22 17:45:48 2010
+++ src/sys/dev/acpi/acpi_cpu_cstate.c Mon Aug 23 16:20:45 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_cstate.c,v 1.32 2010/08/22 17:45:48 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_cstate.c,v 1.33 2010/08/23 16:20:45 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <[email protected]>
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.32 2010/08/22 17:45:48 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.33 2010/08/23 16:20:45 jruoho Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -216,8 +216,9 @@
void
acpicpu_cstate_start(device_t self)
{
+ struct acpicpu_softc *sc = device_private(self);
- (void)acpicpu_md_idle_start();
+ (void)acpicpu_md_idle_start(sc);
}
bool
@@ -653,31 +654,31 @@
void
acpicpu_cstate_idle(void)
{
- struct cpu_info *ci = curcpu();
+ struct cpu_info *ci = curcpu();
struct acpicpu_softc *sc;
int state;
- if (__predict_false(ci->ci_want_resched) != 0)
- return;
-
acpi_md_OsDisableInterrupt();
+ if (__predict_false(ci->ci_want_resched != 0))
+ goto out;
+
KASSERT(acpicpu_sc != NULL);
KASSERT(ci->ci_acpiid < maxcpus);
sc = acpicpu_sc[ci->ci_acpiid];
if (__predict_false(sc == NULL))
- goto halt;
+ goto out;
KASSERT(ci->ci_ilevel == IPL_NONE);
KASSERT((sc->sc_flags & ACPICPU_FLAG_C) != 0);
if (__predict_false(sc->sc_cold != false))
- goto halt;
+ goto out;
if (__predict_false(mutex_tryenter(&sc->sc_mtx) == 0))
- goto halt;
+ goto out;
mutex_exit(&sc->sc_mtx);
state = acpicpu_cstate_latency(sc);
@@ -739,8 +740,8 @@
return;
-halt:
- acpicpu_md_idle_enter(ACPICPU_C_STATE_HALT, ACPI_STATE_C1);
+out:
+ acpi_md_OsEnableInterrupt();
}
static void
@@ -761,18 +762,13 @@
case ACPICPU_C_STATE_SYSIO:
(void)AcpiOsReadPort(cs->cs_addr, &val, 8);
break;
-
- default:
- acpicpu_md_idle_enter(ACPICPU_C_STATE_HALT, ACPI_STATE_C1);
- break;
}
- cs->cs_evcnt.ev_count++;
+ acpi_md_OsEnableInterrupt();
+ cs->cs_evcnt.ev_count++;
end = acpitimer_read_fast(NULL);
sc->sc_cstate_sleep = hztoms(acpitimer_delta(end, start)) * 1000;
-
- acpi_md_OsEnableInterrupt();
}
static bool