linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] cpufreq: Specify the default governor on command line
@ 2020-06-23 14:21 Quentin Perret
  2020-06-23 14:21 ` [PATCH v2 1/2] cpufreq: Register governors at core_initcall Quentin Perret
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Quentin Perret @ 2020-06-23 14:21 UTC (permalink / raw)
  To: rjw, rafael, viresh.kumar
  Cc: arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, qperret, tkjos, adharmap

This series enables users of prebuilt kernels (e.g. distro kernels) to
specify their CPUfreq governor of choice using the kernel command line,
instead of having to wait for the system to fully boot to userspace to
switch using the sysfs interface. This is helpful for 2 reasons:
  1. users get to choose the governor that runs during the actual boot;
  2. it simplifies the userspace boot procedure a bit (one less thing to
     worry about).

To enable this, the first patch moves all governor init calls to
core_initcall, to make sure they are registered by the time the drivers
probe. This should be relatively low impact as registering a governor
is a simple procedure (it gets added to a llist), and all governors
already load at core_initcall anyway when they're set as the default
in Kconfig. This also allows to clean-up the governors' init/exit code,
and reduces boilerplate.

The second patch introduces the new command line parameter, inspired by
its cpuidle counterpart. More details can be found in the respective
patch headers.

Changes in v2:
 - added Viresh's ack to patch 01
 - moved the assignment of 'default_governor' in patch 02 to the governor
   registration path instead of the driver registration (Viresh)

Thanks,
Quentin

Quentin Perret (2):
  cpufreq: Register governors at core_initcall
  cpufreq: Specify default governor on command line

 .../admin-guide/kernel-parameters.txt         |  5 ++++
 Documentation/admin-guide/pm/cpufreq.rst      |  6 ++---
 .../platforms/cell/cpufreq_spudemand.c        | 26 ++-----------------
 drivers/cpufreq/cpufreq.c                     | 23 ++++++++++++----
 drivers/cpufreq/cpufreq_conservative.c        | 22 ++++------------
 drivers/cpufreq/cpufreq_ondemand.c            | 24 +++++------------
 drivers/cpufreq/cpufreq_performance.c         | 14 ++--------
 drivers/cpufreq/cpufreq_powersave.c           | 18 +++----------
 drivers/cpufreq/cpufreq_userspace.c           | 18 +++----------
 include/linux/cpufreq.h                       | 14 ++++++++++
 kernel/sched/cpufreq_schedutil.c              |  6 +----
 11 files changed, 62 insertions(+), 114 deletions(-)

-- 
2.27.0.111.gc72c7da667-goog


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/2] cpufreq: Register governors at core_initcall
  2020-06-23 14:21 [PATCH v2 0/2] cpufreq: Specify the default governor on command line Quentin Perret
@ 2020-06-23 14:21 ` Quentin Perret
  2020-06-23 14:21 ` [PATCH v2 2/2] cpufreq: Specify default governor on command line Quentin Perret
  2020-06-23 17:54 ` [PATCH v2 0/2] cpufreq: Specify the " Doug Smythies
  2 siblings, 0 replies; 19+ messages in thread
From: Quentin Perret @ 2020-06-23 14:21 UTC (permalink / raw)
  To: rjw, rafael, viresh.kumar
  Cc: arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, qperret, tkjos, adharmap

Currently, most CPUFreq governors are registered at core_initcall time
when used as default, and module_init otherwise. In preparation for
letting users specify the default governor on the kernel command line,
change all of them to use core_initcall unconditionally, as is already
the case for schedutil and performance. This will enable us to assume
builtin governors have been registered before the builtin CPUFreq
drivers probe.

And since all governors now have similar init/exit patterns, introduce
two new macros cpufreq_governor_{init,exit}() to factorize the code.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Quentin Perret <qperret@google.com>
---
Note: I couldn't boot-test the change to spudemand, by lack of hardware.
But I can confirm cell_defconfig compiles just fine.
---
 .../platforms/cell/cpufreq_spudemand.c        | 26 ++-----------------
 drivers/cpufreq/cpufreq_conservative.c        | 22 ++++------------
 drivers/cpufreq/cpufreq_ondemand.c            | 24 +++++------------
 drivers/cpufreq/cpufreq_performance.c         | 14 ++--------
 drivers/cpufreq/cpufreq_powersave.c           | 18 +++----------
 drivers/cpufreq/cpufreq_userspace.c           | 18 +++----------
 include/linux/cpufreq.h                       | 14 ++++++++++
 kernel/sched/cpufreq_schedutil.c              |  6 +----
 8 files changed, 36 insertions(+), 106 deletions(-)

diff --git a/arch/powerpc/platforms/cell/cpufreq_spudemand.c b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
index 55b31eadb3c8..ca7849e113d7 100644
--- a/arch/powerpc/platforms/cell/cpufreq_spudemand.c
+++ b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
@@ -126,30 +126,8 @@ static struct cpufreq_governor spu_governor = {
 	.stop = spu_gov_stop,
 	.owner = THIS_MODULE,
 };
-
-/*
- * module init and destoy
- */
-
-static int __init spu_gov_init(void)
-{
-	int ret;
-
-	ret = cpufreq_register_governor(&spu_governor);
-	if (ret)
-		printk(KERN_ERR "registration of governor failed\n");
-	return ret;
-}
-
-static void __exit spu_gov_exit(void)
-{
-	cpufreq_unregister_governor(&spu_governor);
-}
-
-
-module_init(spu_gov_init);
-module_exit(spu_gov_exit);
+cpufreq_governor_init(spu_governor);
+cpufreq_governor_exit(spu_governor);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
-
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 737ff3b9c2c0..aa39ff31ec9f 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -322,17 +322,7 @@ static struct dbs_governor cs_governor = {
 	.start = cs_start,
 };
 
-#define CPU_FREQ_GOV_CONSERVATIVE	(&cs_governor.gov)
-
-static int __init cpufreq_gov_dbs_init(void)
-{
-	return cpufreq_register_governor(CPU_FREQ_GOV_CONSERVATIVE);
-}
-
-static void __exit cpufreq_gov_dbs_exit(void)
-{
-	cpufreq_unregister_governor(CPU_FREQ_GOV_CONSERVATIVE);
-}
+#define CPU_FREQ_GOV_CONSERVATIVE	(cs_governor.gov)
 
 MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
 MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for "
@@ -343,11 +333,9 @@ MODULE_LICENSE("GPL");
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
 struct cpufreq_governor *cpufreq_default_governor(void)
 {
-	return CPU_FREQ_GOV_CONSERVATIVE;
+	return &CPU_FREQ_GOV_CONSERVATIVE;
 }
-
-core_initcall(cpufreq_gov_dbs_init);
-#else
-module_init(cpufreq_gov_dbs_init);
 #endif
-module_exit(cpufreq_gov_dbs_exit);
+
+cpufreq_governor_init(CPU_FREQ_GOV_CONSERVATIVE);
+cpufreq_governor_exit(CPU_FREQ_GOV_CONSERVATIVE);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 82a4d37ddecb..ac361a8b1d3b 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -408,7 +408,7 @@ static struct dbs_governor od_dbs_gov = {
 	.start = od_start,
 };
 
-#define CPU_FREQ_GOV_ONDEMAND	(&od_dbs_gov.gov)
+#define CPU_FREQ_GOV_ONDEMAND	(od_dbs_gov.gov)
 
 static void od_set_powersave_bias(unsigned int powersave_bias)
 {
@@ -429,7 +429,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias)
 			continue;
 
 		policy = cpufreq_cpu_get_raw(cpu);
-		if (!policy || policy->governor != CPU_FREQ_GOV_ONDEMAND)
+		if (!policy || policy->governor != &CPU_FREQ_GOV_ONDEMAND)
 			continue;
 
 		policy_dbs = policy->governor_data;
@@ -461,16 +461,6 @@ void od_unregister_powersave_bias_handler(void)
 }
 EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler);
 
-static int __init cpufreq_gov_dbs_init(void)
-{
-	return cpufreq_register_governor(CPU_FREQ_GOV_ONDEMAND);
-}
-
-static void __exit cpufreq_gov_dbs_exit(void)
-{
-	cpufreq_unregister_governor(CPU_FREQ_GOV_ONDEMAND);
-}
-
 MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
 MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
 MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
@@ -480,11 +470,9 @@ MODULE_LICENSE("GPL");
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
 struct cpufreq_governor *cpufreq_default_governor(void)
 {
-	return CPU_FREQ_GOV_ONDEMAND;
+	return &CPU_FREQ_GOV_ONDEMAND;
 }
-
-core_initcall(cpufreq_gov_dbs_init);
-#else
-module_init(cpufreq_gov_dbs_init);
 #endif
