Skip to content

Commit

Permalink
[CPUFREQ] If max_freq got reduced (e.g. by _PPC) a write to sysfs sca…
Browse files Browse the repository at this point in the history
…ling_governor let cpufreq core stuck at low max_freq for ever

The previous patch had bugs (locking and refcount).

This one could also be related to the latest DELL reports.
But they only slip into this if a user prog (e.g. powersave daemon does when
AC got (un) plugged due to a scheme change) echos something to
/sys/../cpufreq/scaling_governor
while the frequencies got limited by BIOS.

This one works:

Subject: Max freq stucks at low freq if reduced by _PPC and sysfs gov access

The problem is reproducable by(if machine is limiting freqs via BIOS):
 - Unplugging AC -> max freq gets limited
 - echo ${governor} >/sys/.../cpufreq/scaling_governor (policy->user_data.max
   gets overridden with policy->max and will never come up again.)

This patch exchanged the cpufreq_set_policy call to __cpufreq_set_policy and
duplicated it's functionality but did not override user_data.max.
The same happens with overridding min/max values. If freqs are limited and
you override the min freq value, the max freq global value will also get
stuck to the limited freq, even if BIOS allows all freqs again.
Last scenario does only happen if BIOS does not reduce the frequency
to the lowest value (should never happen, just for correctness...)

 drivers/cpufreq/cpufreq.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
Signed-off-by: Dave Jones <davej@redhat.com>
  • Loading branch information
Thomas Renninger authored and Dave Jones committed Apr 18, 2006
1 parent f1f76af commit 7970e08
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ show_one(scaling_min_freq, min);
show_one(scaling_max_freq, max);
show_one(scaling_cur_freq, cur);

static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy);

/**
* cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
*/
Expand All @@ -364,7 +366,10 @@ static ssize_t store_##file_name \
if (ret != 1) \
return -EINVAL; \
\
ret = cpufreq_set_policy(&new_policy); \
mutex_lock(&policy->lock); \
ret = __cpufreq_set_policy(policy, &new_policy); \
policy->user_policy.object = policy->object; \
mutex_unlock(&policy->lock); \
\
return ret ? ret : count; \
}
Expand Down Expand Up @@ -420,7 +425,15 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor))
return -EINVAL;

ret = cpufreq_set_policy(&new_policy);
/* Do not use cpufreq_set_policy here or the user_policy.max
will be wrongly overridden */
mutex_lock(&policy->lock);
ret = __cpufreq_set_policy(policy, &new_policy);

policy->user_policy.policy = policy->policy;
policy->user_policy.governor = policy->governor;
mutex_unlock(&policy->lock);

return ret ? ret : count;
}

Expand Down

0 comments on commit 7970e08

Please sign in to comment.