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

Reply via email to