linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/3] add SW BOOST support for CPPC
@ 2020-05-18  7:10 Xiongfeng Wang
  2020-05-18  7:10 ` [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly Xiongfeng Wang
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Xiongfeng Wang @ 2020-05-18  7:10 UTC (permalink / raw)
  To: rjw, viresh.kumar, Souvik.Chakravarty, Thanu.Rangarajan
  Cc: Sudeep.Holla, guohanjun, john.garry, jonathan.cameron, linux-pm,
	linux-kernel, wangxiongfeng2

ACPI spec 6.2 section 8.4.7.1 provide the following two CPC registers.

"Highest performance is the absolute maximum performance an individual
processor may reach, assuming ideal conditions. This performance level
may not be sustainable for long durations, and may only be achievable if
other platform components are in a specific state; for example, it may
require other processors be in an idle state.

Nominal Performance is the maximum sustained performance level of the
processor, assuming ideal operating conditions. In absence of an
external constraint (power, thermal, etc.) this is the performance level
the platform is expected to be able to maintain continuously. All
processors are expected to be able to sustain their nominal performance
state simultaneously."

We can use Highest Performance as the max performance in boost mode and
Nomial Performance as the max performance in non-boost mode. If the
Highest Performance is greater than the Nominal Performance, we assume
SW BOOST is supported.

Xiongfeng Wang (3):
  cpufreq: handle the return value of '.set_boost()' properly
  cpufreq: export 'cpufreq_policy_list' and make macro
    'for_each_*_policy' public
  CPPC: add support for SW BOOST

 drivers/cpufreq/cppc_cpufreq.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 drivers/cpufreq/cpufreq.c      | 21 ++++++---------------
 include/linux/cpufreq.h        | 14 ++++++++++++++
 3 files changed, 60 insertions(+), 17 deletions(-)

-- 
1.7.12.4


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

* [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly
  2020-05-18  7:10 [RFC PATCH v2 0/3] add SW BOOST support for CPPC Xiongfeng Wang
@ 2020-05-18  7:10 ` Xiongfeng Wang
  2020-05-18  7:46   ` Viresh Kumar
  2020-05-18  7:10 ` [RFC PATCH v2 2/3] cpufreq: export 'cpufreq_policy_list' and make macro 'for_each_*_policy' public Xiongfeng Wang
  2020-05-18  7:10 ` [RFC PATCH v2 3/3] CPPC: add support for SW BOOST Xiongfeng Wang
  2 siblings, 1 reply; 7+ messages in thread
From: Xiongfeng Wang @ 2020-05-18  7:10 UTC (permalink / raw)
  To: rjw, viresh.kumar, Souvik.Chakravarty, Thanu.Rangarajan
  Cc: Sudeep.Holla, guohanjun, john.garry, jonathan.cameron, linux-pm,
	linux-kernel, wangxiongfeng2

'freq_qos_update_request()' called by 'cpufreq_boost_set_sw()' reutrns 1
when the effective constraint value of frequency QoS has changed. It's
not an error code. So handle the return value 1 of '.set_boost()' in
'cpufreq_boost_trigger_state()' properly.

Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
 drivers/cpufreq/cpufreq.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 4adac3a..bb6746e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2540,7 +2540,10 @@ int cpufreq_boost_trigger_state(int state)
 	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
 	ret = cpufreq_driver->set_boost(state);
-	if (ret) {
+	if (ret == 1) {
+		pr_debug("The effective constraint value of frequency QoS has changed.\n");
+		return 0;
+	} else if (ret) {
 		write_lock_irqsave(&cpufreq_driver_lock, flags);
 		cpufreq_driver->boost_enabled = !state;
 		write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-- 
1.7.12.4


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

* [RFC PATCH v2 2/3] cpufreq: export 'cpufreq_policy_list' and make macro 'for_each_*_policy' public
  2020-05-18  7:10 [RFC PATCH v2 0/3] add SW BOOST support for CPPC Xiongfeng Wang
  2020-05-18  7:10 ` [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly Xiongfeng Wang
@ 2020-05-18  7:10 ` Xiongfeng Wang
  2020-05-18  7:10 ` [RFC PATCH v2 3/3] CPPC: add support for SW BOOST Xiongfeng Wang
  2 siblings, 0 replies; 7+ messages in thread
From: Xiongfeng Wang @ 2020-05-18  7:10 UTC (permalink / raw)
  To: rjw, viresh.kumar, Souvik.Chakravarty, Thanu.Rangarajan
  Cc: Sudeep.Holla, guohanjun, john.garry, jonathan.cameron, linux-pm,
	linux-kernel, wangxiongfeng2

Export variable 'cpufreq_policy_list' and make macro 'for_each_*_policy"
public. This is preparation for adding SW BOOST support for CPPC.

Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
 drivers/cpufreq/cpufreq.c | 16 ++--------------
 include/linux/cpufreq.h   | 14 ++++++++++++++
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index bb6746e..953e163 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -30,20 +30,8 @@
 #include <linux/tick.h>
 #include <trace/events/power.h>
 
-static LIST_HEAD(cpufreq_policy_list);
-
-/* Macros to iterate over CPU policies */
-#define for_each_suitable_policy(__policy, __active)			 \
-	list_for_each_entry(__policy, &cpufreq_policy_list, policy_list) \
-		if ((__active) == !policy_is_inactive(__policy))
-
-#define for_each_active_policy(__policy)		\
-	for_each_suitable_policy(__policy, true)
-#define for_each_inactive_policy(__policy)		\
-	for_each_suitable_policy(__policy, false)
-
-#define for_each_policy(__policy)			\
-	list_for_each_entry(__policy, &cpufreq_policy_list, policy_list)
+LIST_HEAD(cpufreq_policy_list);
+EXPORT_SYMBOL_GPL(cpufreq_policy_list);
 
 /* Iterate over governors */
 static LIST_HEAD(cpufreq_governor_list);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 018dce8..27a2a7f 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -222,6 +222,20 @@ static inline bool policy_is_shared(struct cpufreq_policy *policy)
 struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy);
 void cpufreq_enable_fast_switch(struct cpufreq_policy *policy);
 void cpufreq_disable_fast_switch(struct cpufreq_policy *policy);
