Merge branches 'pm-cpufreq-x86', 'pm-cpufreq-docs' and 'intel_pstate'
* pm-cpufreq-x86: cpufreq: x86: Make scaling_cur_freq behave more as expected * pm-cpufreq-docs: cpufreq: docs: Add missing cpuinfo_cur_freq description * intel_pstate: cpufreq: intel_pstate: Drop ->get from intel_pstate structure
This commit is contained in:
commit
8a05c3115d
|
@ -237,6 +237,14 @@ are the following:
|
||||||
This attribute is not present if the scaling driver in use does not
|
This attribute is not present if the scaling driver in use does not
|
||||||
support it.
|
support it.
|
||||||
|
|
||||||
|
``cpuinfo_cur_freq``
|
||||||
|
Current frequency of the CPUs belonging to this policy as obtained from
|
||||||
|
the hardware (in KHz).
|
||||||
|
|
||||||
|
This is expected to be the frequency the hardware actually runs at.
|
||||||
|
If that frequency cannot be determined, this attribute should not
|
||||||
|
be present.
|
||||||
|
|
||||||
``cpuinfo_max_freq``
|
``cpuinfo_max_freq``
|
||||||
Maximum possible operating frequency the CPUs belonging to this policy
|
Maximum possible operating frequency the CPUs belonging to this policy
|
||||||
can run at (in kHz).
|
can run at (in kHz).
|
||||||
|
|
|
@ -8,20 +8,25 @@
|
||||||
* This file is licensed under GPLv2.
|
* This file is licensed under GPLv2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/jiffies.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/ktime.h>
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
|
||||||
struct aperfmperf_sample {
|
struct aperfmperf_sample {
|
||||||
unsigned int khz;
|
unsigned int khz;
|
||||||
unsigned long jiffies;
|
ktime_t time;
|
||||||
u64 aperf;
|
u64 aperf;
|
||||||
u64 mperf;
|
u64 mperf;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
|
static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
|
||||||
|
|
||||||
|
#define APERFMPERF_CACHE_THRESHOLD_MS 10
|
||||||
|
#define APERFMPERF_REFRESH_DELAY_MS 20
|
||||||
|
#define APERFMPERF_STALE_THRESHOLD_MS 1000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* aperfmperf_snapshot_khz()
|
* aperfmperf_snapshot_khz()
|
||||||
* On the current CPU, snapshot APERF, MPERF, and jiffies
|
* On the current CPU, snapshot APERF, MPERF, and jiffies
|
||||||
|
@ -33,9 +38,11 @@ static void aperfmperf_snapshot_khz(void *dummy)
|
||||||
u64 aperf, aperf_delta;
|
u64 aperf, aperf_delta;
|
||||||
u64 mperf, mperf_delta;
|
u64 mperf, mperf_delta;
|
||||||
struct aperfmperf_sample *s = this_cpu_ptr(&samples);
|
struct aperfmperf_sample *s = this_cpu_ptr(&samples);
|
||||||
|
ktime_t now = ktime_get();
|
||||||
|
s64 time_delta = ktime_ms_delta(now, s->time);
|
||||||
|
|
||||||
/* Don't bother re-computing within 10 ms */
|
/* Don't bother re-computing within the cache threshold time. */
|
||||||
if (time_before(jiffies, s->jiffies + HZ/100))
|
if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rdmsrl(MSR_IA32_APERF, aperf);
|
rdmsrl(MSR_IA32_APERF, aperf);
|
||||||
|
@ -51,22 +58,21 @@ static void aperfmperf_snapshot_khz(void *dummy)
|
||||||
if (mperf_delta == 0)
|
if (mperf_delta == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
s->time = now;
|
||||||
* if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
|
|
||||||
* khz = (cpu_khz * aperf_delta) / mperf_delta
|
|
||||||
*/
|
|
||||||
if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
|
|
||||||
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
|
|
||||||
else /* khz = aperf_delta / (mperf_delta / cpu_khz) */
|
|
||||||
s->khz = div64_u64(aperf_delta,
|
|
||||||
div64_u64(mperf_delta, cpu_khz));
|
|
||||||
s->jiffies = jiffies;
|
|
||||||
s->aperf = aperf;
|
s->aperf = aperf;
|
||||||
s->mperf = mperf;
|
s->mperf = mperf;
|
||||||
|
|
||||||
|
/* If the previous iteration was too long ago, discard it. */
|
||||||
|
if (time_delta > APERFMPERF_STALE_THRESHOLD_MS)
|
||||||
|
s->khz = 0;
|
||||||
|
else
|
||||||
|
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int arch_freq_get_on_cpu(int cpu)
|
unsigned int arch_freq_get_on_cpu(int cpu)
|
||||||
{
|
{
|
||||||
|
unsigned int khz;
|
||||||
|
|
||||||
if (!cpu_khz)
|
if (!cpu_khz)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -74,6 +80,12 @@ unsigned int arch_freq_get_on_cpu(int cpu)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
|
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
|
||||||
|
khz = per_cpu(samples.khz, cpu);
|
||||||
|
if (khz)
|
||||||
|
return khz;
|
||||||
|
|
||||||
|
msleep(APERFMPERF_REFRESH_DELAY_MS);
|
||||||
|
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
|
||||||
|
|
||||||
return per_cpu(samples.khz, cpu);
|
return per_cpu(samples.khz, cpu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1922,13 +1922,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int intel_pstate_get(unsigned int cpu_num)
|
|
||||||
{
|
|
||||||
struct cpudata *cpu = all_cpu_data[cpu_num];
|
|
||||||
|
|
||||||
return cpu ? get_avg_frequency(cpu) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
|
static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
|
||||||
{
|
{
|
||||||
struct cpudata *cpu = all_cpu_data[cpu_num];
|
struct cpudata *cpu = all_cpu_data[cpu_num];
|
||||||
|
@ -2169,7 +2162,6 @@ static struct cpufreq_driver intel_pstate = {
|
||||||
.setpolicy = intel_pstate_set_policy,
|
.setpolicy = intel_pstate_set_policy,
|
||||||
.suspend = intel_pstate_hwp_save_state,
|
.suspend = intel_pstate_hwp_save_state,
|
||||||
.resume = intel_pstate_resume,
|
.resume = intel_pstate_resume,
|
||||||
.get = intel_pstate_get,
|
|
||||||
.init = intel_pstate_cpu_init,
|
.init = intel_pstate_cpu_init,
|
||||||
.exit = intel_pstate_cpu_exit,
|
.exit = intel_pstate_cpu_exit,
|
||||||
.stop_cpu = intel_pstate_stop_cpu,
|
.stop_cpu = intel_pstate_stop_cpu,
|
||||||
|
|
Loading…
Reference in New Issue