cpuidle: Add cpuidle.governor= command line parameter

Add cpuidle.governor= command line parameter to allow the default
cpuidle governor to be replaced.

That is useful, for example, if someone running a tickful kernel
wants to use the menu governor on it.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Rafael J. Wysocki 2018-12-05 23:45:34 +01:00
parent 800fb34a99
commit 61cb5758d3
5 changed files with 19 additions and 2 deletions

View File

@ -674,6 +674,9 @@
cpuidle.off=1 [CPU_IDLE] cpuidle.off=1 [CPU_IDLE]
disable the cpuidle sub-system disable the cpuidle sub-system
cpuidle.governor=
[CPU_IDLE] Name of the cpuidle governor to use.
cpufreq.off=1 [CPU_FREQ] cpufreq.off=1 [CPU_FREQ]
disable the cpufreq sub-system disable the cpufreq sub-system

View File

@ -566,6 +566,13 @@ processors implementing the architecture (i.e. CPU instruction set) in question,
however, so it is rather crude and not very energy-efficient. For this reason, however, so it is rather crude and not very energy-efficient. For this reason,
it is not recommended for production use. it is not recommended for production use.
The ``cpuidle.governor=`` kernel command line switch allows the ``CPUIdle``
governor to use to be specified. It has to be appended with a string matching
the name of an available governor (e.g. ``cpuidle.governor=menu``) and that
governor will be used instead of the default one. It is possible to force
the ``menu`` governor to be used on the systems that use the ``ladder`` governor
by default this way, for example.
The other kernel command line parameters controlling CPU idle time management The other kernel command line parameters controlling CPU idle time management
described below are only relevant for the *x86* architecture and some of described below are only relevant for the *x86* architecture and some of
them affect Intel processors only. them affect Intel processors only.

View File

@ -702,4 +702,5 @@ static int __init cpuidle_init(void)
} }
module_param(off, int, 0444); module_param(off, int, 0444);
module_param_string(governor, param_governor, CPUIDLE_NAME_LEN, 0444);
core_initcall(cpuidle_init); core_initcall(cpuidle_init);

View File

@ -7,6 +7,7 @@
#define __DRIVER_CPUIDLE_H #define __DRIVER_CPUIDLE_H
/* For internal use only */ /* For internal use only */
extern char param_governor[];
extern struct cpuidle_governor *cpuidle_curr_governor; extern struct cpuidle_governor *cpuidle_curr_governor;
extern struct list_head cpuidle_governors; extern struct list_head cpuidle_governors;
extern struct list_head cpuidle_detected_devices; extern struct list_head cpuidle_detected_devices;

View File

@ -11,10 +11,13 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/module.h>
#include <linux/pm_qos.h> #include <linux/pm_qos.h>
#include "cpuidle.h" #include "cpuidle.h"
char param_governor[CPUIDLE_NAME_LEN];
LIST_HEAD(cpuidle_governors); LIST_HEAD(cpuidle_governors);
struct cpuidle_governor *cpuidle_curr_governor; struct cpuidle_governor *cpuidle_curr_governor;
@ -86,9 +89,11 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
mutex_lock(&cpuidle_lock); mutex_lock(&cpuidle_lock);
if (__cpuidle_find_governor(gov->name) == NULL) { if (__cpuidle_find_governor(gov->name) == NULL) {
ret = 0; ret = 0;
list_add_tail(&gov->governor_list, &cpuidle_governors);
if (!cpuidle_curr_governor || if (!cpuidle_curr_governor ||
cpuidle_curr_governor->rating < gov->rating) !strncasecmp(param_governor, gov->name, CPUIDLE_NAME_LEN) ||
(cpuidle_curr_governor->rating < gov->rating &&
strncasecmp(param_governor, cpuidle_curr_governor->name,
CPUIDLE_NAME_LEN)))
cpuidle_switch_governor(gov); cpuidle_switch_governor(gov);
} }
mutex_unlock(&cpuidle_lock); mutex_unlock(&cpuidle_lock);