]> git.hungrycats.org Git - linux/commitdiff
[CPUFREQ] speedstep-ich SMT support.
authorDave Jones <davej@redhat.com>
Mon, 2 Aug 2004 21:14:21 +0000 (22:14 +0100)
committerDave Jones <davej@delerium.codemonkey.org.uk>
Mon, 2 Aug 2004 21:14:21 +0000 (22:14 +0100)
i have noticed that the most recent vanilla kernel oopses on a P4M-HT
(because only one CPU is registered in sysfs but 2 are informed of a
change of state). also there are some returns out of subroutines before
set_cpus_allowed() is performed to restore the mask prior to entering
the subroutine (this should not matter on uniprocessor systems, but
still...).

this patch should fix these 2 issues. for the first one, it registers
all logical cpu's and a tiny modification is made in cpufreq.c to
perform a policy change on all siblings.

From: Christian Hoelbling
Signed-off-by: Dave Jones <davej@redhat.com>
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c

index 93b70f0dc53b2a6e4012c57894c4c5420d2b182a..6e463e50a44e777893d5a0ca2cfb507d0555e57e 100644 (file)
@@ -247,14 +247,14 @@ static int speedstep_target (struct cpufreq_policy *policy,
        if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
                return -EINVAL;
 
+       freqs.old = speedstep_get(policy->cpu);
+       freqs.new = speedstep_freqs[newstate].frequency;
+       freqs.cpu = policy->cpu;
+
        /* no transition necessary */
        if (freqs.old == freqs.new)
                return 0;
 
-       freqs.old = speedstep_get_processor_frequency(speedstep_processor);
-       freqs.new = speedstep_freqs[newstate].frequency;
-       freqs.cpu = policy->cpu;
-
        cpus_allowed = current->cpus_allowed;
 
        /* only run on CPU to be set, or on its sibling */
@@ -324,14 +324,13 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
                                     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
                                     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
                                     &speedstep_set_state);
+       set_cpus_allowed(current, cpus_allowed);
        if (result) {
-               set_cpus_allowed(current, cpus_allowed);
                return result;
        }
 
        /* get current speed setting */
-       speed = speedstep_get_processor_frequency(speedstep_processor);
-       set_cpus_allowed(current, cpus_allowed);
+       speed = speedstep_get(policy->cpu);
        if (!speed)
                return -EIO;
 
@@ -362,7 +361,20 @@ static int speedstep_cpu_exit(struct cpufreq_policy *policy)
 
 static unsigned int speedstep_get(unsigned int cpu)
 {
-       return speedstep_get_processor_frequency(speedstep_processor);
+       unsigned int    speed;
+       cpumask_t       cpus_allowed,affected_cpu_map;
+ 
+       /* 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_allowed);
+       return speed;
 }
 
 static struct freq_attr* speedstep_attr[] = {