Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b69880f9 authored by Dirk Brandewie's avatar Dirk Brandewie Committed by Rafael J. Wysocki
Browse files

intel_pstate: Add trace point to report internal state.



Add perf trace event "power:pstate_sample" to report driver state to
aid in diagnosing issues reported against intel_pstate.

Signed-off-by: default avatarDirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 652ed95d
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ static inline int32_t div_fp(int32_t x, int32_t y)
	return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
}

static u64 energy_divisor;

struct sample {
	int32_t core_pct_busy;
	u64 aperf;
@@ -559,6 +561,7 @@ static inline void intel_pstate_sample(struct cpudata *cpu)

	rdmsrl(MSR_IA32_APERF, aperf);
	rdmsrl(MSR_IA32_MPERF, mperf);

	cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
	cpu->samples[cpu->sample_ptr].aperf = aperf;
	cpu->samples[cpu->sample_ptr].mperf = mperf;
@@ -603,6 +606,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
	ctl = pid_calc(pid, busy_scaled);

	steps = abs(ctl);

	if (ctl < 0)
		intel_pstate_pstate_increase(cpu, steps);
	else
@@ -612,9 +616,24 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
static void intel_pstate_timer_func(unsigned long __data)
{
	struct cpudata *cpu = (struct cpudata *) __data;
	struct sample *sample;
	u64 energy;

	intel_pstate_sample(cpu);

	sample = &cpu->samples[cpu->sample_ptr];
	rdmsrl(MSR_PKG_ENERGY_STATUS, energy);

	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,
			div64_u64(energy, energy_divisor),
			sample->freq);

	intel_pstate_set_sample_time(cpu);
}

@@ -894,6 +913,7 @@ static int __init intel_pstate_init(void)
	int cpu, rc = 0;
	const struct x86_cpu_id *id;
	struct cpu_defaults *cpu_info;
	u64 units;

	if (no_load)
		return -ENODEV;
@@ -927,8 +947,12 @@ static int __init intel_pstate_init(void)
	if (rc)
		goto out;

	rdmsrl(MSR_RAPL_POWER_UNIT, units);
	energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */

	intel_pstate_debug_expose_params();
	intel_pstate_sysfs_expose_params();

	return rc;
out:
	get_online_cpus();
+53 −0
Original line number Diff line number Diff line
@@ -35,6 +35,59 @@ DEFINE_EVENT(cpu, cpu_idle,
	TP_ARGS(state, cpu_id)
);

TRACE_EVENT(pstate_sample,

	TP_PROTO(u32 core_busy,
		u32 scaled_busy,
		u32 state,
		u64 mperf,
		u64 aperf,
		u32 energy,
		u32 freq
		),

	TP_ARGS(core_busy,
		scaled_busy,
		state,
		mperf,
		aperf,
		energy,
		freq
		),

	TP_STRUCT__entry(
		__field(u32, core_busy)
		__field(u32, scaled_busy)
		__field(u32, state)
		__field(u64, mperf)
		__field(u64, aperf)
		__field(u32, energy)
		__field(u32, freq)

	),

	TP_fast_assign(
		__entry->core_busy = core_busy;
		__entry->scaled_busy = scaled_busy;
		__entry->state = state;
		__entry->mperf = mperf;
		__entry->aperf = aperf;
		__entry->energy = energy;
		__entry->freq = freq;
		),

	TP_printk("core_busy=%lu scaled=%lu state=%lu mperf=%llu aperf=%llu energy=%lu freq=%lu ",
		(unsigned long)__entry->core_busy,
		(unsigned long)__entry->scaled_busy,
		(unsigned long)__entry->state,
		(unsigned long long)__entry->mperf,
		(unsigned long long)__entry->aperf,
		(unsigned long)__entry->energy,
		(unsigned long)__entry->freq
		)

);

/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */
#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING
#define _PWR_EVENT_AVOID_DOUBLE_DEFINING