+
+extern struct list_head cpufreq_policy_list;
+
+/* Macros to iterate over CPU policies */
+#define for_each_suitable_policy(__policy, __active)			 \
+	list_for_each_entry(__policy, &cpufreq_policy_list, policy_list) \
+		if ((__active) == !policy_is_inactive(__policy))
+#define for_each_active_policy(__policy)		\
+	for_each_suitable_policy(__policy, true)
+#define for_each_inactive_policy(__policy)		\
+	for_each_suitable_policy(__policy, false)
+#define for_each_policy(__policy)			\
+	list_for_each_entry(__policy, &cpufreq_policy_list, policy_list)
+
 #else
 static inline unsigned int cpufreq_get(unsigned int cpu)
 {
-- 
1.7.12.4


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

* [RFC PATCH v2 3/3] CPPC: add support for SW BOOST
  2020-05-18  7:10 [RFC PATCH v2 0/3] add SW BOOST support for CPPC Xiongfeng Wang
  2020-05-18  7:10 ` [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly Xiongfeng Wang
  2020-05-18  7:10 ` [RFC PATCH v2 2/3] cpufreq: export 'cpufreq_policy_list' and make macro 'for_each_*_policy' public Xiongfeng Wang
@ 2020-05-18  7:10 ` Xiongfeng Wang
  2 siblings, 0 replies; 7+ messages in thread
From: Xiongfeng Wang @ 2020-05-18  7:10 UTC (permalink / raw)
  To: rjw, viresh.kumar, Souvik.Chakravarty, Thanu.Rangarajan
  Cc: Sudeep.Holla, guohanjun, john.garry, jonathan.cameron, linux-pm,
	linux-kernel, wangxiongfeng2

To add SW BOOST support for CPPC, we need to get the max frequency of
boost mode and non-boost mode. ACPI spec 6.2 section 8.4.7.1 describe
the following two CPC registers.

"Highest performance is the absolute maximum performance an individual
processor may reach, assuming ideal conditions. This performance level
may not be sustainable for long durations, and may only be achievable if
other platform components are in a specific state; for example, it may
require other processors be in an idle state.

Nominal Performance is the maximum sustained performance level of the
processor, assuming ideal operating conditions. In absence of an
external constraint (power, thermal, etc.) this is the performance level
the platform is expected to be able to maintain continuously. All
processors are expected to be able to sustain their nominal performance
state simultaneously."

To add SW BOOST support for CPPC, we can use Highest Performance as the
max performance in boost mode and Nominal Performance as the max
performance in non-boost mode. If the Highest Performance is greater
than the Nominal Performance, we assume SW BOOST is supported.

The current CPPC driver does not support SW BOOST and use 'Highest
Performance' as the max performance the CPU can achieve. 'Nominal
Performance' is used to convert 'performance' to 'frequency'. That
means, if firmware enable boost and provide a value for Highest
Performance which is greater than Nominal Performance, boost feature is
enabled by default.

Because SW BOOST is disabled by default, so, after this patch, boost
feature is disabled by default even if boost is enabled by firmware.

Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
---
 drivers/cpufreq/cppc_cpufreq.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index bda0b24..79fe6ac 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -37,6 +37,7 @@
  * requested etc.
  */
 static struct cppc_cpudata **all_cpu_data;
+static bool boost_supported;
 
 struct cppc_workaround_oem_info {
 	char oem_id[ACPI_OEM_ID_SIZE + 1];
@@ -310,7 +311,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	 * Section 8.4.7.1.1.5 of ACPI 6.1 spec)
 	 */
 	policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf);
-	policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
+	policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
 
 	/*
 	 * Set cpuinfo.min_freq to Lowest to make the full range of performance
@@ -318,7 +319,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	 * nonlinear perf
 	 */
 	policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf);
-	policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
+	policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
 
 	policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
 	policy->shared_type = cpu->shared_type;
@@ -343,6 +344,13 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
 	cpu->cur_policy = policy;
 
+	/*
+	 * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
+	 * is supported.
+	 */
+	if (cpu->perf_caps.highest_perf > cpu->perf_caps.nominal_perf)
+		boost_supported = true;
+
 	/* Set policy->cur to max now. The governors will adjust later. */
 	policy->cur = cppc_cpufreq_perf_to_khz(cpu,
 					cpu->perf_caps.highest_perf);
@@ -410,6 +418,35 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
 	return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
 }
 
+static int cppc_cpufreq_set_boost(int state)
+{
+	struct cpufreq_policy *policy;
+	struct cppc_cpudata *cpudata;
+	int ret = 0;
+
+	if (!boost_supported) {
+		pr_err("BOOST not supported by CPU or firmware\n");
+		return -EINVAL;
+	}
+
+	for_each_active_policy(policy) {
+		cpudata = all_cpu_data[policy->cpu];
+		if (state)
+			policy->max = cppc_cpufreq_perf_to_khz(cpudata,
+					cpudata->perf_caps.highest_perf);
+		else
+			policy->max = cppc_cpufreq_perf_to_khz(cpudata,
+					cpudata->perf_caps.nominal_perf);
+		policy->cpuinfo.max_freq = policy->max;
+
+		ret = freq_qos_update_request(policy->max_freq_req, policy->max);
+		if (ret < 0)
+			return ret;
+	}
+
+	return ret;
+}
+
 static struct cpufreq_driver cppc_cpufreq_driver = {
 	.flags = CPUFREQ_CONST_LOOPS,
 	.verify = cppc_verify_policy,
@@ -417,6 +454,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
 	.get = cppc_cpufreq_get_rate,
 	.init = cppc_cpufreq_cpu_init,
 	.stop_cpu = cppc_cpufreq_stop_cpu,
+	.set_boost = cppc_cpufreq_set_boost,
 	.name = "cppc_cpufreq",
 };
 
-- 
1.7.12.4


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

* Re: [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly
  2020-05-18  7:10 ` [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly Xiongfeng Wang
@ 2020-05-18  7:46   ` Viresh Kumar
  2020-05-18 11:43     ` Viresh Kumar
  0 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2020-05-18  7:46 UTC (permalink / raw)
  To: Xiongfeng Wang
  Cc: rjw, Souvik.Chakravarty, Thanu.Rangarajan, Sudeep.Holla,
	guohanjun, john.garry, jonathan.cameron, linux-pm, linux-kernel

On 18-05-20, 15:10, Xiongfeng Wang wrote:
> 'freq_qos_update_request()' called by 'cpufreq_boost_set_sw()' reutrns 1
> when the effective constraint value of frequency QoS has changed. It's
> not an error code. So handle the return value 1 of '.set_boost()' in
> 'cpufreq_boost_trigger_state()' properly.
> 
> Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> ---
>  drivers/cpufreq/cpufreq.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 4adac3a..bb6746e 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -2540,7 +2540,10 @@ int cpufreq_boost_trigger_state(int state)
>  	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
>  
>  	ret = cpufreq_driver->set_boost(state);
> -	if (ret) {
> +	if (ret == 1) {
> +		pr_debug("The effective constraint value of frequency QoS has changed.\n");
> +		return 0;
> +	} else if (ret) {

Rafael, IMO it is better to pick patch from Sergey for this as this is
implementation detail.

>  		write_lock_irqsave(&cpufreq_driver_lock, flags);
>  		cpufreq_driver->boost_enabled = !state;
>  		write_unlock_irqrestore(&cpufreq_driver_lock, flags);
> -- 
> 1.7.12.4

-- 
viresh

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

* Re: [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly
  2020-05-18  7:46   ` Viresh Kumar
@ 2020-05-18 11:43     ` Viresh Kumar
  2020-05-19  1:12       ` Xiongfeng Wang
  0 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2020-05-18 11:43 UTC (permalink / raw)
  To: Xiongfeng Wang
  Cc: rjw, Souvik.Chakravarty, Thanu.Rangarajan, Sudeep.Holla,
	guohanjun, john.garry, jonathan.cameron, linux-pm, linux-kernel

On 18-05-20, 13:16, Viresh Kumar wrote:
> On 18-05-20, 15:10, Xiongfeng Wang wrote:
> > 'freq_qos_update_request()' called by 'cpufreq_boost_set_sw()' reutrns 1
> > when the effective constraint value of frequency QoS has changed. It's
> > not an error code. So handle the return value 1 of '.set_boost()' in
> > 'cpufreq_boost_trigger_state()' properly.
> > 
> > Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
> > ---
> >  drivers/cpufreq/cpufreq.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 4adac3a..bb6746e 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -2540,7 +2540,10 @@ int cpufreq_boost_trigger_state(int state)
> >  	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
> >  
> >  	ret = cpufreq_driver->set_boost(state);
> > -	if (ret) {
> > +	if (ret == 1) {
> > +		pr_debug("The effective constraint value of frequency QoS has changed.\n");
> > +		return 0;
> > +	} else if (ret) {
> 
> Rafael, IMO it is better to pick patch from Sergey for this as this is
> implementation detail.
> 
> >  		write_lock_irqsave(&cpufreq_driver_lock, flags);
> >  		cpufreq_driver->boost_enabled = !state;
> >  		write_unlock_irqrestore(&cpufreq_driver_lock, flags);

This is already fixed in the PM tree with a different patch Xiongfeng.

-- 
viresh

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

* Re: [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly
  2020-05-18 11:43     ` Viresh Kumar
@ 2020-05-19  1:12       ` Xiongfeng Wang
  0 siblings, 0 replies; 7+ messages in thread
From: Xiongfeng Wang @ 2020-05-19  1:12 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: rjw, Souvik.Chakravarty, Thanu.Rangarajan, Sudeep.Holla,
	guohanjun, john.garry, jonathan.cameron, linux-pm, linux-kernel

Hi Viresh,

On 2020/5/18 19:43, Viresh Kumar wrote:
> On 18-05-20, 13:16, Viresh Kumar wrote:
>> On 18-05-20, 15:10, Xiongfeng Wang wrote:
>>> 'freq_qos_update_request()' called by 'cpufreq_boost_set_sw()' reutrns 1
>>> when the effective constraint value of frequency QoS has changed. It's
>>> not an error code. So handle the return value 1 of '.set_boost()' in
>>> 'cpufreq_boost_trigger_state()' properly.
>>>
>>> Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
>>> ---
>>>  drivers/cpufreq/cpufreq.c | 5 ++++-
>>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
>>> index 4adac3a..bb6746e 100644
>>> --- a/drivers/cpufreq/cpufreq.c
>>> +++ b/drivers/cpufreq/cpufreq.c
>>> @@ -2540,7 +2540,10 @@ int cpufreq_boost_trigger_state(int state)
>>>  	write_unlock_irqrestore(&cpufreq_driver_lock, flags);
>>>  
>>>  	ret = cpufreq_driver->set_boost(state);
>>> -	if (ret) {
>>> +	if (ret == 1) {
>>> +		pr_debug("The effective constraint value of frequency QoS has changed.\n");
>>> +		return 0;
>>> +	} else if (ret) {
>>
>> Rafael, IMO it is better to pick patch from Sergey for this as this is
>> implementation detail.
>>
>>>  		write_lock_irqsave(&cpufreq_driver_lock, flags);
>>>  		cpufreq_driver->boost_enabled = !state;
>>>  		write_unlock_irqrestore(&cpufreq_driver_lock, flags);
> 
> This is already fixed in the PM tree with a different patch Xiongfeng.

Thanks for telling me. I will drop it in the next version.

Thanks,
Xiongfeng

> 


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

end of thread, other threads:[~2020-05-19  1:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-18  7:10 [RFC PATCH v2 0/3] add SW BOOST support for CPPC Xiongfeng Wang
2020-05-18  7:10 ` [RFC PATCH v2 1/3] cpufreq: handle the return value of '.set_boost()' properly Xiongfeng Wang
2020-05-18  7:46   ` Viresh Kumar
2020-05-18 11:43     ` Viresh Kumar
2020-05-19  1:12       ` Xiongfeng Wang
2020-05-18  7:10 ` [RFC PATCH v2 2/3] cpufreq: export 'cpufreq_policy_list' and make macro 'for_each_*_policy' public Xiongfeng Wang
2020-05-18  7:10 ` [RFC PATCH v2 3/3] CPPC: add support for SW BOOST Xiongfeng Wang

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).