Commit c0672860 authored by Thomas Renninger's avatar Thomas Renninger Committed by Dave Jones

[CPUFREQ] Get rid of userspace policy struct, make userspace gov _PPC safe.

Userspace governor need not to hold it's own cpufreq_policy,
better make use of the global core policy.
Also fixes a bug in case of frequency changes via _PPC.
Old min/max values have wrongly been passed to __cpufreq_driver_target()
(kind of buffered) and when max freq was available again, only the old
max(normally lowest freq) was still active.
Signed-off-by: default avatarThomas Renninger <trenn@suse.de>
Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarDave Jones <davej@redhat.com>

 cpufreq_userspace.c |   53 +++++++++++++++++++++++++++-------------------------
 1 files changed, 28 insertions(+), 25 deletions(-)
parent 0961dd0d
/* /*
* linux/drivers/cpufreq/cpufreq_userspace.c * linux/drivers/cpufreq/cpufreq_userspace.c
* *
...@@ -34,7 +35,6 @@ static unsigned int cpu_min_freq[NR_CPUS]; ...@@ -34,7 +35,6 @@ static unsigned int cpu_min_freq[NR_CPUS];
static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */
static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
static unsigned int cpu_is_managed[NR_CPUS]; static unsigned int cpu_is_managed[NR_CPUS];
static struct cpufreq_policy current_policy[NR_CPUS];
static DEFINE_MUTEX (userspace_mutex); static DEFINE_MUTEX (userspace_mutex);
...@@ -65,22 +65,22 @@ static struct notifier_block userspace_cpufreq_notifier_block = { ...@@ -65,22 +65,22 @@ static struct notifier_block userspace_cpufreq_notifier_block = {
* *
* Sets the CPU frequency to freq. * Sets the CPU frequency to freq.
*/ */
static int cpufreq_set(unsigned int freq, unsigned int cpu) static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
{ {
int ret = -EINVAL; int ret = -EINVAL;
dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq); dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
mutex_lock(&userspace_mutex); mutex_lock(&userspace_mutex);
if (!cpu_is_managed[cpu]) if (!cpu_is_managed[policy->cpu])
goto err; goto err;
cpu_set_freq[cpu] = freq; cpu_set_freq[policy->cpu] = freq;
if (freq < cpu_min_freq[cpu]) if (freq < cpu_min_freq[policy->cpu])
freq = cpu_min_freq[cpu]; freq = cpu_min_freq[policy->cpu];
if (freq > cpu_max_freq[cpu]) if (freq > cpu_max_freq[policy->cpu])
freq = cpu_max_freq[cpu]; freq = cpu_max_freq[policy->cpu];
/* /*
* We're safe from concurrent calls to ->target() here * We're safe from concurrent calls to ->target() here
...@@ -89,8 +89,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu) ...@@ -89,8 +89,7 @@ static int cpufreq_set(unsigned int freq, unsigned int cpu)
* A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
* B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
*/ */
ret = __cpufreq_driver_target(&current_policy[cpu], freq, ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
CPUFREQ_RELATION_L);
err: err:
mutex_unlock(&userspace_mutex); mutex_unlock(&userspace_mutex);
...@@ -114,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count) ...@@ -114,7 +113,7 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
if (ret != 1) if (ret != 1)
return -EINVAL; return -EINVAL;
cpufreq_set(freq, policy->cpu); cpufreq_set(freq, policy);
return count; return count;
} }
...@@ -142,7 +141,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, ...@@ -142,7 +141,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_cur_freq[cpu] = policy->cur; cpu_cur_freq[cpu] = policy->cur;
cpu_set_freq[cpu] = policy->cur; cpu_set_freq[cpu] = policy->cur;
sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
mutex_unlock(&userspace_mutex); mutex_unlock(&userspace_mutex);
break; break;
...@@ -158,20 +156,25 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, ...@@ -158,20 +156,25 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
break; break;
case CPUFREQ_GOV_LIMITS: case CPUFREQ_GOV_LIMITS:
mutex_lock(&userspace_mutex); mutex_lock(&userspace_mutex);
cpu_min_freq[cpu] = policy->min; dprintk("limit event for cpu %u: %u - %u kHz,"
cpu_max_freq[cpu] = policy->max; "currently %u kHz, last set to %u kHz\n",
dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]); cpu, policy->min, policy->max,
cpu_cur_freq[cpu], cpu_set_freq[cpu]);
if (policy->max < cpu_set_freq[cpu]) { if (policy->max < cpu_set_freq[cpu]) {
__cpufreq_driver_target(&current_policy[cpu], policy->max, __cpufreq_driver_target(policy, policy->max,
CPUFREQ_RELATION_H); CPUFREQ_RELATION_H);
} else if (policy->min > cpu_set_freq[cpu]) { }
__cpufreq_driver_target(&current_policy[cpu], policy->min, else if (policy->min > cpu_set_freq[cpu]) {
CPUFREQ_RELATION_L); __cpufreq_driver_target(policy, policy->min,
} else { CPUFREQ_RELATION_L);
__cpufreq_driver_target(&current_policy[cpu], cpu_set_freq[cpu],
CPUFREQ_RELATION_L);
} }
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy)); else {
__cpufreq_driver_target(policy, cpu_set_freq[cpu],
CPUFREQ_RELATION_L);
}
cpu_min_freq[cpu] = policy->min;
cpu_max_freq[cpu] = policy->max;
cpu_cur_freq[cpu] = policy->cur;
mutex_unlock(&userspace_mutex); mutex_unlock(&userspace_mutex);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment