Module Name:    src
Committed By:   jruoho
Date:           Thu Dec 30 12:05:03 UTC 2010

Modified Files:
        src/sys/dev/acpi: acpi_cpu.c acpi_cpu.h acpi_cpu_pstate.c
            acpi_cpu_tstate.c

Log Message:
Change the default behavior to enforce the maximum frequency when the
firmware requests to do so. This cures severe overhating (> 120 C) observed
on many laptops, being also on par with the specification(s). This can be
reverted by using the new "hw.acpi.cpu.dynamic" sysctl variable.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/acpi/acpi_cpu.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/acpi/acpi_cpu.h
cvs rdiff -u -r1.35 -r1.36 src/sys/dev/acpi/acpi_cpu_pstate.c
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/acpi/acpi_cpu_tstate.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/dev/acpi/acpi_cpu.c
diff -u src/sys/dev/acpi/acpi_cpu.c:1.23 src/sys/dev/acpi/acpi_cpu.c:1.24
--- src/sys/dev/acpi/acpi_cpu.c:1.23	Thu Oct 28 04:28:29 2010
+++ src/sys/dev/acpi/acpi_cpu.c	Thu Dec 30 12:05:02 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.c,v 1.23 2010/10/28 04:28:29 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.c,v 1.24 2010/12/30 12:05:02 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.23 2010/10/28 04:28:29 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.24 2010/12/30 12:05:02 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -36,6 +36,7 @@
 #include <sys/module.h>
 #include <sys/mutex.h>
 #include <sys/once.h>
+#include <sys/sysctl.h>
 
 #include <dev/acpi/acpireg.h>
 #include <dev/acpi/acpivar.h>
@@ -53,6 +54,7 @@
 static int		  acpicpu_once_detach(void);
 static void		  acpicpu_prestart(device_t);
 static void		  acpicpu_start(device_t);
+static void		  acpicpu_sysctl(device_t);
 
 static int		  acpicpu_object(ACPI_HANDLE, struct acpicpu_object *);
 static cpuid_t		  acpicpu_id(uint32_t);
@@ -65,6 +67,9 @@
 static bool		  acpicpu_resume(device_t, const pmf_qual_t *);
 
 struct acpicpu_softc	**acpicpu_sc = NULL;
+static struct sysctllog	 *acpicpu_log = NULL;
+static bool		  acpicpu_dynamic = true;
+static bool		  acpicpu_passive = true;
 
 static const char * const acpicpu_hid[] = {
 	"ACPI0007",
@@ -115,7 +120,6 @@
 
 	sc->sc_dev = self;
 	sc->sc_cold = true;
-	sc->sc_passive = false;
 	sc->sc_node = aa->aa_node;
 	sc->sc_cpuid = acpicpu_id(sc->sc_object.ao_procid);
 
@@ -211,6 +215,9 @@
 	if (acpicpu_sc != NULL)
 		kmem_free(acpicpu_sc, maxcpus * sizeof(*sc));
 
+	if (acpicpu_log != NULL)
+		sysctl_teardown(&acpicpu_log);
+
 	return 0;
 }
 
@@ -250,12 +257,63 @@
 	if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
 		acpicpu_tstate_start(self);
 
+	acpicpu_sysctl(self);
+
 	aprint_debug_dev(sc->sc_dev, "ACPI CPUs started (cap "
 	    "0x%02x, flags 0x%06x)\n", sc->sc_cap, sc->sc_flags);
 
 	sc->sc_cold = false;
 }
 