-module_exit(cpufreq_gov_dbs_exit);
+
+cpufreq_governor_init(CPU_FREQ_GOV_ONDEMAND);
+cpufreq_governor_exit(CPU_FREQ_GOV_ONDEMAND);
diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c
index def9afe0f5b8..71c1d9aba772 100644
--- a/drivers/cpufreq/cpufreq_performance.c
+++ b/drivers/cpufreq/cpufreq_performance.c
@@ -23,16 +23,6 @@ static struct cpufreq_governor cpufreq_gov_performance = {
 	.limits		= cpufreq_gov_performance_limits,
 };
 
-static int __init cpufreq_gov_performance_init(void)
-{
-	return cpufreq_register_governor(&cpufreq_gov_performance);
-}
-
-static void __exit cpufreq_gov_performance_exit(void)
-{
-	cpufreq_unregister_governor(&cpufreq_gov_performance);
-}
-
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
 struct cpufreq_governor *cpufreq_default_governor(void)
 {
@@ -50,5 +40,5 @@ MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'performance'");
 MODULE_LICENSE("GPL");
 
-core_initcall(cpufreq_gov_performance_init);
-module_exit(cpufreq_gov_performance_exit);
+cpufreq_governor_init(cpufreq_gov_performance);
+cpufreq_governor_exit(cpufreq_gov_performance);
diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c
index 1ae66019eb83..7749522355b5 100644
--- a/drivers/cpufreq/cpufreq_powersave.c
+++ b/drivers/cpufreq/cpufreq_powersave.c
@@ -23,16 +23,6 @@ static struct cpufreq_governor cpufreq_gov_powersave = {
 	.owner		= THIS_MODULE,
 };
 
-static int __init cpufreq_gov_powersave_init(void)
-{
-	return cpufreq_register_governor(&cpufreq_gov_powersave);
-}
-
-static void __exit cpufreq_gov_powersave_exit(void)
-{
-	cpufreq_unregister_governor(&cpufreq_gov_powersave);
-}
-
 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'");
 MODULE_LICENSE("GPL");
@@ -42,9 +32,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
 {
 	return &cpufreq_gov_powersave;
 }
-
-core_initcall(cpufreq_gov_powersave_init);
-#else
-module_init(cpufreq_gov_powersave_init);
 #endif
-module_exit(cpufreq_gov_powersave_exit);
+
+cpufreq_governor_init(cpufreq_gov_powersave);
+cpufreq_governor_exit(cpufreq_gov_powersave);
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index b43e7cd502c5..50a4d7846580 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -126,16 +126,6 @@ static struct cpufreq_governor cpufreq_gov_userspace = {
 	.owner		= THIS_MODULE,
 };
 
-static int __init cpufreq_gov_userspace_init(void)
-{
-	return cpufreq_register_governor(&cpufreq_gov_userspace);
-}
-
-static void __exit cpufreq_gov_userspace_exit(void)
-{
-	cpufreq_unregister_governor(&cpufreq_gov_userspace);
-}
-
 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
 		"Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
@@ -146,9 +136,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
 {
 	return &cpufreq_gov_userspace;
 }
-
-core_initcall(cpufreq_gov_userspace_init);
-#else
-module_init(cpufreq_gov_userspace_init);
 #endif
-module_exit(cpufreq_gov_userspace_exit);
+
+cpufreq_governor_init(cpufreq_gov_userspace);
+cpufreq_governor_exit(cpufreq_gov_userspace);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3494f6763597..e62b022cb07e 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -577,6 +577,20 @@ unsigned int cpufreq_policy_transition_delay_us(struct cpufreq_policy *policy);
 int cpufreq_register_governor(struct cpufreq_governor *governor);
 void cpufreq_unregister_governor(struct cpufreq_governor *governor);
 
+#define cpufreq_governor_init(__governor)			\
+static int __init __governor##_init(void)			\
+{								\
+	return cpufreq_register_governor(&__governor);	\
+}								\
+core_initcall(__governor##_init)
+
+#define cpufreq_governor_exit(__governor)			\
+static void __exit __governor##_exit(void)			\
+{								\
+	return cpufreq_unregister_governor(&__governor);	\
+}								\
+module_exit(__governor##_exit)
+
 struct cpufreq_governor *cpufreq_default_governor(void);
 struct cpufreq_governor *cpufreq_fallback_governor(void);
 
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 7fbaee24c824..402a09af9f43 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -909,11 +909,7 @@ struct cpufreq_governor *cpufreq_default_governor(void)
 }
 #endif
 
-static int __init sugov_register(void)
-{
-	return cpufreq_register_governor(&schedutil_gov);
-}
-core_initcall(sugov_register);
+cpufreq_governor_init(schedutil_gov);
 
 #ifdef CONFIG_ENERGY_MODEL
 extern bool sched_energy_update;
-- 
2.27.0.111.gc72c7da667-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-23 14:21 [PATCH v2 0/2] cpufreq: Specify the default governor on command line Quentin Perret
  2020-06-23 14:21 ` [PATCH v2 1/2] cpufreq: Register governors at core_initcall Quentin Perret
@ 2020-06-23 14:21 ` Quentin Perret
  2020-06-24  5:50   ` Viresh Kumar
                     ` (2 more replies)
  2020-06-23 17:54 ` [PATCH v2 0/2] cpufreq: Specify the " Doug Smythies
  2 siblings, 3 replies; 19+ messages in thread
From: Quentin Perret @ 2020-06-23 14:21 UTC (permalink / raw)
  To: rjw, rafael, viresh.kumar
  Cc: arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, qperret, tkjos, adharmap

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 different
default 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 enable those users to specify
their governor of choice earlier on, and to simplify slighlty the
userspace boot procedure.

To support this use-case, add a kernel command line parameter enabling
to specify a default governor for CPUfreq, which takes precedence over
the builtin 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 <qperret@google.com>
---
 .../admin-guide/kernel-parameters.txt         |  5 ++++
 Documentation/admin-guide/pm/cpufreq.rst      |  6 ++---
 drivers/cpufreq/cpufreq.c                     | 23 +++++++++++++++----
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index fb95fad81c79..5fd3c9f187eb 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -703,6 +703,11 @@
 	cpufreq.off=1	[CPU_FREQ]
 			disable the cpufreq sub-system
 
+	cpufreq.default_governor=
+			[CPU_FREQ] Name of the default cpufreq governor to use.
+			This governor must be registered in the kernel before
+			the cpufreq driver probes.
+
 	cpu_init_udelay=N
 			[X86] Delay for N microsec between assert and de-assert
 			of APIC INIT to start processors.  This delay occurs
diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
index 0c74a7784964..368e612145d2 100644
--- a/Documentation/admin-guide/pm/cpufreq.rst
+++ b/Documentation/admin-guide/pm/cpufreq.rst
@@ -147,9 +147,9 @@ CPUs in it.
 
 The next major initialization step for a new policy object is to attach a
 scaling governor to it (to begin with, that is the default scaling governor
-determined by the kernel configuration, but it may be changed later
-via ``sysfs``).  First, a pointer to the new policy object is passed to the
-governor's ``->init()`` callback which is expected to initialize all of the
+determined by the kernel command line or configuration, but it may be changed
+later via ``sysfs``).  First, a pointer to the new policy object is passed to
+the governor's ``->init()`` callback which is expected to initialize all of the
 data structures necessary to handle the given policy and, possibly, to add
 a governor ``sysfs`` interface to it.  Next, the governor is started by
 invoking its ``->start()`` callback.
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0128de3603df..4b1a5c0173cf 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -50,6 +50,9 @@ static LIST_HEAD(cpufreq_governor_list);
 #define for_each_governor(__governor)				\
 	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
 
+static char cpufreq_param_governor[CPUFREQ_NAME_LEN];
+static struct cpufreq_governor *default_governor;
+
 /**
  * The "cpufreq driver" - the arch- or hardware-dependent low
  * level driver of CPUFreq support, and its spinlock. This lock
@@ -1055,7 +1058,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
 
 static int cpufreq_init_policy(struct cpufreq_policy *policy)
 {
-	struct cpufreq_governor *def_gov = cpufreq_default_governor();
 	struct cpufreq_governor *gov = NULL;
 	unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
 
@@ -1065,8 +1067,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
 		if (gov) {
 			pr_debug("Restoring governor %s for cpu %d\n",
 				 policy->governor->name, policy->cpu);
-		} else if (def_gov) {
-			gov = def_gov;
+		} else if (default_governor) {
+			gov = default_governor;
 		} else {
 			return -ENODATA;
 		}
@@ -1074,8 +1076,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
 		/* Use the default policy if there is no last_policy. */
 		if (policy->last_policy) {
 			pol = policy->last_policy;
-		} else if (def_gov) {
-			pol = cpufreq_parse_policy(def_gov->name);
+		} else if (default_governor) {
+			pol = cpufreq_parse_policy(default_governor->name);
 			/*
 			 * In case the default governor is neiter "performance"
 			 * nor "powersave", fall back to the initial policy
@@ -2320,6 +2322,9 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
 		list_add(&governor->governor_list, &cpufreq_governor_list);
 	}
 
+	if (!strncasecmp(cpufreq_param_governor, governor->name, CPUFREQ_NAME_LEN))
+		default_governor = governor;
+
 	mutex_unlock(&cpufreq_governor_mutex);
 	return err;
 }
@@ -2348,6 +2353,8 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
 
 	mutex_lock(&cpufreq_governor_mutex);
 	list_del(&governor->governor_list);
+	if (governor == default_governor)
+		default_governor = cpufreq_default_governor();
 	mutex_unlock(&cpufreq_governor_mutex);
 }
 EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
@@ -2789,7 +2796,13 @@ static int __init cpufreq_core_init(void)
 	cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
 	BUG_ON(!cpufreq_global_kobject);
 
+	mutex_lock(&cpufreq_governor_mutex);
+	if (!default_governor)
+		default_governor = cpufreq_default_governor();
+	mutex_unlock(&cpufreq_governor_mutex);
+
 	return 0;
 }
 module_param(off, int, 0444);
+module_param_string(default_governor, cpufreq_param_governor, CPUFREQ_NAME_LEN, 0444);
 core_initcall(cpufreq_core_init);
-- 
2.27.0.111.gc72c7da667-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 0/2] cpufreq: Specify the default governor on command line
  2020-06-23 14:21 [PATCH v2 0/2] cpufreq: Specify the default governor on command line Quentin Perret
  2020-06-23 14:21 ` [PATCH v2 1/2] cpufreq: Register governors at core_initcall Quentin Perret
  2020-06-23 14:21 ` [PATCH v2 2/2] cpufreq: Specify default governor on command line Quentin Perret
@ 2020-06-23 17:54 ` Doug Smythies
  2020-06-23 18:04   ` Quentin Perret
  2 siblings, 1 reply; 19+ messages in thread
From: Doug Smythies @ 2020-06-23 17:54 UTC (permalink / raw)
  To: 'Quentin Perret'
  Cc: arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap, viresh.kumar, rafael, rjw

On 2020.06.23 07:22 Quentin Perret wrote:
> 
> This series enables users of prebuilt kernels (e.g. distro kernels) to
> specify their CPUfreq governor of choice using the kernel command line,
> instead of having to wait for the system to fully boot to userspace to
> switch using the sysfs interface. This is helpful for 2 reasons:
>   1. users get to choose the governor that runs during the actual boot;
>   2. it simplifies the userspace boot procedure a bit (one less thing to
>      worry about).
> 
> To enable this, the first patch moves all governor init calls to
> core_initcall, to make sure they are registered by the time the drivers
> probe. This should be relatively low impact as registering a governor
> is a simple procedure (it gets added to a llist), and all governors
> already load at core_initcall anyway when they're set as the default
> in Kconfig. This also allows to clean-up the governors' init/exit code,
> and reduces boilerplate.
> 
> The second patch introduces the new command line parameter, inspired by
> its cpuidle counterpart. More details can be found in the respective
> patch headers.
> 
> Changes in v2:
>  - added Viresh's ack to patch 01
>  - moved the assignment of 'default_governor' in patch 02 to the governor
>    registration path instead of the driver registration (Viresh)
> 
> Thanks,
> Quentin
> 
> Quentin Perret (2):
>   cpufreq: Register governors at core_initcall
>   cpufreq: Specify default governor on command line
> 
>  .../admin-guide/kernel-parameters.txt         |  5 ++++
>  Documentation/admin-guide/pm/cpufreq.rst      |  6 ++---
>  .../platforms/cell/cpufreq_spudemand.c        | 26 ++-----------------
>  drivers/cpufreq/cpufreq.c                     | 23 ++++++++++++----
>  drivers/cpufreq/cpufreq_conservative.c        | 22 ++++------------
>  drivers/cpufreq/cpufreq_ondemand.c            | 24 +++++------------
>  drivers/cpufreq/cpufreq_performance.c         | 14 ++--------
>  drivers/cpufreq/cpufreq_powersave.c           | 18 +++----------
>  drivers/cpufreq/cpufreq_userspace.c           | 18 +++----------
>  include/linux/cpufreq.h                       | 14 ++++++++++
>  kernel/sched/cpufreq_schedutil.c              |  6 +----
>  11 files changed, 62 insertions(+), 114 deletions(-)
> 
> --
> 2.27.0.111.gc72c7da667-goog

Hi Quentin,

Because I am lazy and sometimes do not want to recompile
the distro source, I have a need/desire for this.

Tested these two grub command lines:

GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 consoleblank=300 intel_pstate=disable cpufreq.default_governor=schedutil cpuidle_sysfs_switch cpuidle.governor=teo"

And

#GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 consoleblank=450 intel_pstate=passive cpufreq.default_governor=schedutil cpuidle_sysfs_switch cpuidle.governor=teo"

And all worked as expected. I use Ubuntu as my distro, and also had to disable a startup script that switches to "ondemand", or similar, after 1 minute.

As a side note (separate subject, but is one reason I tried it):
My i5-9600K based computer seems to hit a power limit during boot approximately 3 seconds after kernel selection on grub.
This had no effect on that issue (even when selecting powersave governor).

... Doug



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/2] cpufreq: Specify the default governor on command line
  2020-06-23 17:54 ` [PATCH v2 0/2] cpufreq: Specify the " Doug Smythies
@ 2020-06-23 18:04   ` Quentin Perret
  2020-06-24  0:07     ` Doug Smythies
  0 siblings, 1 reply; 19+ messages in thread
From: Quentin Perret @ 2020-06-23 18:04 UTC (permalink / raw)
  To: Doug Smythies
  Cc: arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap, viresh.kumar, rafael, rjw

Hi Doug,

On Tuesday 23 Jun 2020 at 10:54:33 (-0700), Doug Smythies wrote:
> Hi Quentin,
> 
> Because I am lazy and sometimes do not want to recompile
> the distro source, I have a need/desire for this.

Good to know I'm not the only one ;-)

> Tested these two grub command lines:
> 
> GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 consoleblank=300 intel_pstate=disable cpufreq.default_governor=schedutil cpuidle_sysfs_switch cpuidle.governor=teo"
> 
> And
> 
> #GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 consoleblank=450 intel_pstate=passive cpufreq.default_governor=schedutil cpuidle_sysfs_switch cpuidle.governor=teo"
> 
> And all worked as expected. I use Ubuntu as my distro, and also had to disable a startup script that switches to "ondemand", or similar, after 1 minute.

Good, thanks for giving it a try.

> As a side note (separate subject, but is one reason I tried it):
> My i5-9600K based computer seems to hit a power limit during boot approximately 3 seconds after kernel selection on grub.
> This had no effect on that issue (even when selecting powersave governor).

Interesting ... Could you confirm that compiling with powersave as
default doesn't fix the issue either?

Other question, when does the intel_pstate driver start on your device?
Before or after that 3 seconds boot time?

Thanks,
Quentin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 0/2] cpufreq: Specify the default governor on command line
  2020-06-23 18:04   ` Quentin Perret
@ 2020-06-24  0:07     ` Doug Smythies
  0 siblings, 0 replies; 19+ messages in thread
From: Doug Smythies @ 2020-06-24  0:07 UTC (permalink / raw)
  To: 'Quentin Perret'
  Cc: arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap, viresh.kumar, rafael, rjw

[-- Attachment #1: Type: text/plain, Size: 2109 bytes --]

Hi Quentin,
Thanks for your quick reply.

On 2020.06.23 11:05 Quentin Perret wrote: 

> Hi Doug,
> 
> On Tuesday 23 Jun 2020 at 10:54:33 (-0700), Doug Smythies wrote:
> > Hi Quentin,
> >
> > Because I am lazy and sometimes do not want to recompile
> > the distro source, I have a need/desire for this.
> 
> Good to know I'm not the only one ;-)
> 
> > Tested these two grub command lines:
> >
> > GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 consoleblank=300 intel_pstate=disable
> cpufreq.default_governor=schedutil cpuidle_sysfs_switch cpuidle.governor=teo"
> >
> > And
> >
> > #GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 consoleblank=450 intel_pstate=passive
> cpufreq.default_governor=schedutil cpuidle_sysfs_switch cpuidle.governor=teo"
> >
> > And all worked as expected. I use Ubuntu as my distro, and also had to disable a startup script that
> switches to "ondemand", or similar, after 1 minute.
> 
> Good, thanks for giving it a try.
> 
> > As a side note (separate subject, but is one reason I tried it):
> > My i5-9600K based computer seems to hit a power limit during boot approximately 3 seconds after
> kernel selection on grub.
> > This had no effect on that issue (even when selecting powersave governor).
> 
> Interesting ... Could you confirm that compiling with powersave as
> default doesn't fix the issue either?

No, it doesn't (good idea for a test though).
However, the big mains spike is also gone. So, I no longer know why those power
limit log bits are always set after boot.

> 
> Other question, when does the intel_pstate driver start on your device?
> Before or after that 3 seconds boot time?

Before, if I understand correctly (from dmesg):

[    0.468969] intel_pstate: Intel P-state driver initializing

I'll attach a couple of annotated mains power graphs.
(which will likely get stripped from the on-list version of this e-mail).

Currently, I am drowning in stuff that doesn't work, and will put
this aside for now. I'll revive this as a new thread or a bugzilla
eventually.

I also tried booting with turbo disabled, no difference.

Thanks for this patch set.

... Doug


[-- Attachment #2: reboot-mains-power.png --]
[-- Type: image/png, Size: 35002 bytes --]

[-- Attachment #3: reboot-mains-power4.png --]
[-- Type: image/png, Size: 34687 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-23 14:21 ` [PATCH v2 2/2] cpufreq: Specify default governor on command line Quentin Perret
@ 2020-06-24  5:50   ` Viresh Kumar
  2020-06-24 12:51     ` Rafael J. Wysocki
  2020-06-25 11:36   ` Viresh Kumar
  2020-06-26  2:53   ` Viresh Kumar
  2 siblings, 1 reply; 19+ messages in thread
From: Viresh Kumar @ 2020-06-24  5:50 UTC (permalink / raw)
  To: Quentin Perret
  Cc: rjw, rafael, arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap

On 23-06-20, 15:21, Quentin Perret wrote:
> 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 different
> default 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 enable those users to specify
> their governor of choice earlier on, and to simplify slighlty the
> userspace boot procedure.
> 
> To support this use-case, add a kernel command line parameter enabling
> to specify a default governor for CPUfreq, which takes precedence over
> the builtin 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 <qperret@google.com>
> ---
>  .../admin-guide/kernel-parameters.txt         |  5 ++++
>  Documentation/admin-guide/pm/cpufreq.rst      |  6 ++---
>  drivers/cpufreq/cpufreq.c                     | 23 +++++++++++++++----
>  3 files changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index fb95fad81c79..5fd3c9f187eb 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -703,6 +703,11 @@
>  	cpufreq.off=1	[CPU_FREQ]
>  			disable the cpufreq sub-system
>  
> +	cpufreq.default_governor=
> +			[CPU_FREQ] Name of the default cpufreq governor to use.
> +			This governor must be registered in the kernel before
> +			the cpufreq driver probes.
> +
>  	cpu_init_udelay=N
>  			[X86] Delay for N microsec between assert and de-assert
>  			of APIC INIT to start processors.  This delay occurs
> diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
> index 0c74a7784964..368e612145d2 100644
> --- a/Documentation/admin-guide/pm/cpufreq.rst
> +++ b/Documentation/admin-guide/pm/cpufreq.rst
> @@ -147,9 +147,9 @@ CPUs in it.
>  
>  The next major initialization step for a new policy object is to attach a
>  scaling governor to it (to begin with, that is the default scaling governor
> -determined by the kernel configuration, but it may be changed later
> -via ``sysfs``).  First, a pointer to the new policy object is passed to the
> -governor's ``->init()`` callback which is expected to initialize all of the
> +determined by the kernel command line or configuration, but it may be changed
> +later via ``sysfs``).  First, a pointer to the new policy object is passed to
> +the governor's ``->init()`` callback which is expected to initialize all of the
>  data structures necessary to handle the given policy and, possibly, to add
>  a governor ``sysfs`` interface to it.  Next, the governor is started by
>  invoking its ``->start()`` callback.
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 0128de3603df..4b1a5c0173cf 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -50,6 +50,9 @@ static LIST_HEAD(cpufreq_governor_list);
>  #define for_each_governor(__governor)				\
>  	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
>  
> +static char cpufreq_param_governor[CPUFREQ_NAME_LEN];
> +static struct cpufreq_governor *default_governor;
> +
>  /**
>   * The "cpufreq driver" - the arch- or hardware-dependent low
>   * level driver of CPUFreq support, and its spinlock. This lock
> @@ -1055,7 +1058,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
>  
>  static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  {
> -	struct cpufreq_governor *def_gov = cpufreq_default_governor();
>  	struct cpufreq_governor *gov = NULL;
>  	unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
>  
> @@ -1065,8 +1067,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  		if (gov) {
>  			pr_debug("Restoring governor %s for cpu %d\n",
>  				 policy->governor->name, policy->cpu);
> -		} else if (def_gov) {
> -			gov = def_gov;
> +		} else if (default_governor) {
> +			gov = default_governor;
>  		} else {
>  			return -ENODATA;
>  		}
> @@ -1074,8 +1076,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  		/* Use the default policy if there is no last_policy. */
>  		if (policy->last_policy) {
>  			pol = policy->last_policy;
> -		} else if (def_gov) {
> -			pol = cpufreq_parse_policy(def_gov->name);
> +		} else if (default_governor) {
> +			pol = cpufreq_parse_policy(default_governor->name);
>  			/*
>  			 * In case the default governor is neiter "performance"
>  			 * nor "powersave", fall back to the initial policy
> @@ -2320,6 +2322,9 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
>  		list_add(&governor->governor_list, &cpufreq_governor_list);
>  	}
>  
> +	if (!strncasecmp(cpufreq_param_governor, governor->name, CPUFREQ_NAME_LEN))
> +		default_governor = governor;
> +
>  	mutex_unlock(&cpufreq_governor_mutex);
>  	return err;
>  }
> @@ -2348,6 +2353,8 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
>  
>  	mutex_lock(&cpufreq_governor_mutex);
>  	list_del(&governor->governor_list);
> +	if (governor == default_governor)
> +		default_governor = cpufreq_default_governor();
>  	mutex_unlock(&cpufreq_governor_mutex);
>  }
>  EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
> @@ -2789,7 +2796,13 @@ static int __init cpufreq_core_init(void)
>  	cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
>  	BUG_ON(!cpufreq_global_kobject);
>  
> +	mutex_lock(&cpufreq_governor_mutex);
> +	if (!default_governor)
> +		default_governor = cpufreq_default_governor();
> +	mutex_unlock(&cpufreq_governor_mutex);

I don't think locking is required here at core-initcall level. Apart
from that:

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

> +
>  	return 0;
>  }
>  module_param(off, int, 0444);
> +module_param_string(default_governor, cpufreq_param_governor, CPUFREQ_NAME_LEN, 0444);
>  core_initcall(cpufreq_core_init);
> -- 
> 2.27.0.111.gc72c7da667-goog

-- 
viresh

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-24  5:50   ` Viresh Kumar
@ 2020-06-24 12:51     ` Rafael J. Wysocki
  2020-06-24 15:32       ` Quentin Perret
  0 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2020-06-24 12:51 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Quentin Perret, Rafael J. Wysocki, Rafael J. Wysocki,
	Arnd Bergmann, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, linuxppc-dev, Linux Kernel Mailing List,
	Linux PM, Cc: Android Kernel, Todd Kjos, adharmap

On Wed, Jun 24, 2020 at 7:50 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On 23-06-20, 15:21, Quentin Perret wrote:
> > 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 different
> > default 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 enable those users to specify
> > their governor of choice earlier on, and to simplify slighlty the
> > userspace boot procedure.
> >
> > To support this use-case, add a kernel command line parameter enabling
> > to specify a default governor for CPUfreq, which takes precedence over
> > the builtin 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 <qperret@google.com>
> > ---
> >  .../admin-guide/kernel-parameters.txt         |  5 ++++
> >  Documentation/admin-guide/pm/cpufreq.rst      |  6 ++---
> >  drivers/cpufreq/cpufreq.c                     | 23 +++++++++++++++----
> >  3 files changed, 26 insertions(+), 8 deletions(-)
> >
> > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > index fb95fad81c79..5fd3c9f187eb 100644
> > --- a/Documentation/admin-guide/kernel-parameters.txt
> > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > @@ -703,6 +703,11 @@
> >       cpufreq.off=1   [CPU_FREQ]
> >                       disable the cpufreq sub-system
> >
> > +     cpufreq.default_governor=
> > +                     [CPU_FREQ] Name of the default cpufreq governor to use.
> > +                     This governor must be registered in the kernel before
> > +                     the cpufreq driver probes.
> > +
> >       cpu_init_udelay=N
> >                       [X86] Delay for N microsec between assert and de-assert
> >                       of APIC INIT to start processors.  This delay occurs
> > diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
> > index 0c74a7784964..368e612145d2 100644
> > --- a/Documentation/admin-guide/pm/cpufreq.rst
> > +++ b/Documentation/admin-guide/pm/cpufreq.rst
> > @@ -147,9 +147,9 @@ CPUs in it.
> >
> >  The next major initialization step for a new policy object is to attach a
> >  scaling governor to it (to begin with, that is the default scaling governor
> > -determined by the kernel configuration, but it may be changed later
> > -via ``sysfs``).  First, a pointer to the new policy object is passed to the
> > -governor's ``->init()`` callback which is expected to initialize all of the
> > +determined by the kernel command line or configuration, but it may be changed
> > +later via ``sysfs``).  First, a pointer to the new policy object is passed to
> > +the governor's ``->init()`` callback which is expected to initialize all of the
> >  data structures necessary to handle the given policy and, possibly, to add
> >  a governor ``sysfs`` interface to it.  Next, the governor is started by
> >  invoking its ``->start()`` callback.
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 0128de3603df..4b1a5c0173cf 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -50,6 +50,9 @@ static LIST_HEAD(cpufreq_governor_list);
> >  #define for_each_governor(__governor)                                \
> >       list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
> >
> > +static char cpufreq_param_governor[CPUFREQ_NAME_LEN];
> > +static struct cpufreq_governor *default_governor;
> > +
> >  /**
> >   * The "cpufreq driver" - the arch- or hardware-dependent low
> >   * level driver of CPUFreq support, and its spinlock. This lock
> > @@ -1055,7 +1058,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
> >
> >  static int cpufreq_init_policy(struct cpufreq_policy *policy)
> >  {
> > -     struct cpufreq_governor *def_gov = cpufreq_default_governor();
> >       struct cpufreq_governor *gov = NULL;
> >       unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
> >
> > @@ -1065,8 +1067,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
> >               if (gov) {
> >                       pr_debug("Restoring governor %s for cpu %d\n",
> >                                policy->governor->name, policy->cpu);
> > -             } else if (def_gov) {
> > -                     gov = def_gov;
> > +             } else if (default_governor) {
> > +                     gov = default_governor;
> >               } else {
> >                       return -ENODATA;
> >               }
> > @@ -1074,8 +1076,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
> >               /* Use the default policy if there is no last_policy. */
> >               if (policy->last_policy) {
> >                       pol = policy->last_policy;
> > -             } else if (def_gov) {
> > -                     pol = cpufreq_parse_policy(def_gov->name);
> > +             } else if (default_governor) {
> > +                     pol = cpufreq_parse_policy(default_governor->name);
> >                       /*
> >                        * In case the default governor is neiter "performance"
> >                        * nor "powersave", fall back to the initial policy
> > @@ -2320,6 +2322,9 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
> >               list_add(&governor->governor_list, &cpufreq_governor_list);
> >       }
> >
> > +     if (!strncasecmp(cpufreq_param_governor, governor->name, CPUFREQ_NAME_LEN))
> > +             default_governor = governor;
> > +
> >       mutex_unlock(&cpufreq_governor_mutex);
> >       return err;
> >  }
> > @@ -2348,6 +2353,8 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
> >
> >       mutex_lock(&cpufreq_governor_mutex);
> >       list_del(&governor->governor_list);
> > +     if (governor == default_governor)
> > +             default_governor = cpufreq_default_governor();
> >       mutex_unlock(&cpufreq_governor_mutex);
> >  }
> >  EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
> > @@ -2789,7 +2796,13 @@ static int __init cpufreq_core_init(void)
> >       cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
> >       BUG_ON(!cpufreq_global_kobject);
> >
> > +     mutex_lock(&cpufreq_governor_mutex);
> > +     if (!default_governor)
> > +             default_governor = cpufreq_default_governor();
> > +     mutex_unlock(&cpufreq_governor_mutex);
>
> I don't think locking is required here at core-initcall level.

It isn't necessary AFAICS, but it may as well be regarded as
annotation (kind of instead of having a comment explaining why it need
not be used).

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-24 12:51     ` Rafael J. Wysocki
@ 2020-06-24 15:32       ` Quentin Perret
  2020-06-25  8:50         ` Viresh Kumar
  0 siblings, 1 reply; 19+ messages in thread
From: Quentin Perret @ 2020-06-24 15:32 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Viresh Kumar, Rafael J. Wysocki, Arnd Bergmann, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, linuxppc-dev,
	Linux Kernel Mailing List, Linux PM, Cc: Android Kernel,
	Todd Kjos, adharmap

On Wednesday 24 Jun 2020 at 14:51:04 (+0200), Rafael J. Wysocki wrote:
> On Wed, Jun 24, 2020 at 7:50 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > > @@ -2789,7 +2796,13 @@ static int __init cpufreq_core_init(void)
> > >       cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
> > >       BUG_ON(!cpufreq_global_kobject);
> > >
> > > +     mutex_lock(&cpufreq_governor_mutex);
> > > +     if (!default_governor)
> > > +             default_governor = cpufreq_default_governor();
> > > +     mutex_unlock(&cpufreq_governor_mutex);
> >
> > I don't think locking is required here at core-initcall level.
> 
> It isn't necessary AFAICS, but it may as well be regarded as
> annotation (kind of instead of having a comment explaining why it need
> not be used).

Right, but I must admit that, looking at this more, I'm getting a bit
confused with the overall locking for governors :/

When in cpufreq_init_policy() we find a governor using
find_governor(policy->last_governor), what guarantees this governor is
not concurrently unregistered? That is, what guarantees this governor
doesn't go away between that find_governor() call, and the subsequent
call to try_module_get() in cpufreq_set_policy() down the line?

Can we somewhat assume that whatever governor is referred to by
policy->last_governor will have a non-null refcount? Or are the
cpufreq_online() and cpufreq_unregister_governor() path mutually
exclusive? Or is there something else?

Thanks,
Quentin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-24 15:32       ` Quentin Perret
@ 2020-06-25  8:50         ` Viresh Kumar
  2020-06-25 10:52           ` Rafael J. Wysocki
  0 siblings, 1 reply; 19+ messages in thread
From: Viresh Kumar @ 2020-06-25  8:50 UTC (permalink / raw)
  To: Quentin Perret
  Cc: Rafael J. Wysocki, Rafael J. Wysocki, Arnd Bergmann,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	linuxppc-dev, Linux Kernel Mailing List, Linux PM,
	Cc: Android Kernel, Todd Kjos, adharmap

On 24-06-20, 16:32, Quentin Perret wrote:
> Right, but I must admit that, looking at this more, I'm getting a bit
> confused with the overall locking for governors :/
> 
> When in cpufreq_init_policy() we find a governor using
> find_governor(policy->last_governor), what guarantees this governor is
> not concurrently unregistered? That is, what guarantees this governor
> doesn't go away between that find_governor() call, and the subsequent
> call to try_module_get() in cpufreq_set_policy() down the line?
> 
> Can we somewhat assume that whatever governor is referred to by
> policy->last_governor will have a non-null refcount? Or are the
> cpufreq_online() and cpufreq_unregister_governor() path mutually
> exclusive? Or is there something else?

This should be sufficient to fix pending issues I believe. Based over your
patches.

-- 
viresh

-------------------------8<-------------------------
From: Viresh Kumar <viresh.kumar@linaro.org>
Date: Thu, 25 Jun 2020 13:15:23 +0530
Subject: [PATCH] cpufreq: Fix locking issues with governors

The locking around governors handling isn't adequate currently. The list
of governors should never be traversed without locking in place. Also we
must make sure the governor isn't removed while it is still referenced
by code.

Reported-by: Quentin Perret <qperret@google.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cpufreq.c | 59 ++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 4b1a5c0173cf..dad6b85f4c89 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -624,6 +624,24 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
 	return NULL;
 }
 
+static struct cpufreq_governor *get_governor(const char *str_governor)
+{
+	struct cpufreq_governor *t;
+
+	mutex_lock(&cpufreq_governor_mutex);
+	t = find_governor(str_governor);
+	if (!t)
+		goto unlock;
+
+	if (!try_module_get(t->owner))
+		t = NULL;
+
+unlock:
+	mutex_unlock(&cpufreq_governor_mutex);
+
+	return t;
+}
+
 static unsigned int cpufreq_parse_policy(char *str_governor)
 {
 	if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN))
@@ -643,28 +661,14 @@ static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor)
 {
 	struct cpufreq_governor *t;
 
-	mutex_lock(&cpufreq_governor_mutex);
-
-	t = find_governor(str_governor);
-	if (!t) {
-		int ret;
-
-		mutex_unlock(&cpufreq_governor_mutex);
-
-		ret = request_module("cpufreq_%s", str_governor);
-		if (ret)
-			return NULL;
-
-		mutex_lock(&cpufreq_governor_mutex);
+	t = get_governor(str_governor);
+	if (t)
+		return t;
 
-		t = find_governor(str_governor);
-	}
-	if (t && !try_module_get(t->owner))
-		t = NULL;
-
-	mutex_unlock(&cpufreq_governor_mutex);
+	if (request_module("cpufreq_%s", str_governor))
+		return NULL;
 
-	return t;
+	return get_governor(str_governor);
 }
 
 /**
@@ -818,12 +822,14 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
 		goto out;
 	}
 
+	mutex_lock(&cpufreq_governor_mutex);
 	for_each_governor(t) {
 		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
 		    - (CPUFREQ_NAME_LEN + 2)))
-			goto out;
+			break;
 		i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
 	}
+	mutex_unlock(&cpufreq_governor_mutex);
 out:
 	i += sprintf(&buf[i], "\n");
 	return i;
@@ -1060,11 +1066,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
 {
 	struct cpufreq_governor *gov = NULL;
 	unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
+	bool put_governor = false;
+	int ret;
 
 	if (has_target()) {
 		/* Update policy governor to the one used before hotplug. */
-		gov = find_governor(policy->last_governor);
+		gov = get_governor(policy->last_governor);
 		if (gov) {
+			put_governor = true;
 			pr_debug("Restoring governor %s for cpu %d\n",
 				 policy->governor->name, policy->cpu);
 		} else if (default_governor) {
@@ -1091,7 +1100,11 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
 			return -ENODATA;
 	}
 
-	return cpufreq_set_policy(policy, gov, pol);
+	ret = cpufreq_set_policy(policy, gov, pol);
+	if (put_governor)
+		module_put(gov->owner);
+
+	return ret;
 }
 
 static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-25  8:50         ` Viresh Kumar
@ 2020-06-25 10:52           ` Rafael J. Wysocki
  0 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2020-06-25 10:52 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Quentin Perret, Rafael J. Wysocki, Rafael J. Wysocki,
	Arnd Bergmann, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, linuxppc-dev, Linux Kernel Mailing List,
	Linux PM, Cc: Android Kernel, Todd Kjos, adharmap

On Thu, Jun 25, 2020 at 10:50 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On 24-06-20, 16:32, Quentin Perret wrote:
> > Right, but I must admit that, looking at this more, I'm getting a bit
> > confused with the overall locking for governors :/
> >
> > When in cpufreq_init_policy() we find a governor using
> > find_governor(policy->last_governor), what guarantees this governor is
> > not concurrently unregistered? That is, what guarantees this governor
> > doesn't go away between that find_governor() call, and the subsequent
> > call to try_module_get() in cpufreq_set_policy() down the line?
> >
> > Can we somewhat assume that whatever governor is referred to by
> > policy->last_governor will have a non-null refcount? Or are the
> > cpufreq_online() and cpufreq_unregister_governor() path mutually
> > exclusive? Or is there something else?
>
> This should be sufficient to fix pending issues I believe. Based over your
> patches.

LGTM, but can you post it in a new thread to let Patchwork pick it up?

> -------------------------8<-------------------------
> From: Viresh Kumar <viresh.kumar@linaro.org>
> Date: Thu, 25 Jun 2020 13:15:23 +0530
> Subject: [PATCH] cpufreq: Fix locking issues with governors
>
> The locking around governors handling isn't adequate currently. The list
> of governors should never be traversed without locking in place. Also we
> must make sure the governor isn't removed while it is still referenced
> by code.
>
> Reported-by: Quentin Perret <qperret@google.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/cpufreq/cpufreq.c | 59 ++++++++++++++++++++++++---------------
>  1 file changed, 36 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 4b1a5c0173cf..dad6b85f4c89 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -624,6 +624,24 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
>         return NULL;
>  }
>
> +static struct cpufreq_governor *get_governor(const char *str_governor)
> +{
> +       struct cpufreq_governor *t;
> +
> +       mutex_lock(&cpufreq_governor_mutex);
> +       t = find_governor(str_governor);
> +       if (!t)
> +               goto unlock;
> +
> +       if (!try_module_get(t->owner))
> +               t = NULL;
> +
> +unlock:
> +       mutex_unlock(&cpufreq_governor_mutex);
> +
> +       return t;
> +}
> +
>  static unsigned int cpufreq_parse_policy(char *str_governor)
>  {
>         if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN))
> @@ -643,28 +661,14 @@ static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor)
>  {
>         struct cpufreq_governor *t;
>
> -       mutex_lock(&cpufreq_governor_mutex);
> -
> -       t = find_governor(str_governor);
> -       if (!t) {
> -               int ret;
> -
> -               mutex_unlock(&cpufreq_governor_mutex);
> -
> -               ret = request_module("cpufreq_%s", str_governor);
> -               if (ret)
> -                       return NULL;
> -
> -               mutex_lock(&cpufreq_governor_mutex);
> +       t = get_governor(str_governor);
> +       if (t)
> +               return t;
>
> -               t = find_governor(str_governor);
> -       }
> -       if (t && !try_module_get(t->owner))
> -               t = NULL;
> -
> -       mutex_unlock(&cpufreq_governor_mutex);
> +       if (request_module("cpufreq_%s", str_governor))
> +               return NULL;
>
> -       return t;
> +       return get_governor(str_governor);
>  }
>
>  /**
> @@ -818,12 +822,14 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
>                 goto out;
>         }
>
> +       mutex_lock(&cpufreq_governor_mutex);
>         for_each_governor(t) {
>                 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
>                     - (CPUFREQ_NAME_LEN + 2)))
> -                       goto out;
> +                       break;
>                 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
>         }
> +       mutex_unlock(&cpufreq_governor_mutex);
>  out:
>         i += sprintf(&buf[i], "\n");
>         return i;
> @@ -1060,11 +1066,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  {
>         struct cpufreq_governor *gov = NULL;
>         unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
> +       bool put_governor = false;
> +       int ret;
>
>         if (has_target()) {
>                 /* Update policy governor to the one used before hotplug. */
> -               gov = find_governor(policy->last_governor);
> +               gov = get_governor(policy->last_governor);
>                 if (gov) {
> +                       put_governor = true;
>                         pr_debug("Restoring governor %s for cpu %d\n",
>                                  policy->governor->name, policy->cpu);
>                 } else if (default_governor) {
> @@ -1091,7 +1100,11 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>                         return -ENODATA;
>         }
>
> -       return cpufreq_set_policy(policy, gov, pol);
> +       ret = cpufreq_set_policy(policy, gov, pol);
> +       if (put_governor)
> +               module_put(gov->owner);
> +
> +       return ret;
>  }
>
>  static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-23 14:21 ` [PATCH v2 2/2] cpufreq: Specify default governor on command line Quentin Perret
  2020-06-24  5:50   ` Viresh Kumar
