From 62d6ae880e3e76098d5e345decd2dce443975889 Mon Sep 17 00:00:00 2001 From: Carsten Emde Date: Thu, 19 Jul 2012 20:34:10 +0000 Subject: Honor state disabling in the cpuidle ladder governor There are two cpuidle governors ladder and menu. While the ladder governor is always available, if CONFIG_CPU_IDLE is selected, the menu governor additionally requires CONFIG_NO_HZ. A particular C state can be disabled by writing to the sysfs file /sys/devices/system/cpu/cpuN/cpuidle/stateN/disable, but this mechanism is only implemented in the menu governor. Thus, in a system where CONFIG_NO_HZ is not selected, the ladder governor becomes default and always will walk through all sleep states - irrespective of whether the C state was disabled via sysfs or not. The only way to select a specific C state was to write the related latency to /dev/cpu_dma_latency and keep the file open as long as this setting was required - not very practical and not suitable for setting a single core in an SMP system. With this patch, the ladder governor only will promote to the next C state, if it has not been disabled, and it will demote, if the current C state was disabled. Note that the patch does not make the setting of the sysfs variable "disable" coherent, i.e. if one is disabling a light state, then all deeper states are disabled as well, but the "disable" variable does not reflect it. Likewise, if one enables a deep state but a lighter state still is disabled, then this has no effect. A related section has been added to the documentation. Signed-off-by: Carsten Emde Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/governors/ladder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index b6a09ea859b..2aef26c520b 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c @@ -88,6 +88,7 @@ static int ladder_select_state(struct cpuidle_driver *drv, /* consider promotion */ if (last_idx < drv->state_count - 1 && + !dev->states_usage[last_idx + 1].disable && last_residency > last_state->threshold.promotion_time && drv->states[last_idx + 1].exit_latency <= latency_req) { last_state->stats.promotion_count++; @@ -100,7 +101,8 @@ static int ladder_select_state(struct cpuidle_driver *drv, /* consider demotion */ if (last_idx > CPUIDLE_DRIVER_STATE_START && - drv->states[last_idx].exit_latency > latency_req) { + (dev->states_usage[last_idx].disable || + drv->states[last_idx].exit_latency > latency_req)) { int i; for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) { -- cgit v1.2.3-70-g09d2 From 66804c13f7b79fb26cf4848ebac1e865b9aff65c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:28:52 +0200 Subject: PM / cpuidle: Make ladder governor use the "disabled" state flag For the mechanism introduced by commit cbc9ef0 (PM / Domains: Add preliminary support for cpuidle, v2) to work with the ladder governor, that governor should respect the "disabled" state flag added by that commit. Change the ladder governor accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/governors/ladder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 2aef26c520b..9b784051ec1 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c @@ -88,6 +88,7 @@ static int ladder_select_state(struct cpuidle_driver *drv, /* consider promotion */ if (last_idx < drv->state_count - 1 && + !drv->states[last_idx + 1].disabled && !dev->states_usage[last_idx + 1].disable && last_residency > last_state->threshold.promotion_time && drv->states[last_idx + 1].exit_latency <= latency_req) { @@ -101,7 +102,8 @@ static int ladder_select_state(struct cpuidle_driver *drv, /* consider demotion */ if (last_idx > CPUIDLE_DRIVER_STATE_START && - (dev->states_usage[last_idx].disable || + (drv->states[last_idx].disabled || + dev->states_usage[last_idx].disable || drv->states[last_idx].exit_latency > latency_req)) { int i; -- cgit v1.2.3-70-g09d2 From c59687f8466df36633d937cc298aad465d704990 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 5 Sep 2012 15:13:48 +0200 Subject: cpuidle / ACPI : remove power from acpi_processor_cx structure Remove the unused power field from struct struct acpi_processor_cx. [rjw: Modified changelog.] Signed-off-by: Daniel Lezcano Acked-by: Konrad Rzeszutek Wilk Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_idle.c | 2 -- drivers/xen/xen-acpi-processor.c | 1 - include/acpi/processor.h | 1 - 3 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ad3730b4038..de896242d14 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -483,8 +483,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) if (obj->type != ACPI_TYPE_INTEGER) continue; - cx.power = obj->integer.value; - current_count++; memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index b590ee067fc..316df65163c 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -98,7 +98,6 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) dst_cx->type = cx->type; dst_cx->latency = cx->latency; - dst_cx->power = cx->power; dst_cx->dpcnt = 0; set_xen_guest_handle(dst_cx->dp, NULL); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 64ec644808b..db427fa8cf8 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -59,7 +59,6 @@ struct acpi_processor_cx { u8 entry_method; u8 index; u32 latency; - u32 power; u8 bm_sts_skip; char desc[ACPI_CX_DESC_LEN]; }; -- cgit v1.2.3-70-g09d2 From 38a991b625ae3898f18149f8fa287338647a4c9f Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sat, 15 Sep 2012 22:42:54 +0200 Subject: ACPI / processor: remove unused function parameter The 'device' parameter is not used neither in acpi_processor_power_init and acpi_processor_power_exit. This patch removes it. Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 6 +++--- drivers/acpi/processor_idle.c | 6 ++---- include/acpi/processor.h | 6 ++---- 3 files changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index bfc31cb0dd3..9c9288b7e41 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -475,7 +475,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr) acpi_processor_get_limit_info(pr); if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) - acpi_processor_power_init(pr, device); + acpi_processor_power_init(pr); pr->cdev = thermal_cooling_device_register("Processor", device, &processor_cooling_ops); @@ -509,7 +509,7 @@ err_remove_sysfs_thermal: err_thermal_unregister: thermal_cooling_device_unregister(pr->cdev); err_power_exit: - acpi_processor_power_exit(pr, device); + acpi_processor_power_exit(pr); return result; } @@ -620,7 +620,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) return -EINVAL; } - acpi_processor_power_exit(pr, device); + acpi_processor_power_exit(pr); sysfs_remove_link(&device->dev.kobj, "sysdev"); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index de896242d14..c46a44a8c86 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1216,8 +1216,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) static int acpi_processor_registered; -int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, - struct acpi_device *device) +int __cpuinit acpi_processor_power_init(struct acpi_processor *pr) { acpi_status status = 0; int retval; @@ -1281,8 +1280,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, return 0; } -int acpi_processor_power_exit(struct acpi_processor *pr, - struct acpi_device *device) +int acpi_processor_power_exit(struct acpi_processor *pr) { if (disabled_by_idle_boot_param()) return 0; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index db427fa8cf8..1d3c1a68acc 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -324,12 +324,10 @@ extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, extern const struct file_operations acpi_processor_throttling_fops; extern void acpi_processor_throttling_init(void); /* in processor_idle.c */ -int acpi_processor_power_init(struct acpi_processor *pr, - struct acpi_device *device); +int acpi_processor_power_init(struct acpi_processor *pr); +int acpi_processor_power_exit(struct acpi_processor *pr); int acpi_processor_cst_has_changed(struct acpi_processor *pr); int acpi_processor_hotplug(struct acpi_processor *pr); -int acpi_processor_power_exit(struct acpi_processor *pr, - struct acpi_device *device); int acpi_processor_suspend(struct device *dev); int acpi_processor_resume(struct device *dev); extern struct cpuidle_driver acpi_idle_driver; -- cgit v1.2.3-70-g09d2 From ed1511b80c92b1b1a8dde567adc090e470a4344a Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sat, 15 Sep 2012 22:43:05 +0200 Subject: ACPI / processor: remove pointless variable initialization The 'errata' variable is a global variable which is set to zero, no need to do that with a memset in the init function. Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9c9288b7e41..e78c2a52ea4 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -905,8 +905,6 @@ static int __init acpi_processor_init(void) if (acpi_disabled) return 0; - memset(&errata, 0, sizeof(errata)); - result = acpi_bus_register_driver(&acpi_processor_driver); if (result < 0) return result; -- cgit v1.2.3-70-g09d2