Commit 1a8a3fc2 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus

Save the "affected_cpu_map" used in SMT-aware drivers in struct
cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In
most cases, the ->get() function is only allowed to run on one CPU [the
one passed as argument] to keep code simpler, and as that code path
isn't executed often, and only root can do it anyway.
Signed-off-by: default avatarDominik Brodowski <linux@brodo.de>
Signed-off-by: default avatarDave Jones <davej@redhat.com>
parent 0569d1c8
......@@ -110,7 +110,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
{
unsigned int newstate = DC_RESV;
struct cpufreq_freqs freqs;
cpumask_t cpus_allowed, affected_cpu_map;
cpumask_t cpus_allowed;
int i;
if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate))
......@@ -122,18 +122,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
if (freqs.new == freqs.old)
return 0;
/* switch to physical CPU where state is to be changed*/
cpus_allowed = current->cpus_allowed;
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
affected_cpu_map = cpu_sibling_map[policy->cpu];
#else
affected_cpu_map = cpumask_of_cpu(policy->cpu);
#endif
/* notifiers */
for_each_cpu_mask(i, affected_cpu_map) {
for_each_cpu_mask(i, policy->cpus) {
freqs.cpu = i;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
}
......@@ -141,7 +131,9 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
/* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
* Developer's Manual, Volume 3
*/
for_each_cpu_mask(i, affected_cpu_map) {
cpus_allowed = current->cpus_allowed;
for_each_cpu_mask(i, policy->cpus) {
cpumask_t this_cpu = cpumask_of_cpu(i);
set_cpus_allowed(current, this_cpu);
......@@ -152,7 +144,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
set_cpus_allowed(current, cpus_allowed);
/* notifiers */
for_each_cpu_mask(i, affected_cpu_map) {
for_each_cpu_mask(i, policy->cpus) {
freqs.cpu = i;
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
......@@ -219,6 +211,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
int cpuid = 0;
unsigned int i;
#ifdef CONFIG_SMP
policy->cpus = cpu_sibling_map[policy->cpu];
#endif
/* Errata workaround */
cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask;
switch (cpuid) {
......@@ -260,14 +256,13 @@ static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy)
static unsigned int cpufreq_p4_get(unsigned int cpu)
{
cpumask_t cpus_allowed, affected_cpu_map;
cpumask_t cpus_allowed;
u32 l, h;
cpus_allowed = current->cpus_allowed;
affected_cpu_map = cpumask_of_cpu(cpu);
set_cpus_allowed(current, affected_cpu_map);
BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map));
set_cpus_allowed(current, cpumask_of_cpu(cpu));
BUG_ON(smp_processor_id() != cpu);
rdmsr(MSR_IA32_THERM_CONTROL, l, h);
......@@ -335,4 +330,3 @@ MODULE_LICENSE ("GPL");
late_initcall(cpufreq_p4_init);
module_exit(cpufreq_p4_exit);
......@@ -569,7 +569,7 @@ static int centrino_target (struct cpufreq_policy *policy,
* Make sure we are running on the CPU that wants to change frequency
*/
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(policy->cpu));
set_cpus_allowed(current, policy->cpus);
if (smp_processor_id() != policy->cpu) {
return(-EAGAIN);
}
......
......@@ -223,24 +223,23 @@ static unsigned int speedstep_detect_chipset (void)
return 0;
}
static unsigned int speedstep_get(unsigned int cpu)
static unsigned int _speedstep_get(cpumask_t cpus)
{
unsigned int speed;
cpumask_t cpus_allowed,affected_cpu_map;
cpumask_t cpus_allowed;
/* only run on CPU to be set, or on its sibling */
cpus_allowed = current->cpus_allowed;
#ifdef CONFIG_SMP
affected_cpu_map = cpu_sibling_map[cpu];
#else
affected_cpu_map = cpumask_of_cpu(cpu);
#endif
set_cpus_allowed(current, affected_cpu_map);
speed=speedstep_get_processor_frequency(speedstep_processor);
set_cpus_allowed(current, cpus);
speed = speedstep_get_processor_frequency(speedstep_processor);
set_cpus_allowed(current, cpus_allowed);
return speed;
}
static unsigned int speedstep_get(unsigned int cpu)
{
return _speedstep_get(cpumask_of_cpu(cpu));
}
/**
* speedstep_target - set a new CPUFreq policy
* @policy: new policy
......@@ -255,13 +254,13 @@ static int speedstep_target (struct cpufreq_policy *policy,
{
unsigned int newstate = 0;
struct cpufreq_freqs freqs;
cpumask_t cpus_allowed, affected_cpu_map;
cpumask_t cpus_allowed;
int i;
if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
return -EINVAL;
freqs.old = speedstep_get(policy->cpu);
freqs.old = _speedstep_get(policy->cpus);
freqs.new = speedstep_freqs[newstate].frequency;
freqs.cpu = policy->cpu;
......@@ -271,27 +270,20 @@ static int speedstep_target (struct cpufreq_policy *policy,
cpus_allowed = current->cpus_allowed;
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
affected_cpu_map = cpu_sibling_map[policy->cpu];
#else
affected_cpu_map = cpumask_of_cpu(policy->cpu);
#endif
for_each_cpu_mask(i, affected_cpu_map) {
for_each_cpu_mask(i, policy->cpus) {
freqs.cpu = i;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
}
/* switch to physical CPU where state is to be changed */
set_cpus_allowed(current, affected_cpu_map);
set_cpus_allowed(current, policy->cpus);
speedstep_set_state(newstate);
/* allow to be run on all CPUs */
set_cpus_allowed(current, cpus_allowed);
for_each_cpu_mask(i, affected_cpu_map) {
for_each_cpu_mask(i, policy->cpus) {
freqs.cpu = i;
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
......@@ -317,7 +309,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
unsigned int speed;
cpumask_t cpus_allowed,affected_cpu_map;
cpumask_t cpus_allowed;
/* capability check */
......@@ -327,11 +319,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
/* only run on CPU to be set, or on its sibling */
cpus_allowed = current->cpus_allowed;
#ifdef CONFIG_SMP
affected_cpu_map = cpu_sibling_map[policy->cpu];
#else
affected_cpu_map = cpumask_of_cpu(policy->cpu);
policy->cpus = cpu_sibling_map[policy->cpu];
#endif
set_cpus_allowed(current, affected_cpu_map);
set_cpus_allowed(current, policy->cpus);
/* detect low and high frequency */
result = speedstep_get_freqs(speedstep_processor,
......@@ -343,7 +333,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
return result;
/* get current speed setting */
speed = speedstep_get(policy->cpu);
speed = _speedstep_get(policy->cpus);
if (!speed)
return -EIO;
......
......@@ -468,6 +468,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
memset(policy, 0, sizeof(struct cpufreq_policy));
policy->cpu = cpu;
policy->cpus = cpumask_of_cpu(cpu);
init_MUTEX_LOCKED(&policy->lock);
init_completion(&policy->kobj_unregister);
INIT_WORK(&policy->update, handle_update, (void *)(long)cpu);
......
......@@ -22,6 +22,7 @@
#include <linux/sysfs.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/cpumask.h>
#define CPUFREQ_NAME_LEN 16
......@@ -69,7 +70,8 @@ struct cpufreq_real_policy {
};
struct cpufreq_policy {
unsigned int cpu; /* cpu nr */
cpumask_t cpus; /* affected CPUs */
unsigned int cpu; /* cpu nr of registered CPU */
struct cpufreq_cpuinfo cpuinfo;/* see above */
unsigned int min; /* in kHz */
......
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