@ 2020-06-25 11:36   ` Viresh Kumar
  2020-06-25 11:44     ` Rafael J. Wysocki
  2020-06-26  2:53   ` Viresh Kumar
  2 siblings, 1 reply; 19+ messages in thread
From: Viresh Kumar @ 2020-06-25 11:36 UTC (permalink / raw)
  To: Quentin Perret
  Cc: rjw, rafael, arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap

After your last email (reply to my patch), I noticed a change which
isn't required. :)

On 23-06-20, 15:21, Quentin Perret wrote:
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 0128de3603df..4b1a5c0173cf 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -50,6 +50,9 @@ static LIST_HEAD(cpufreq_governor_list);
>  #define for_each_governor(__governor)				\
>  	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
>  
> +static char cpufreq_param_governor[CPUFREQ_NAME_LEN];
> +static struct cpufreq_governor *default_governor;
> +
>  /**
>   * The "cpufreq driver" - the arch- or hardware-dependent low
>   * level driver of CPUFreq support, and its spinlock. This lock
> @@ -1055,7 +1058,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
>  
>  static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  {
> -	struct cpufreq_governor *def_gov = cpufreq_default_governor();
>  	struct cpufreq_governor *gov = NULL;
>  	unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
>  
> @@ -1065,8 +1067,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  		if (gov) {
>  			pr_debug("Restoring governor %s for cpu %d\n",
>  				 policy->governor->name, policy->cpu);
> -		} else if (def_gov) {
> -			gov = def_gov;
> +		} else if (default_governor) {
> +			gov = default_governor;
>  		} else {
>  			return -ENODATA;
>  		}


> @@ -1074,8 +1076,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  		/* Use the default policy if there is no last_policy. */
>  		if (policy->last_policy) {
>  			pol = policy->last_policy;
> -		} else if (def_gov) {
> -			pol = cpufreq_parse_policy(def_gov->name);
> +		} else if (default_governor) {
> +			pol = cpufreq_parse_policy(default_governor->name);

This change is not right IMO. This part handles the set-policy case,
where there are no governors. Right now this code, for some reasons
unknown to me, forcefully uses the default governor set to indicate
the policy, which is not a great idea in my opinion TBH. This doesn't
and shouldn't care about governor modules and should only be looking
at strings instead of governor pointer.

Rafael, I even think we should remove this code completely and just
rely on what the driver has sent to us. Using the selected governor
for set policy drivers is very confusing and also we shouldn't be
forced to compiling any governor for the set-policy case.

-- 
viresh

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-25 11:36   ` Viresh Kumar
@ 2020-06-25 11:44     ` Rafael J. Wysocki
  2020-06-25 11:53       ` Quentin Perret
  0 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2020-06-25 11:44 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Quentin Perret, Rafael J. Wysocki, Rafael J. Wysocki,
	Arnd Bergmann, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, linuxppc-dev, Linux Kernel Mailing List,
	Linux PM, Cc: Android Kernel, Todd Kjos, adharmap

On Thu, Jun 25, 2020 at 1:36 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> After your last email (reply to my patch), I noticed a change which
> isn't required. :)
>
> On 23-06-20, 15:21, Quentin Perret wrote:
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 0128de3603df..4b1a5c0173cf 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -50,6 +50,9 @@ static LIST_HEAD(cpufreq_governor_list);
> >  #define for_each_governor(__governor)                                \
> >       list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
> >
> > +static char cpufreq_param_governor[CPUFREQ_NAME_LEN];
> > +static struct cpufreq_governor *default_governor;
> > +
> >  /**
> >   * The "cpufreq driver" - the arch- or hardware-dependent low
> >   * level driver of CPUFreq support, and its spinlock. This lock
> > @@ -1055,7 +1058,6 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
> >
> >  static int cpufreq_init_policy(struct cpufreq_policy *policy)
> >  {
> > -     struct cpufreq_governor *def_gov = cpufreq_default_governor();
> >       struct cpufreq_governor *gov = NULL;
> >       unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
> >
> > @@ -1065,8 +1067,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
> >               if (gov) {
> >                       pr_debug("Restoring governor %s for cpu %d\n",
> >                                policy->governor->name, policy->cpu);
> > -             } else if (def_gov) {
> > -                     gov = def_gov;
> > +             } else if (default_governor) {
> > +                     gov = default_governor;
> >               } else {
> >                       return -ENODATA;
> >               }
>
>
> > @@ -1074,8 +1076,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
> >               /* Use the default policy if there is no last_policy. */
> >               if (policy->last_policy) {
> >                       pol = policy->last_policy;
> > -             } else if (def_gov) {
> > -                     pol = cpufreq_parse_policy(def_gov->name);
> > +             } else if (default_governor) {
> > +                     pol = cpufreq_parse_policy(default_governor->name);
>
> This change is not right IMO. This part handles the set-policy case,
> where there are no governors. Right now this code, for some reasons
> unknown to me, forcefully uses the default governor set to indicate
> the policy, which is not a great idea in my opinion TBH. This doesn't
> and shouldn't care about governor modules and should only be looking
> at strings instead of governor pointer.

Sounds right.

> Rafael, I even think we should remove this code completely and just
> rely on what the driver has sent to us. Using the selected governor
> for set policy drivers is very confusing and also we shouldn't be
> forced to compiling any governor for the set-policy case.

Well, AFAICS the idea was to use the default governor as a kind of
default policy proxy, but I agree that strings should be sufficient
for that.

I'll have a look at what to do with that code.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-25 11:44     ` Rafael J. Wysocki
@ 2020-06-25 11:53       ` Quentin Perret
  2020-06-25 13:28         ` Rafael J. Wysocki
  0 siblings, 1 reply; 19+ messages in thread
From: Quentin Perret @ 2020-06-25 11:53 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Viresh Kumar, Rafael J. Wysocki, Arnd Bergmann, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, linuxppc-dev,
	Linux Kernel Mailing List, Linux PM, Cc: Android Kernel,
	Todd Kjos, adharmap

On Thursday 25 Jun 2020 at 13:44:34 (+0200), Rafael J. Wysocki wrote:
> On Thu, Jun 25, 2020 at 1:36 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > This change is not right IMO. This part handles the set-policy case,
> > where there are no governors. Right now this code, for some reasons
> > unknown to me, forcefully uses the default governor set to indicate
> > the policy, which is not a great idea in my opinion TBH. This doesn't
> > and shouldn't care about governor modules and should only be looking
> > at strings instead of governor pointer.
> 
> Sounds right.
> 
> > Rafael, I even think we should remove this code completely and just
> > rely on what the driver has sent to us. Using the selected governor
> > for set policy drivers is very confusing and also we shouldn't be
> > forced to compiling any governor for the set-policy case.
> 
> Well, AFAICS the idea was to use the default governor as a kind of
> default policy proxy, but I agree that strings should be sufficient
> for that.

I agree with all the above. I'd much rather not rely on the default
governor name to populate the default policy, too, so +1 from me.

Thanks,
Quentin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-25 11:53       ` Quentin Perret
@ 2020-06-25 13:28         ` Rafael J. Wysocki
  2020-06-25 13:49           ` Quentin Perret
  0 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2020-06-25 13:28 UTC (permalink / raw)
  To: Quentin Perret
  Cc: Rafael J. Wysocki, Viresh Kumar, Rafael J. Wysocki,
	Arnd Bergmann, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, linuxppc-dev, Linux Kernel Mailing List,
	Linux PM, Cc: Android Kernel, Todd Kjos, adharmap

On Thu, Jun 25, 2020 at 1:53 PM Quentin Perret <qperret@google.com> wrote:
>
> On Thursday 25 Jun 2020 at 13:44:34 (+0200), Rafael J. Wysocki wrote:
> > On Thu, Jun 25, 2020 at 1:36 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > > This change is not right IMO. This part handles the set-policy case,
> > > where there are no governors. Right now this code, for some reasons
> > > unknown to me, forcefully uses the default governor set to indicate
> > > the policy, which is not a great idea in my opinion TBH. This doesn't
> > > and shouldn't care about governor modules and should only be looking
> > > at strings instead of governor pointer.
> >
> > Sounds right.
> >
> > > Rafael, I even think we should remove this code completely and just
> > > rely on what the driver has sent to us. Using the selected governor
> > > for set policy drivers is very confusing and also we shouldn't be
> > > forced to compiling any governor for the set-policy case.
> >
> > Well, AFAICS the idea was to use the default governor as a kind of
> > default policy proxy, but I agree that strings should be sufficient
> > for that.
>
> I agree with all the above. I'd much rather not rely on the default
> governor name to populate the default policy, too, so +1 from me.

So before this series the default governor was selected at the kernel
configuration time (pre-build) and was always built-in.  Because it
could not go away, its name could be used to indicate the default
policy for the "setpolicy" drivers.

After this series, however, it cannot be used this way reliably, but
you can still pass cpufreq_param_governor to cpufreq_parse_policy()
instead of def_gov->name in cpufreq_init_policy(), can't you?

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-25 13:28         ` Rafael J. Wysocki
@ 2020-06-25 13:49           ` Quentin Perret
  2020-06-25 14:08             ` Rafael J. Wysocki
  0 siblings, 1 reply; 19+ messages in thread
From: Quentin Perret @ 2020-06-25 13:49 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Viresh Kumar, Rafael J. Wysocki, Arnd Bergmann, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ingo Molnar,
	Peter Zijlstra, Juri Lelli, Vincent Guittot, linuxppc-dev,
	Linux Kernel Mailing List, Linux PM, Cc: Android Kernel,
	Todd Kjos, adharmap

On Thursday 25 Jun 2020 at 15:28:43 (+0200), Rafael J. Wysocki wrote:
> On Thu, Jun 25, 2020 at 1:53 PM Quentin Perret <qperret@google.com> wrote:
> >
> > On Thursday 25 Jun 2020 at 13:44:34 (+0200), Rafael J. Wysocki wrote:
> > > On Thu, Jun 25, 2020 at 1:36 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > > > This change is not right IMO. This part handles the set-policy case,
> > > > where there are no governors. Right now this code, for some reasons
> > > > unknown to me, forcefully uses the default governor set to indicate
> > > > the policy, which is not a great idea in my opinion TBH. This doesn't
> > > > and shouldn't care about governor modules and should only be looking
> > > > at strings instead of governor pointer.
> > >
> > > Sounds right.
> > >
> > > > Rafael, I even think we should remove this code completely and just
> > > > rely on what the driver has sent to us. Using the selected governor
> > > > for set policy drivers is very confusing and also we shouldn't be
> > > > forced to compiling any governor for the set-policy case.
> > >
> > > Well, AFAICS the idea was to use the default governor as a kind of
> > > default policy proxy, but I agree that strings should be sufficient
> > > for that.
> >
> > I agree with all the above. I'd much rather not rely on the default
> > governor name to populate the default policy, too, so +1 from me.
> 
> So before this series the default governor was selected at the kernel
> configuration time (pre-build) and was always built-in.  Because it
> could not go away, its name could be used to indicate the default
> policy for the "setpolicy" drivers.
> 
> After this series, however, it cannot be used this way reliably, but
> you can still pass cpufreq_param_governor to cpufreq_parse_policy()
> instead of def_gov->name in cpufreq_init_policy(), can't you?

Good point. I also need to fallback to the default builtin governor if
the command line parameter isn't valid (or non-existent), so perhaps
something like so?

iff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index dad6b85f4c89..20a2020abf88 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -653,6 +653,23 @@ static unsigned int cpufreq_parse_policy(char *str_governor)
        return CPUFREQ_POLICY_UNKNOWN;
 }
 
