lkml.org 
[lkml]   [2009]   [Jun]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectRE: [PATCH 4/6] x86/cpufreq: use cpumask_copy instead of =
    Date
    From
    > powernow_k8_target is problematic: it grabs a mutex.  cpufreq 
    > people, is this called often?

    Yes. It's the function that makes a frequency change
    happen, so 5+ times per second per core isn't
    unreasonable.

    -Mark Langsdorf
    Operating System Research Center
    AMD


    > Subject: cpumask: avoid playing with cpus_allowed in powernow-k8.c
    > From: Rusty Russell <rusty@rustcorp.com.au>
    >
    > It's generally a very bad idea to mug some process's cpumask: it could
    > legitimately and reasonably be changed by root, which could break us
    > (if done before our code) or them (if we restore the wrong value).
    >
    > I use work_on_cpu, which is slightly less efficient than the old code,
    > but the code is complex enough that using smp_call_function_single()
    > is not trivial.


    > -/* Driver entry point to switch to the target frequency */
    > -static int powernowk8_target(struct cpufreq_policy *pol,
    > - unsigned targfreq, unsigned relation)
    > +struct target_data {
    > + struct cpufreq_policy *pol;
    > + unsigned targfreq;
    > + unsigned relation;
    > +};
    > +
    > +static long powernowk8_target_on_cpu(void *_tdata)
    > {
    > - cpumask_t oldmask;
    > + struct target_data *tdata = _tdata;
    > + struct cpufreq_policy *pol = tdata->pol;
    > struct powernow_k8_data *data = per_cpu(powernow_data,
    > pol->cpu);
    > u32 checkfid;
    > u32 checkvid;
    > @@ -1158,22 +1152,13 @@ static int powernowk8_target(struct cpuf
    > 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));
    > -
    > - if (smp_processor_id() != pol->cpu) {
    > - printk(KERN_ERR PFX "limiting to cpu %u
    > failed\n", pol->cpu);
    > - goto err_out;
    > - }
    > -
    > if (pending_bit_stuck()) {
    > printk(KERN_ERR PFX "failing targ, change
    > pending bit set\n");
    > goto err_out;
    > }
    >
    > dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
    > - pol->cpu, targfreq, pol->min, pol->max, relation);
    > + pol->cpu, tdata->targfreq, pol->min, pol->max,
    > tdata->relation);
    >
    > if (query_current_values_with_pending_wait(data))
    > goto err_out;
    > @@ -1193,7 +1178,8 @@ static int powernowk8_target(struct cpuf
    > }
    >
    > if (cpufreq_frequency_table_target(pol, data->powernow_table,
    > - targfreq, relation, &newstate))
    > + tdata->targfreq,
    > tdata->relation,
    > + &newstate))
    > goto err_out;
    >
    > mutex_lock(&fidvid_mutex);
    > @@ -1220,10 +1206,19 @@ static int powernowk8_target(struct cpuf
    > ret = 0;
    >
    > err_out:
    > - set_cpus_allowed_ptr(current, &oldmask);
    > return ret;
    > }
    >
    > +/* Driver entry point to switch to the target frequency */
    > +static int powernowk8_target(struct cpufreq_policy *pol,
    > + unsigned targfreq, unsigned relation)
    > +{
    > + struct target_data tdata = { .pol = pol,
    > + .targfreq = targfreq,
    > + .relation = relation };
    > + return work_on_cpu(pol->cpu, powernowk8_target_on_cpu, &tdata);
    > +}
    > +
    > /* Driver entry point to verify the policy and range of
    > frequencies */
    > static int powernowk8_verify(struct cpufreq_policy *pol)
    > {



    \
     
     \ /
      Last update: 2009-06-10 21:45    [W:2.725 / U:0.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site