Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Dec 2003 17:57:53 -0800 (PST)
From:      Nate Lawson <nate@root.org>
To:        current@freebsd.org
Cc:        acpi-jp@jp.freebsd.org
Subject:   ACPI throttling changes
Message-ID:  <20031209175230.I44055@root.org>

next in thread | raw e-mail | index | archive | help
I'm working on a shared CPU frequency control driver.  One step is to
remove some of the autonomy of the throttling portion of acpi_cpu.
Please test this patch if you have a machine which supports throttling.
With this patch, throttling can be changed by doing:

   sysctl hw.acpi.cpu.current_speed=X

where X is some number between 1 and hw.acpi.cpu.max_speed.  It is no
longer driven by AC line transitions.  Run a CPU benchmark like this one
to make sure the throttling transition still works with this patch.

    dd if=/dev/zero bs=1m count=500 | md5

This is part of a larger work.  Don't worry, it won't be committed until
general CPU frequency control is done so no loss of functionality will be
committed.

-Nate

Index: sys/dev/acpica/acpi_cpu.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpica/acpi_cpu.c,v
retrieving revision 1.24
diff -u -r1.24 acpi_cpu.c
--- sys/dev/acpica/acpi_cpu.c	9 Dec 2003 03:01:54 -0000	1.24
+++ sys/dev/acpica/acpi_cpu.c	10 Dec 2003 01:40:29 -0000
@@ -135,8 +135,6 @@

 /* Values for sysctl. */
 static uint32_t		 cpu_current_state;
-static uint32_t		 cpu_performance_state;
-static uint32_t		 cpu_economy_state;
 static uint32_t		 cpu_max_state;
 static int		 cpu_cx_lowest;
 static char 		 cpu_cx_supported[64];
@@ -165,7 +163,6 @@
 static void	acpi_pm_ticksub(uint32_t *end, const uint32_t *start);
 static void	acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context);
 static int	acpi_cpu_quirks(struct acpi_cpu_softc *sc);
-static void	acpi_cpu_power_profile(void *arg);
 static int	acpi_cpu_throttle_sysctl(SYSCTL_HANDLER_ARGS);
 static int	acpi_cpu_history_sysctl(SYSCTL_HANDLER_ARGS);
 static int	acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
@@ -616,10 +613,6 @@
     /* Get set of CPU devices */
     devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices);

-    /* Register performance profile change handler */
-    EVENTHANDLER_REGISTER(power_profile_change, acpi_cpu_power_profile,
-			  NULL, 0);
-
     /*
      * Make sure all the processors' Cx counts match.  We should probably
      * also check the contents of each.  However, no known systems have
@@ -647,56 +640,30 @@
 static void
 acpi_cpu_startup_throttling()
 {
-    int cpu_temp_speed;
     ACPI_LOCK_DECL;

     /* Initialise throttling states */
     cpu_max_state = CPU_MAX_SPEED;
-    cpu_performance_state = cpu_max_state;
-    cpu_economy_state = cpu_performance_state / 2;
-
-    /* 0 is 'reserved' */
-    if (cpu_economy_state == 0)
-	cpu_economy_state++;
-    if (TUNABLE_INT_FETCH("hw.acpi.cpu.performance_speed", &cpu_temp_speed) &&
-	cpu_temp_speed > 0 && cpu_temp_speed <= cpu_max_state) {
-
-	cpu_performance_state = cpu_temp_speed;
-    }
-    if (TUNABLE_INT_FETCH("hw.acpi.cpu.economy_speed", &cpu_temp_speed) &&
-	cpu_temp_speed > 0 && cpu_temp_speed <= cpu_max_state) {
-
-	cpu_economy_state = cpu_temp_speed;
-    }
+    cpu_current_state = CPU_MAX_SPEED;

     SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
 		   SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
 		   OID_AUTO, "max_speed", CTLFLAG_RD,
 		   &cpu_max_state, 0, "maximum CPU speed");