+static unsigned int cpufreq_default_policy(void)
+{
+       unsigned int pol;
+
+       pol = cpufreq_parse_policy(cpufreq_param_governor);
+       if (pol != CPUFREQ_POLICY_UNKNOWN)
+               return pol;
+
+       if (IS_BUILTIN(CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE))
+               return CPUFREQ_POLICY_PERFORMANCE;
+
+       if (IS_BUILTIN(CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE))
+               return CPUFREQ_POLICY_POWERSAVE;
+
+       return CPUFREQ_POLICY_UNKNOWN;
+}
+
 /**
  * cpufreq_parse_governor - parse a governor string only for has_target()
  * @str_governor: Governor name.
@@ -1085,8 +1102,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
                /* Use the default policy if there is no last_policy. */
                if (policy->last_policy) {
                        pol = policy->last_policy;
-               } else if (default_governor) {
-                       pol = cpufreq_parse_policy(default_governor->name);
+               } else {
+                       pol = cpufreq_default_policy();
                        /*
                         * In case the default governor is neiter "performance"
                         * nor "powersave", fall back to the initial policy

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-25 13:49           ` Quentin Perret
@ 2020-06-25 14:08             ` Rafael J. Wysocki
  0 siblings, 0 replies; 19+ messages in thread
From: Rafael J. Wysocki @ 2020-06-25 14:08 UTC (permalink / raw)
  To: Quentin Perret
  Cc: Rafael J. Wysocki, Viresh Kumar, Rafael J. Wysocki,
	Arnd Bergmann, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, linuxppc-dev, Linux Kernel Mailing List,
	Linux PM, Cc: Android Kernel, Todd Kjos, adharmap

On Thu, Jun 25, 2020 at 3:50 PM Quentin Perret <qperret@google.com> wrote:
>
> On Thursday 25 Jun 2020 at 15:28:43 (+0200), Rafael J. Wysocki wrote:
> > On Thu, Jun 25, 2020 at 1:53 PM Quentin Perret <qperret@google.com> wrote:
> > >
> > > On Thursday 25 Jun 2020 at 13:44:34 (+0200), Rafael J. Wysocki wrote:
> > > > On Thu, Jun 25, 2020 at 1:36 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > > > > This change is not right IMO. This part handles the set-policy case,
> > > > > where there are no governors. Right now this code, for some reasons
> > > > > unknown to me, forcefully uses the default governor set to indicate
> > > > > the policy, which is not a great idea in my opinion TBH. This doesn't
> > > > > and shouldn't care about governor modules and should only be looking
> > > > > at strings instead of governor pointer.
> > > >
> > > > Sounds right.
> > > >
> > > > > Rafael, I even think we should remove this code completely and just
> > > > > rely on what the driver has sent to us. Using the selected governor
> > > > > for set policy drivers is very confusing and also we shouldn't be
> > > > > forced to compiling any governor for the set-policy case.
> > > >
> > > > Well, AFAICS the idea was to use the default governor as a kind of
> > > > default policy proxy, but I agree that strings should be sufficient
> > > > for that.
> > >
> > > I agree with all the above. I'd much rather not rely on the default
> > > governor name to populate the default policy, too, so +1 from me.
> >
> > So before this series the default governor was selected at the kernel
> > configuration time (pre-build) and was always built-in.  Because it
> > could not go away, its name could be used to indicate the default
> > policy for the "setpolicy" drivers.
> >
> > After this series, however, it cannot be used this way reliably, but
> > you can still pass cpufreq_param_governor to cpufreq_parse_policy()
> > instead of def_gov->name in cpufreq_init_policy(), can't you?
>
> Good point. I also need to fallback to the default builtin governor if
> the command line parameter isn't valid (or non-existent), so perhaps
> something like so?

Yes, that should work if I haven't missed anything.

> iff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index dad6b85f4c89..20a2020abf88 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -653,6 +653,23 @@ static unsigned int cpufreq_parse_policy(char *str_governor)
>         return CPUFREQ_POLICY_UNKNOWN;
>  }
>
> +static unsigned int cpufreq_default_policy(void)
> +{
> +       unsigned int pol;
> +
> +       pol = cpufreq_parse_policy(cpufreq_param_governor);
> +       if (pol != CPUFREQ_POLICY_UNKNOWN)
> +               return pol;
> +
> +       if (IS_BUILTIN(CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE))
> +               return CPUFREQ_POLICY_PERFORMANCE;
> +
> +       if (IS_BUILTIN(CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE))
> +               return CPUFREQ_POLICY_POWERSAVE;
> +
> +       return CPUFREQ_POLICY_UNKNOWN;
> +}
> +
>  /**
>   * cpufreq_parse_governor - parse a governor string only for has_target()
>   * @str_governor: Governor name.
> @@ -1085,8 +1102,8 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>                 /* Use the default policy if there is no last_policy. */
>                 if (policy->last_policy) {
>                         pol = policy->last_policy;
> -               } else if (default_governor) {
> -                       pol = cpufreq_parse_policy(default_governor->name);
> +               } else {
> +                       pol = cpufreq_default_policy();
>                         /*
>                          * In case the default governor is neiter "performance"
>                          * nor "powersave", fall back to the initial policy

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-23 14:21 ` [PATCH v2 2/2] cpufreq: Specify default governor on command line Quentin Perret
  2020-06-24  5:50   ` Viresh Kumar
  2020-06-25 11:36   ` Viresh Kumar
@ 2020-06-26  2:53   ` Viresh Kumar
  2020-06-26  8:09     ` Quentin Perret
  2 siblings, 1 reply; 19+ messages in thread
From: Viresh Kumar @ 2020-06-26  2:53 UTC (permalink / raw)
  To: Quentin Perret
  Cc: rjw, rafael, arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap

On 23-06-20, 15:21, Quentin Perret wrote:
> @@ -2789,7 +2796,13 @@ static int __init cpufreq_core_init(void)
>  	cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
>  	BUG_ON(!cpufreq_global_kobject);
>  
> +	mutex_lock(&cpufreq_governor_mutex);
> +	if (!default_governor)

Also is this check really required ? The pointer will always be NULL
at this point, isn't it ?

> +		default_governor = cpufreq_default_governor();
> +	mutex_unlock(&cpufreq_governor_mutex);
> +
>  	return 0;
>  }
>  module_param(off, int, 0444);
> +module_param_string(default_governor, cpufreq_param_governor, CPUFREQ_NAME_LEN, 0444);
>  core_initcall(cpufreq_core_init);
> -- 
> 2.27.0.111.gc72c7da667-goog

-- 
viresh

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/2] cpufreq: Specify default governor on command line
  2020-06-26  2:53   ` Viresh Kumar
@ 2020-06-26  8:09     ` Quentin Perret
  0 siblings, 0 replies; 19+ messages in thread
From: Quentin Perret @ 2020-06-26  8:09 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: rjw, rafael, arnd, mpe, benh, paulus, mingo, peterz, juri.lelli,
	vincent.guittot, linuxppc-dev, linux-kernel, linux-pm,
	kernel-team, tkjos, adharmap

On Friday 26 Jun 2020 at 08:23:46 (+0530), Viresh Kumar wrote:
> On 23-06-20, 15:21, Quentin Perret wrote:
> > @@ -2789,7 +2796,13 @@ static int __init cpufreq_core_init(void)
> >  	cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
> >  	BUG_ON(!cpufreq_global_kobject);
> >  
> > +	mutex_lock(&cpufreq_governor_mutex);
> > +	if (!default_governor)
> 
> Also is this check really required ? The pointer will always be NULL
> at this point, isn't it ?

Not necessarily in this implementation -- the governors are registered
at core_initcall time too, so I don't think we can assume any ordering
there.

But it looks like your new version has fixed that by design, so I'll go
look at it some more, and try it out.

Thanks for the help!
Quentin
> 
> > +		default_governor = cpufreq_default_governor();
> > +	mutex_unlock(&cpufreq_governor_mutex);
> > +
> >  	return 0;
> >  }
> >  module_param(off, int, 0444);
> > +module_param_string(default_governor, cpufreq_param_governor, CPUFREQ_NAME_LEN, 0444);
> >  core_initcall(cpufreq_core_init);
> > -- 
> > 2.27.0.111.gc72c7da667-goog
> 
> -- 
> viresh

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-06-26  8:09 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-23 14:21 [PATCH v2 0/2] cpufreq: Specify the default governor on command line Quentin Perret
2020-06-23 14:21 ` [PATCH v2 1/2] cpufreq: Register governors at core_initcall Quentin Perret
2020-06-23 14:21 ` [PATCH v2 2/2] cpufreq: Specify default governor on command line Quentin Perret
2020-06-24  5:50   ` Viresh Kumar
2020-06-24 12:51     ` Rafael J. Wysocki
2020-06-24 15:32       ` Quentin Perret
2020-06-25  8:50         ` Viresh Kumar
2020-06-25 10:52           ` Rafael J. Wysocki
2020-06-25 11:36   ` Viresh Kumar
2020-06-25 11:44     ` Rafael J. Wysocki
2020-06-25 11:53       ` Quentin Perret
2020-06-25 13:28         ` Rafael J. Wysocki
2020-06-25 13:49           ` Quentin Perret
2020-06-25 14:08             ` Rafael J. Wysocki
2020-06-26  2:53   ` Viresh Kumar
2020-06-26  8:09     ` Quentin Perret
2020-06-23 17:54 ` [PATCH v2 0/2] cpufreq: Specify the " Doug Smythies
2020-06-23 18:04   ` Quentin Perret
2020-06-24  0:07     ` Doug Smythies

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).