Skip to content

Commit

Permalink
cpufreq: Introduce CPUFREQ_NEED_UPDATE_LIMITS driver flag
Browse files Browse the repository at this point in the history
commit 1c53435 upstream.

Generally, a cpufreq driver may need to update some internal upper
and lower frequency boundaries on policy max and min changes,
respectively, but currently this does not work if the target
frequency does not change along with the policy limit.

Namely, if the target frequency does not change along with the
policy min or max, the "target_freq == policy->cur" check in
__cpufreq_driver_target() prevents driver callbacks from being
invoked and they do not even have a chance to update the
corresponding internal boundary.

This particularly affects the "powersave" and "performance"
governors that always set the target frequency to one of the
policy limits and it never changes when the other limit is updated.

To allow cpufreq the drivers needing to update internal frequency
boundaries on policy limits changes to avoid this issue, introduce
a new driver flag, CPUFREQ_NEED_UPDATE_LIMITS, that (when set) will
neutralize the check mentioned above.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
rafaeljw authored and gregkh committed Nov 5, 2020
1 parent 345b28c commit db6e432
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
3 changes: 2 additions & 1 deletion drivers/cpufreq/cpufreq.c
Expand Up @@ -2166,7 +2166,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
* exactly same freq is called again and so we can save on few function
* calls.
*/
if (target_freq == policy->cur)
if (target_freq == policy->cur &&
!(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS))
return 0;

/* Save last value to restore later on errors */
Expand Down
10 changes: 9 additions & 1 deletion include/linux/cpufreq.h
Expand Up @@ -293,7 +293,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)

struct cpufreq_driver {
char name[CPUFREQ_NAME_LEN];
u8 flags;
u16 flags;
void *driver_data;

/* needed by all drivers */
Expand Down Expand Up @@ -417,6 +417,14 @@ struct cpufreq_driver {
*/
#define CPUFREQ_IS_COOLING_DEV BIT(7)

/*
* Set by drivers that need to update internale upper and lower boundaries along
* with the target frequency and so the core and governors should also invoke
* the diver if the target frequency does not change, but the policy min or max
* may have changed.
*/
#define CPUFREQ_NEED_UPDATE_LIMITS BIT(8)

int cpufreq_register_driver(struct cpufreq_driver *driver_data);
int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);

Expand Down

0 comments on commit db6e432

Please sign in to comment.