[CPUFREQ] cpumask: don't put a cpumask on the stack in x86...cpufreq/powernow-k8.c
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 3 Nov 2009 04:27:56 +0000 (14:57 +1030)
committerDave Jones <davej@redhat.com>
Tue, 24 Nov 2009 18:33:33 +0000 (13:33 -0500)
It's still mugging the current process's cpumask, but as comment in
1ff6e97f1d says, it's not a trivial fix.

So, at least we can use a cpumask_var_t to do the Wrong Thing the Right Way :)

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
To: cpufreq@vger.kernel.org
Cc: Mark Langsdorf <mark.langsdorf@amd.com>
Signed-off-by: Dave Jones <davej@redhat.com>
arch/x86/kernel/cpu/cpufreq/powernow-k8.c

index 3f12dab..f30d253 100644 (file)
@@ -1118,7 +1118,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
 static int powernowk8_target(struct cpufreq_policy *pol,
                unsigned targfreq, unsigned relation)
 {
-       cpumask_t oldmask;
+       cpumask_var_t oldmask;
        struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
        u32 checkfid;
        u32 checkvid;
@@ -1131,9 +1131,13 @@ static int powernowk8_target(struct cpufreq_policy *pol,
        checkfid = data->currfid;
        checkvid = data->currvid;
 
-       /* only run on specific CPU from here on */
-       oldmask = current->cpus_allowed;
-       set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu));
+       /* only run on specific CPU from here on. */
+       /* This is poor form: use a workqueue or smp_call_function_single */
+       if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
+               return -ENOMEM;
+
+       cpumask_copy(oldmask, tsk_cpumask(current));
+       set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
 
        if (smp_processor_id() != pol->cpu) {
                printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
@@ -1193,7 +1197,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
        ret = 0;
 
 err_out:
-       set_cpus_allowed_ptr(current, &oldmask);
+       set_cpus_allowed_ptr(current, oldmask);
+       free_cpumask_var(oldmask);
        return ret;
 }