mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
cpufreq: amd-pstate: Add more tracepoint for AMD P-State module
Add frequency, mperf, aperf and tsc in the trace. This can be used to debug and tune the performance of AMD P-state driver. Use the time difference between amd_pstate_update to calculate CPU frequency. There could be sleep in arch_freq_get_on_cpu, so do not use it here. Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com> Co-developed-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
a1b6f487cb
commit
23c296fb7e
@ -27,6 +27,10 @@ TRACE_EVENT(amd_pstate_perf,
|
|||||||
TP_PROTO(unsigned long min_perf,
|
TP_PROTO(unsigned long min_perf,
|
||||||
unsigned long target_perf,
|
unsigned long target_perf,
|
||||||
unsigned long capacity,
|
unsigned long capacity,
|
||||||
|
u64 freq,
|
||||||
|
u64 mperf,
|
||||||
|
u64 aperf,
|
||||||
|
u64 tsc,
|
||||||
unsigned int cpu_id,
|
unsigned int cpu_id,
|
||||||
bool changed,
|
bool changed,
|
||||||
bool fast_switch
|
bool fast_switch
|
||||||
@ -35,6 +39,10 @@ TRACE_EVENT(amd_pstate_perf,
|
|||||||
TP_ARGS(min_perf,
|
TP_ARGS(min_perf,
|
||||||
target_perf,
|
target_perf,
|
||||||
capacity,
|
capacity,
|
||||||
|
freq,
|
||||||
|
mperf,
|
||||||
|
aperf,
|
||||||
|
tsc,
|
||||||
cpu_id,
|
cpu_id,
|
||||||
changed,
|
changed,
|
||||||
fast_switch
|
fast_switch
|
||||||
@ -44,6 +52,10 @@ TRACE_EVENT(amd_pstate_perf,
|
|||||||
__field(unsigned long, min_perf)
|
__field(unsigned long, min_perf)
|
||||||
__field(unsigned long, target_perf)
|
__field(unsigned long, target_perf)
|
||||||
__field(unsigned long, capacity)
|
__field(unsigned long, capacity)
|
||||||
|
__field(unsigned long long, freq)
|
||||||
|
__field(unsigned long long, mperf)
|
||||||
|
__field(unsigned long long, aperf)
|
||||||
|
__field(unsigned long long, tsc)
|
||||||
__field(unsigned int, cpu_id)
|
__field(unsigned int, cpu_id)
|
||||||
__field(bool, changed)
|
__field(bool, changed)
|
||||||
__field(bool, fast_switch)
|
__field(bool, fast_switch)
|
||||||
@ -53,15 +65,23 @@ TRACE_EVENT(amd_pstate_perf,
|
|||||||
__entry->min_perf = min_perf;
|
__entry->min_perf = min_perf;
|
||||||
__entry->target_perf = target_perf;
|
__entry->target_perf = target_perf;
|
||||||
__entry->capacity = capacity;
|
__entry->capacity = capacity;
|
||||||
|
__entry->freq = freq;
|
||||||
|
__entry->mperf = mperf;
|
||||||
|
__entry->aperf = aperf;
|
||||||
|
__entry->tsc = tsc;
|
||||||
__entry->cpu_id = cpu_id;
|
__entry->cpu_id = cpu_id;
|
||||||
__entry->changed = changed;
|
__entry->changed = changed;
|
||||||
__entry->fast_switch = fast_switch;
|
__entry->fast_switch = fast_switch;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u changed=%s fast_switch=%s",
|
TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s",
|
||||||
(unsigned long)__entry->min_perf,
|
(unsigned long)__entry->min_perf,
|
||||||
(unsigned long)__entry->target_perf,
|
(unsigned long)__entry->target_perf,
|
||||||
(unsigned long)__entry->capacity,
|
(unsigned long)__entry->capacity,
|
||||||
|
(unsigned long long)__entry->freq,
|
||||||
|
(unsigned long long)__entry->mperf,
|
||||||
|
(unsigned long long)__entry->aperf,
|
||||||
|
(unsigned long long)__entry->tsc,
|
||||||
(unsigned int)__entry->cpu_id,
|
(unsigned int)__entry->cpu_id,
|
||||||
(__entry->changed) ? "true" : "false",
|
(__entry->changed) ? "true" : "false",
|
||||||
(__entry->fast_switch) ? "true" : "false"
|
(__entry->fast_switch) ? "true" : "false"
|
||||||
|
@ -65,6 +65,18 @@ MODULE_PARM_DESC(shared_mem,
|
|||||||
|
|
||||||
static struct cpufreq_driver amd_pstate_driver;
|
static struct cpufreq_driver amd_pstate_driver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct amd_aperf_mperf
|
||||||
|
* @aperf: actual performance frequency clock count
|
||||||
|
* @mperf: maximum performance frequency clock count
|
||||||
|
* @tsc: time stamp counter
|
||||||
|
*/
|
||||||
|
struct amd_aperf_mperf {
|
||||||
|
u64 aperf;
|
||||||
|
u64 mperf;
|
||||||
|
u64 tsc;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct amd_cpudata - private CPU data for AMD P-State
|
* struct amd_cpudata - private CPU data for AMD P-State
|
||||||
* @cpu: CPU number
|
* @cpu: CPU number
|
||||||
@ -81,6 +93,9 @@ static struct cpufreq_driver amd_pstate_driver;
|
|||||||
* @min_freq: the frequency that mapped to lowest_perf
|
* @min_freq: the frequency that mapped to lowest_perf
|
||||||
* @nominal_freq: the frequency that mapped to nominal_perf
|
* @nominal_freq: the frequency that mapped to nominal_perf
|
||||||
* @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
|
* @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
|
||||||
|
* @cur: Difference of Aperf/Mperf/tsc count between last and current sample
|
||||||
|
* @prev: Last Aperf/Mperf/tsc count value read from register
|
||||||
|
* @freq: current cpu frequency value
|
||||||
* @boost_supported: check whether the Processor or SBIOS supports boost mode
|
* @boost_supported: check whether the Processor or SBIOS supports boost mode
|
||||||
*
|
*
|
||||||
* The amd_cpudata is key private data for each CPU thread in AMD P-State, and
|
* The amd_cpudata is key private data for each CPU thread in AMD P-State, and
|
||||||
@ -102,6 +117,10 @@ struct amd_cpudata {
|
|||||||
u32 nominal_freq;
|
u32 nominal_freq;
|
||||||
u32 lowest_nonlinear_freq;
|
u32 lowest_nonlinear_freq;
|
||||||
|
|
||||||
|
struct amd_aperf_mperf cur;
|
||||||
|
struct amd_aperf_mperf prev;
|
||||||
|
|
||||||
|
u64 freq;
|
||||||
bool boost_supported;
|
bool boost_supported;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -211,6 +230,39 @@ static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
|
|||||||
max_perf, fast_switch);
|
max_perf, fast_switch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
|
||||||
|
{
|
||||||
|
u64 aperf, mperf, tsc;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
rdmsrl(MSR_IA32_APERF, aperf);
|
||||||
|
rdmsrl(MSR_IA32_MPERF, mperf);
|
||||||
|
tsc = rdtsc();
|
||||||
|
|
||||||
|
if (cpudata->prev.mperf == mperf || cpudata->prev.tsc == tsc) {
|
||||||
|
local_irq_restore(flags);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
|
||||||
|
cpudata->cur.aperf = aperf;
|
||||||
|
cpudata->cur.mperf = mperf;
|
||||||
|
cpudata->cur.tsc = tsc;
|
||||||
|
cpudata->cur.aperf -= cpudata->prev.aperf;
|
||||||
|
cpudata->cur.mperf -= cpudata->prev.mperf;
|
||||||
|
cpudata->cur.tsc -= cpudata->prev.tsc;
|
||||||
|
|
||||||
|
cpudata->prev.aperf = aperf;
|
||||||
|
cpudata->prev.mperf = mperf;
|
||||||
|
cpudata->prev.tsc = tsc;
|
||||||
|
|
||||||
|
cpudata->freq = div64_u64((cpudata->cur.aperf * cpu_khz), cpudata->cur.mperf);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
|
static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
|
||||||
u32 des_perf, u32 max_perf, bool fast_switch)
|
u32 des_perf, u32 max_perf, bool fast_switch)
|
||||||
{
|
{
|
||||||
@ -226,8 +278,11 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
|
|||||||
value &= ~AMD_CPPC_MAX_PERF(~0L);
|
value &= ~AMD_CPPC_MAX_PERF(~0L);
|
||||||
value |= AMD_CPPC_MAX_PERF(max_perf);
|
value |= AMD_CPPC_MAX_PERF(max_perf);
|
||||||
|
|
||||||
trace_amd_pstate_perf(min_perf, des_perf, max_perf,
|
if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
|
||||||
cpudata->cpu, (value != prev), fast_switch);
|
trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
|
||||||
|
cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
|
||||||
|
cpudata->cpu, (value != prev), fast_switch);
|
||||||
|
}
|
||||||
|
|
||||||
if (value == prev)
|
if (value == prev)
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user