Skip to content

Commit 8412b45

Browse files
Quentin Perretrafaeljw
authored andcommitted
cpufreq: Specify default governor on command line
Currently, the only way to specify the default CPUfreq governor is via Kconfig options, which suits users who can build the kernel themselves perfectly. However, for those who use a distro-like kernel (such as Android, with the Generic Kernel Image project), the only way to use a non-default governor is to boot to userspace, and to then switch using the sysfs interface. Being able to specify the default governor on the command line, like is the case for cpuidle, would allow those users to specify their governor of choice earlier on, and to simplify the userspace boot procedure slighlty. To support this use-case, add a kernel command line parameter allowing the default governor for CPUfreq to be specified, which takes precedence over the built-in default. This implementation has one notable limitation: the default governor must be registered before the driver. This is solved for builtin governors and drivers using appropriate *_initcall() functions. And in the modular case, this must be reflected as a constraint on the module loading order. Signed-off-by: Quentin Perret <[email protected]> [ Viresh: Converted 'default_governor' to a string and parsing it only at initcall level, and several updates to cpufreq_init_policy(). ] Signed-off-by: Viresh Kumar <[email protected]> [ rjw: Changelog ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 10dd857 commit 8412b45

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,11 @@
703703
cpufreq.off=1 [CPU_FREQ]
704704
disable the cpufreq sub-system
705705

706+
cpufreq.default_governor=
707+
[CPU_FREQ] Name of the default cpufreq governor or
708+
policy to use. This governor must be registered in the
709+
kernel before the cpufreq driver probes.
710+
706711
cpu_init_udelay=N
707712
[X86] Delay for N microsec between assert and de-assert
708713
of APIC INIT to start processors. This delay occurs

Documentation/admin-guide/pm/cpufreq.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ CPUs in it.
147147

148148
The next major initialization step for a new policy object is to attach a
149149
scaling governor to it (to begin with, that is the default scaling governor
150-
determined by the kernel configuration, but it may be changed later
151-
via ``sysfs``). First, a pointer to the new policy object is passed to the
152-
governor's ``->init()`` callback which is expected to initialize all of the
150+
determined by the kernel command line or configuration, but it may be changed
151+
later via ``sysfs``). First, a pointer to the new policy object is passed to
152+
the governor's ``->init()`` callback which is expected to initialize all of the
153153
data structures necessary to handle the given policy and, possibly, to add
154154
a governor ``sysfs`` interface to it. Next, the governor is started by
155155
invoking its ``->start()`` callback.

drivers/cpufreq/cpufreq.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ static LIST_HEAD(cpufreq_governor_list);
5050
#define for_each_governor(__governor) \
5151
list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
5252

53+
static char default_governor[CPUFREQ_NAME_LEN];
54+
5355
/**
5456
* The "cpufreq driver" - the arch- or hardware-dependent low
5557
* level driver of CPUFreq support, and its spinlock. This lock
@@ -1061,7 +1063,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
10611063

10621064
static int cpufreq_init_policy(struct cpufreq_policy *policy)
10631065
{
1064-
struct cpufreq_governor *def_gov = cpufreq_default_governor();
10651066
struct cpufreq_governor *gov = NULL;
10661067
unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
10671068
int ret;
@@ -1071,21 +1072,27 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
10711072
gov = get_governor(policy->last_governor);
10721073
if (gov) {
10731074
pr_debug("Restoring governor %s for cpu %d\n",
1074-
policy->governor->name, policy->cpu);
1075-
} else if (def_gov) {
1076-
gov = def_gov;
1077-
__module_get(gov->owner);
1075+
gov->name, policy->cpu);
10781076
} else {
1079-
return -ENODATA;
1077+
gov = get_governor(default_governor);
1078+
}
1079+
1080+
if (!gov) {
1081+
gov = cpufreq_default_governor();
1082+
if (!gov)
1083+
return -ENODATA;
1084+
__module_get(gov->owner);
10801085
}
1086+
10811087
} else {
1088+
10821089
/* Use the default policy if there is no last_policy. */
10831090
if (policy->last_policy) {
10841091
pol = policy->last_policy;
1085-
} else if (def_gov) {
1086-
pol = cpufreq_parse_policy(def_gov->name);
1092+
} else {
1093+
pol = cpufreq_parse_policy(default_governor);
10871094
/*
1088-
* In case the default governor is neiter "performance"
1095+
* In case the default governor is neither "performance"
10891096
* nor "powersave", fall back to the initial policy
10901097
* value set by the driver.
10911098
*/
@@ -2795,13 +2802,19 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
27952802

27962803
static int __init cpufreq_core_init(void)
27972804
{
2805+
struct cpufreq_governor *gov = cpufreq_default_governor();
2806+
27982807
if (cpufreq_disabled())
27992808
return -ENODEV;
28002809

28012810
cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
28022811
BUG_ON(!cpufreq_global_kobject);
28032812

2813+
if (!strlen(default_governor))
2814+
strncpy(default_governor, gov->name, CPUFREQ_NAME_LEN);
2815+
28042816
return 0;
28052817
}
28062818
module_param(off, int, 0444);
2819+
module_param_string(default_governor, default_governor, CPUFREQ_NAME_LEN, 0444);
28072820
core_initcall(cpufreq_core_init);

0 commit comments

Comments
 (0)