+static void
+acpicpu_sysctl(device_t self)
+{
+	const struct sysctlnode *node;
+	int err;
+
+	err = sysctl_createv(&acpicpu_log, 0, NULL, &node,
+	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
+	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL);
+
+	if (err != 0)
+		goto fail;
+
+	err = sysctl_createv(&acpicpu_log, 0, &node, &node,
+	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi", NULL,
+	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
+
+	if (err != 0)
+		goto fail;
+
+	err = sysctl_createv(&acpicpu_log, 0, &node, &node,
+	    0, CTLTYPE_NODE, "cpu", SYSCTL_DESCR("ACPI CPU"),
+	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
+
+	if (err != 0)
+		goto fail;
+
+	err = sysctl_createv(&acpicpu_log, 0, &node, NULL,
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "dynamic",
+	    SYSCTL_DESCR("Dynamic states"), NULL, 0,
+	    &acpicpu_dynamic, 0, CTL_CREATE, CTL_EOL);
+
+	if (err != 0)
+		goto fail;
+
+	err = sysctl_createv(&acpicpu_log, 0, &node, NULL,
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "passive",
+	    SYSCTL_DESCR("Passive cooling"), NULL, 0,
+	    &acpicpu_passive, 0, CTL_CREATE, CTL_EOL);
+
+	if (err != 0)
+		goto fail;
+
+	return;
+
+fail:
+	aprint_error_dev(self, "failed to initialize sysctl (err %d)\n", err);
+}
+
 static int
 acpicpu_object(ACPI_HANDLE hdl, struct acpicpu_object *ao)
 {
@@ -492,6 +550,9 @@
 	if (sc->sc_cold != false)
 		return;
 
+	if (acpicpu_dynamic != true)
+		return;
+
 	switch (evt) {
 
 	case ACPICPU_C_NOTIFY:

Index: src/sys/dev/acpi/acpi_cpu.h
diff -u src/sys/dev/acpi/acpi_cpu.h:1.26 src/sys/dev/acpi/acpi_cpu.h:1.27
--- src/sys/dev/acpi/acpi_cpu.h:1.26	Tue Nov 30 04:31:00 2010
+++ src/sys/dev/acpi/acpi_cpu.h	Thu Dec 30 12:05:02 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.h,v 1.26 2010/11/30 04:31:00 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.h,v 1.27 2010/12/30 12:05:02 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi>
@@ -205,7 +205,6 @@
 	uint32_t		 sc_flags;
 	cpuid_t			 sc_cpuid;
 	bool			 sc_cold;
-	bool			 sc_passive;
 };
 
 void		acpicpu_cstate_attach(device_t);

Index: src/sys/dev/acpi/acpi_cpu_pstate.c
diff -u src/sys/dev/acpi/acpi_cpu_pstate.c:1.35 src/sys/dev/acpi/acpi_cpu_pstate.c:1.36
--- src/sys/dev/acpi/acpi_cpu_pstate.c:1.35	Mon Dec 20 08:13:04 2010
+++ src/sys/dev/acpi/acpi_cpu_pstate.c	Thu Dec 30 12:05:02 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_pstate.c,v 1.35 2010/12/20 08:13:04 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_pstate.c,v 1.36 2010/12/30 12:05:02 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.35 2010/12/20 08:13:04 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.36 2010/12/30 12:05:02 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/evcnt.h>
@@ -346,26 +346,24 @@
 	sc = device_private(self);
 
 	mutex_enter(&sc->sc_mtx);
+
 	old = sc->sc_pstate_max;
 	acpicpu_pstate_change(sc);
 	new = sc->sc_pstate_max;
-	mutex_exit(&sc->sc_mtx);
 
-	if (old != new) {
+	if (old == new) {
+		mutex_exit(&sc->sc_mtx);
+		return;
+	}
 
-		aprint_debug_dev(sc->sc_dev, "maximum frequency "
-		    "changed from P%u (%u MHz) to P%u (%u MHz)\n",
-		    old, sc->sc_pstate[old].ps_freq, new,
-		    sc->sc_pstate[sc->sc_pstate_max].ps_freq);
-#if 0
-		/*
-		 * If the maximum changed, proactively
-		 * raise or lower the target frequency.
-		 */
-		(void)acpicpu_pstate_set(sc, sc->sc_pstate[new].ps_freq);
+	mutex_exit(&sc->sc_mtx);
 
-#endif
-	}
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "maximum frequency "
+		"changed from P%u (%u MHz) to P%u (%u MHz)\n",
+		old, sc->sc_pstate[old].ps_freq, new,
+		sc->sc_pstate[sc->sc_pstate_max].ps_freq));
+
+	(void)acpicpu_pstate_set(sc, sc->sc_pstate[new].ps_freq);
 }
 
 ACPI_STATUS
@@ -800,9 +798,17 @@
 	static ACPI_STATUS rv = AE_OK;
 	ACPI_OBJECT_LIST arg;
 	ACPI_OBJECT obj[2];
+	static int val = 0;
 
 	acpicpu_pstate_reset(sc);
 
+	/*
+	 * Cache the checks as the optional
+	 * _PDL and _OST are rarely present.
+	 */
+	if (val == 0)
+		val = acpicpu_pstate_min(sc);
+
 	arg.Count = 2;
 	arg.Pointer = obj;
 
@@ -812,9 +818,6 @@
 	obj[0].Integer.Value = ACPICPU_P_NOTIFY;
 	obj[1].Integer.Value = acpicpu_pstate_max(sc);
 
-	if (sc->sc_passive != false)
-		(void)acpicpu_pstate_min(sc);
-
 	if (ACPI_FAILURE(rv))
 		return;
 

Index: src/sys/dev/acpi/acpi_cpu_tstate.c
diff -u src/sys/dev/acpi/acpi_cpu_tstate.c:1.17 src/sys/dev/acpi/acpi_cpu_tstate.c:1.18
--- src/sys/dev/acpi/acpi_cpu_tstate.c:1.17	Mon Dec 20 08:13:04 2010
+++ src/sys/dev/acpi/acpi_cpu_tstate.c	Thu Dec 30 12:05:02 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_tstate.c,v 1.17 2010/12/20 08:13:04 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_tstate.c,v 1.18 2010/12/30 12:05:02 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_tstate.c,v 1.17 2010/12/20 08:13:04 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_tstate.c,v 1.18 2010/12/30 12:05:02 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/evcnt.h>
@@ -605,9 +605,6 @@
 			sc->sc_tstate_max = val;
 	}
 
-	if (sc->sc_passive != true)
-		return AE_OK;
-
 	rv = acpi_eval_integer(sc->sc_node->ad_handle, "_TDL", &val);
 
 	if (ACPI_SUCCESS(rv) && val < sc->sc_tstate_count) {

Reply via email to