Commit 4055fad3 authored by Doug Smythies's avatar Doug Smythies Committed by Rafael J. Wysocki

intel_pstate: Add tsc collection and keep previous target pstate

The intel_pstate driver is difficult to debug and investigate without tsc.

Also, it is likely use of tsc, and some version of C0 percentage,
will be re-introdcued in futute.

There have also been occasions where it is desirebale to know, and
confirm, the previous target pstate.

This patch brings back tsc, adds previous target pstate,
and adds both to the trace data collection.
Signed-off-by: default avatarDoug Smythies <dsmythies@telus.net>
Acked-by: default avatarKristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent b904f5cc
...@@ -68,6 +68,7 @@ struct sample { ...@@ -68,6 +68,7 @@ struct sample {
int32_t core_pct_busy; int32_t core_pct_busy;
u64 aperf; u64 aperf;
u64 mperf; u64 mperf;
u64 tsc;
int freq; int freq;
ktime_t time; ktime_t time;
}; };
...@@ -109,6 +110,7 @@ struct cpudata { ...@@ -109,6 +110,7 @@ struct cpudata {
ktime_t last_sample_time; ktime_t last_sample_time;
u64 prev_aperf; u64 prev_aperf;
u64 prev_mperf; u64 prev_mperf;
u64 prev_tsc;
struct sample sample; struct sample sample;
}; };
...@@ -756,23 +758,28 @@ static inline void intel_pstate_sample(struct cpudata *cpu) ...@@ -756,23 +758,28 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
{ {
u64 aperf, mperf; u64 aperf, mperf;
unsigned long flags; unsigned long flags;
u64 tsc;
local_irq_save(flags); local_irq_save(flags);
rdmsrl(MSR_IA32_APERF, aperf); rdmsrl(MSR_IA32_APERF, aperf);
rdmsrl(MSR_IA32_MPERF, mperf); rdmsrl(MSR_IA32_MPERF, mperf);
tsc = native_read_tsc();
local_irq_restore(flags); local_irq_restore(flags);
cpu->last_sample_time = cpu->sample.time; cpu->last_sample_time = cpu->sample.time;
cpu->sample.time = ktime_get(); cpu->sample.time = ktime_get();
cpu->sample.aperf = aperf; cpu->sample.aperf = aperf;
cpu->sample.mperf = mperf; cpu->sample.mperf = mperf;
cpu->sample.tsc = tsc;
cpu->sample.aperf -= cpu->prev_aperf; cpu->sample.aperf -= cpu->prev_aperf;
cpu->sample.mperf -= cpu->prev_mperf; cpu->sample.mperf -= cpu->prev_mperf;
cpu->sample.tsc -= cpu->prev_tsc;
intel_pstate_calc_busy(cpu); intel_pstate_calc_busy(cpu);
cpu->prev_aperf = aperf; cpu->prev_aperf = aperf;
cpu->prev_mperf = mperf; cpu->prev_mperf = mperf;
cpu->prev_tsc = tsc;
} }
static inline void intel_hwp_set_sample_time(struct cpudata *cpu) static inline void intel_hwp_set_sample_time(struct cpudata *cpu)
...@@ -837,6 +844,10 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) ...@@ -837,6 +844,10 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
int32_t busy_scaled; int32_t busy_scaled;
struct _pid *pid; struct _pid *pid;
signed int ctl; signed int ctl;
int from;
struct sample *sample;
from = cpu->pstate.current_pstate;
pid = &cpu->pid; pid = &cpu->pid;
busy_scaled = intel_pstate_get_scaled_busy(cpu); busy_scaled = intel_pstate_get_scaled_busy(cpu);
...@@ -845,6 +856,16 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) ...@@ -845,6 +856,16 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
/* Negative values of ctl increase the pstate and vice versa */ /* Negative values of ctl increase the pstate and vice versa */
intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl); intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl);
sample = &cpu->sample;
trace_pstate_sample(fp_toint(sample->core_pct_busy),
fp_toint(busy_scaled),
from,
cpu->pstate.current_pstate,
sample->mperf,
sample->aperf,
sample->tsc,
sample->freq);
} }
static void intel_hwp_timer_func(unsigned long __data) static void intel_hwp_timer_func(unsigned long __data)
...@@ -858,21 +879,11 @@ static void intel_hwp_timer_func(unsigned long __data) ...@@ -858,21 +879,11 @@ static void intel_hwp_timer_func(unsigned long __data)
static void intel_pstate_timer_func(unsigned long __data) static void intel_pstate_timer_func(unsigned long __data)
{ {
struct cpudata *cpu = (struct cpudata *) __data; struct cpudata *cpu = (struct cpudata *) __data;
struct sample *sample;
intel_pstate_sample(cpu); intel_pstate_sample(cpu);
sample = &cpu->sample;
intel_pstate_adjust_busy_pstate(cpu); intel_pstate_adjust_busy_pstate(cpu);
trace_pstate_sample(fp_toint(sample->core_pct_busy),
fp_toint(intel_pstate_get_scaled_busy(cpu)),
cpu->pstate.current_pstate,
sample->mperf,
sample->aperf,
sample->freq);
intel_pstate_set_sample_time(cpu); intel_pstate_set_sample_time(cpu);
} }
......
...@@ -42,45 +42,54 @@ TRACE_EVENT(pstate_sample, ...@@ -42,45 +42,54 @@ TRACE_EVENT(pstate_sample,
TP_PROTO(u32 core_busy, TP_PROTO(u32 core_busy,
u32 scaled_busy, u32 scaled_busy,
u32 state, u32 from,
u32 to,
u64 mperf, u64 mperf,
u64 aperf, u64 aperf,
u64 tsc,
u32 freq u32 freq
), ),
TP_ARGS(core_busy, TP_ARGS(core_busy,
scaled_busy, scaled_busy,
state, from,
to,
mperf, mperf,
aperf, aperf,
tsc,
freq freq
), ),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u32, core_busy) __field(u32, core_busy)
__field(u32, scaled_busy) __field(u32, scaled_busy)
__field(u32, state) __field(u32, from)
__field(u32, to)
__field(u64, mperf) __field(u64, mperf)
__field(u64, aperf) __field(u64, aperf)
__field(u64, tsc)
__field(u32, freq) __field(u32, freq)
),
),
TP_fast_assign( TP_fast_assign(
__entry->core_busy = core_busy; __entry->core_busy = core_busy;
__entry->scaled_busy = scaled_busy; __entry->scaled_busy = scaled_busy;
__entry->state = state; __entry->from = from;
__entry->to = to;
__entry->mperf = mperf; __entry->mperf = mperf;
__entry->aperf = aperf; __entry->aperf = aperf;
__entry->tsc = tsc;
__entry->freq = freq; __entry->freq = freq;
), ),
TP_printk("core_busy=%lu scaled=%lu state=%lu mperf=%llu aperf=%llu freq=%lu ", TP_printk("core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu ",
(unsigned long)__entry->core_busy, (unsigned long)__entry->core_busy,
(unsigned long)__entry->scaled_busy, (unsigned long)__entry->scaled_busy,
(unsigned long)__entry->state, (unsigned long)__entry->from,
(unsigned long)__entry->to,
(unsigned long long)__entry->mperf, (unsigned long long)__entry->mperf,
(unsigned long long)__entry->aperf, (unsigned long long)__entry->aperf,
(unsigned long long)__entry->tsc,
(unsigned long)__entry->freq (unsigned long)__entry->freq
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment