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