2020-07-30 04:12:01

by Viresh Kumar

[permalink] [raw]
Subject: [PATCH] cpufreq: cached_resolved_idx can not be negative

It is not possible for cached_resolved_idx to be invalid here as the
cpufreq core always sets index to a positive value.

Change its type to unsigned int and fix qcom usage a bit.

Signed-off-by: Viresh Kumar <[email protected]>
---
drivers/cpufreq/qcom-cpufreq-hw.c | 5 +----
include/linux/cpufreq.h | 2 +-
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 0a04b6f03b9a..8c0842bd6c5a 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -66,13 +66,10 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
unsigned int target_freq)
{
void __iomem *perf_state_reg = policy->driver_data;
- int index;
+ unsigned int index;
unsigned long freq;

index = policy->cached_resolved_idx;
- if (index < 0)
- return 0;
-
writel_relaxed(index, perf_state_reg);

freq = policy->freq_table[index].frequency;
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index e62b022cb07e..58687a5bf9c8 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -127,7 +127,7 @@ struct cpufreq_policy {

/* Cached frequency lookup from cpufreq_driver_resolve_freq. */
unsigned int cached_target_freq;
- int cached_resolved_idx;
+ unsigned int cached_resolved_idx;

/* Synchronization for frequency transitions */
bool transition_ongoing; /* Tracks transition status */
--
2.14.1


2020-07-30 06:03:02

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH] cpufreq: cached_resolved_idx can not be negative

On Thu, Jul 30, 2020 at 9:38 AM Viresh Kumar <[email protected]> wrote:
>
> It is not possible for cached_resolved_idx to be invalid here as the
> cpufreq core always sets index to a positive value.
>
> Change its type to unsigned int and fix qcom usage a bit.

Shouldn't you fix up idx in cpufreq_driver_resolve_freq() to be
unsigned int too?

> Signed-off-by: Viresh Kumar <[email protected]>
> ---
> drivers/cpufreq/qcom-cpufreq-hw.c | 5 +----
> include/linux/cpufreq.h | 2 +-
> 2 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
> index 0a04b6f03b9a..8c0842bd6c5a 100644
> --- a/drivers/cpufreq/qcom-cpufreq-hw.c
> +++ b/drivers/cpufreq/qcom-cpufreq-hw.c
> @@ -66,13 +66,10 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
> unsigned int target_freq)
> {
> void __iomem *perf_state_reg = policy->driver_data;
> - int index;
> + unsigned int index;
> unsigned long freq;
>
> index = policy->cached_resolved_idx;
> - if (index < 0)
> - return 0;
> -
> writel_relaxed(index, perf_state_reg);
>
> freq = policy->freq_table[index].frequency;
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index e62b022cb07e..58687a5bf9c8 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -127,7 +127,7 @@ struct cpufreq_policy {
>
> /* Cached frequency lookup from cpufreq_driver_resolve_freq. */
> unsigned int cached_target_freq;
> - int cached_resolved_idx;
> + unsigned int cached_resolved_idx;
>
> /* Synchronization for frequency transitions */
> bool transition_ongoing; /* Tracks transition status */
> --
> 2.14.1
>

2020-07-30 06:11:27

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH] cpufreq: cached_resolved_idx can not be negative

On 30-07-20, 11:29, Amit Kucheria wrote:
> On Thu, Jul 30, 2020 at 9:38 AM Viresh Kumar <[email protected]> wrote:
> >
> > It is not possible for cached_resolved_idx to be invalid here as the
> > cpufreq core always sets index to a positive value.
> >
> > Change its type to unsigned int and fix qcom usage a bit.
>
> Shouldn't you fix up idx in cpufreq_driver_resolve_freq() to be
> unsigned int too?

Yes, merged this into the patch.

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0128de3603df..053d72e52a31 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -538,7 +538,7 @@ unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
policy->cached_target_freq = target_freq;

if (cpufreq_driver->target_index) {
- int idx;
+ unsigned int idx;

idx = cpufreq_frequency_table_target(policy, target_freq,
CPUFREQ_RELATION_L);

--
viresh

2020-07-30 06:35:42

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCH] cpufreq: cached_resolved_idx can not be negative

On Thu, Jul 30, 2020 at 11:40 AM Viresh Kumar <[email protected]> wrote:
>
> On 30-07-20, 11:29, Amit Kucheria wrote:
> > On Thu, Jul 30, 2020 at 9:38 AM Viresh Kumar <[email protected]> wrote:
> > >
> > > It is not possible for cached_resolved_idx to be invalid here as the
> > > cpufreq core always sets index to a positive value.
> > >
> > > Change its type to unsigned int and fix qcom usage a bit.
> >
> > Shouldn't you fix up idx in cpufreq_driver_resolve_freq() to be
> > unsigned int too?
>
> Yes, merged this into the patch.

Looking at this more closely, I found another call site for
cpufreq_frequency_table_target() in cpufreq.c that needs the index to
be unsigned int.

But then cpufreq_frequency_table_target() returns -EINVAL, so we
should be able to handle int values.

I think you will need to fix the unconditional assignment of
policy->cached_resolved_idx = idx
in cpufreq_driver_resolve_freq(). It doesn't check for -EINVAL, so the
qcom driver is write in checking for a negative value.

>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 0128de3603df..053d72e52a31 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -538,7 +538,7 @@ unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
> policy->cached_target_freq = target_freq;
>
> if (cpufreq_driver->target_index) {
> - int idx;
> + unsigned int idx;
>
> idx = cpufreq_frequency_table_target(policy, target_freq,
> CPUFREQ_RELATION_L);
>
> --
> viresh

2020-07-30 06:42:13

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH] cpufreq: cached_resolved_idx can not be negative

On 30-07-20, 12:02, Amit Kucheria wrote:
> Looking at this more closely, I found another call site for
> cpufreq_frequency_table_target() in cpufreq.c that needs the index to
> be unsigned int.
>
> But then cpufreq_frequency_table_target() returns -EINVAL, so we

It returns -EINVAL only in the case where the relation is not valid,
which will never happen. Maybe that should be marked with WARN or BUG
and we should drop return value of -EINVAL.

Rafael ?

> should be able to handle int values.

And so no.

> I think you will need to fix the unconditional assignment of
> policy->cached_resolved_idx = idx
> in cpufreq_driver_resolve_freq(). It doesn't check for -EINVAL, so the
> qcom driver is write in checking for a negative value.

Right, I don't want it to have that check for the reason stated above.

The point is I don't want code that verifies cached-idx at all, it is
useless.

--
viresh

2020-07-30 16:28:47

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH] cpufreq: cached_resolved_idx can not be negative

On Thu, Jul 30, 2020 at 8:41 AM Viresh Kumar <[email protected]> wrote:
>
> On 30-07-20, 12:02, Amit Kucheria wrote:
> > Looking at this more closely, I found another call site for
> > cpufreq_frequency_table_target() in cpufreq.c that needs the index to
> > be unsigned int.
> >
> > But then cpufreq_frequency_table_target() returns -EINVAL, so we
>
> It returns -EINVAL only in the case where the relation is not valid,
> which will never happen. Maybe that should be marked with WARN or BUG
> and we should drop return value of -EINVAL.
>
> Rafael ?

Yeah, make it a WARN_ON_ONCE() IMO.

> > should be able to handle int values.
>
> And so no.
>
> > I think you will need to fix the unconditional assignment of
> > policy->cached_resolved_idx = idx
> > in cpufreq_driver_resolve_freq(). It doesn't check for -EINVAL, so the
> > qcom driver is write in checking for a negative value.
>
> Right, I don't want it to have that check for the reason stated above.
>
> The point is I don't want code that verifies cached-idx at all, it is
> useless.
>
> --
> viresh