On Fri, 1 Apr 2016, Len Brown wrote:
> +/*
> + * aperfmperf_snapshot_khz()
> + * On the current CPU, snapshot APERF, MPERF, and jiffies
> + * unless we already did it within 100ms
> + * calculate kHz, save snapshot
> + */
> +static void aperfmperf_snapshot_khz(void *dummy)
> +{
> +     unsigned long long aperf, aperf_delta;
> +     unsigned long long mperf, mperf_delta;
> +     unsigned long long numerator;
> +     struct aperfmperf_sample *s = &get_cpu_var(samples);

this_cpu_ptr is sufficient. That's a smp function call ...

> +
> +     /* Cache KHz for 100 ms */
> +     if (time_before(jiffies, s->jiffies + HZ/10))
> +             goto out;
> +
> +     rdmsrl(MSR_IA32_APERF, aperf);
> +     rdmsrl(MSR_IA32_MPERF, mperf);
> +
> +     aperf_delta = aperf - s->aperf;
> +     mperf_delta = mperf - s->mperf;
> +
> +     /*
> +      * There is no architectural guarantee that MPERF
> +      * increments faster than we can read it.
> +      */
> +     if (mperf_delta == 0)
> +             goto out;
> +
> +     numerator = cpu_khz * aperf_delta;
> +     s->khz = div64_u64(numerator, mperf_delta);
> +     s->jiffies = jiffies;
> +     s->aperf = aperf;
> +     s->mperf = mperf;
> +
> +out:
> +     put_cpu_var(samples);
> +}
> +
> +unsigned int aperfmperf_khz_on_cpu(int cpu)
> +{
> +     if (!cpu_khz)
> +             return 0;
> +
> +     if (!boot_cpu_has(X86_FEATURE_APERFMPERF))
> +             return 0;
> +
> +     smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);

You can avoid the function call if you check s->jiffies here.

Thanks,

        tglx

Reply via email to