-    SYSCTL_ADD_INT(&acpi_cpu_sysctl_ctx,
-		   SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		   OID_AUTO, "current_speed", CTLFLAG_RD,
-		   &cpu_current_state, 0, "current CPU speed");
     SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
 		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		    OID_AUTO, "performance_speed",
-		    CTLTYPE_INT | CTLFLAG_RW, &cpu_performance_state,
-		    0, acpi_cpu_throttle_sysctl, "I", "");
-    SYSCTL_ADD_PROC(&acpi_cpu_sysctl_ctx,
-		    SYSCTL_CHILDREN(acpi_cpu_sysctl_tree),
-		    OID_AUTO, "economy_speed",
-		    CTLTYPE_INT | CTLFLAG_RW, &cpu_economy_state,
-		    0, acpi_cpu_throttle_sysctl, "I", "");
+		    OID_AUTO, "current_speed",
+		    CTLTYPE_INT | CTLFLAG_RW, &cpu_current_state,
+		    0, acpi_cpu_throttle_sysctl, "I", "current CPU speed");

     /* If ACPI 2.0+, signal platform that we are taking over throttling. */
-    if (cpu_pstate_cnt != 0) {
-	ACPI_LOCK;
+    ACPI_LOCK;
+    if (cpu_pstate_cnt != 0)
 	AcpiOsWritePort(cpu_smi_cmd, cpu_pstate_cnt, 8);
-	ACPI_UNLOCK;
-    }

-    /* Set initial speed */
-    acpi_cpu_power_profile(NULL);
+    /* Set initial speed to maximum. */
+    acpi_cpu_throttle_set(cpu_max_state);
+    ACPI_UNLOCK;

     printf("acpi_cpu: throttling enabled, %d steps (100%% to %d.%d%%), "
 	   "currently %d.%d%%\n", CPU_MAX_SPEED, CPU_SPEED_PRINTABLE(1),
@@ -1026,54 +993,14 @@
     return (0);
 }

-/*
- * Power profile change hook.
- *
- * Uses the ACPI lock to avoid reentrancy.
- */
-static void
-acpi_cpu_power_profile(void *arg)
-{
-    int		state;
-    uint32_t	new;
-    ACPI_LOCK_DECL;
-
-    state = power_profile_get_state();
-    if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY)
-	return;
-
-    ACPI_LOCK;
-
-    switch (state) {
-    case POWER_PROFILE_PERFORMANCE:
-	new = cpu_performance_state;
-	break;
-    case POWER_PROFILE_ECONOMY:
-	new = cpu_economy_state;
-	break;
-    default:
-	new = cpu_current_state;
-	break;
-    }
-
-    if (cpu_current_state != new)
-	acpi_cpu_throttle_set(new);
-
-    ACPI_UNLOCK;
-}
-
-/*
- * Handle changes in the performance/ecomony CPU settings.
- *
- * Does not need the ACPI lock (although setting *argp should
- * probably be atomic).
- */
+/* Handle changes in the CPU throttling setting. */
 static int
 acpi_cpu_throttle_sysctl(SYSCTL_HANDLER_ARGS)
 {
     uint32_t	*argp;
     uint32_t	 arg;
     int		 error;
+    ACPI_LOCK_DECL;

     argp = (uint32_t *)oidp->oid_arg1;
     arg = *argp;
@@ -1085,9 +1012,13 @@
     if (arg < 1 || arg > cpu_max_state)
 	return (EINVAL);

-    /* Set new value and possibly switch */
-    *argp = arg;
-    acpi_cpu_power_profile(NULL);
+    /* If throttling changed, notify the BIOS of the new rate. */
+    ACPI_LOCK;
+    if (*argp != arg) {
+	*argp = arg;
+	acpi_cpu_throttle_set(arg);
+    }
+    ACPI_UNLOCK;

     return (0);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031209175230.I44055>