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

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

intel_pstate: Take core C0 time into account for core busy calculation

Take non-idle time into account when calculating core busy time.
This ensures that intel_pstate will notice a decrease in load.

References: https://bugzilla.kernel.org/show_bug.cgi?id=66581


Cc: 3.10+ <stable@vger.kernel.org> # 3.10+
Signed-off-by: default avatarDirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 38dbfb59
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ struct sample {
	int32_t core_pct_busy;
	u64 aperf;
	u64 mperf;
	unsigned long long tsc;
	int freq;
};

@@ -96,6 +97,7 @@ struct cpudata {

	u64	prev_aperf;
	u64	prev_mperf;
	unsigned long long prev_tsc;
	int	sample_ptr;
	struct sample samples[SAMPLE_COUNT];
};
@@ -548,30 +550,41 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
					struct sample *sample)
{
	u64 core_pct;
	core_pct = div64_u64(int_tofp(sample->aperf * 100),
			     sample->mperf);
	sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000);
	u64 c0_pct;

	sample->core_pct_busy = core_pct;
	core_pct = div64_u64(sample->aperf * 100, sample->mperf);

	c0_pct = div64_u64(sample->mperf * 100, sample->tsc);
	sample->freq = fp_toint(
		mul_fp(int_tofp(cpu->pstate.max_pstate),
			int_tofp(core_pct * 1000)));

	sample->core_pct_busy = mul_fp(int_tofp(core_pct),
				div_fp(int_tofp(c0_pct + 1), int_tofp(100)));
}

static inline void intel_pstate_sample(struct cpudata *cpu)
{
	u64 aperf, mperf;
	unsigned long long tsc;

	rdmsrl(MSR_IA32_APERF, aperf);
	rdmsrl(MSR_IA32_MPERF, mperf);
	tsc = native_read_tsc();

	cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
	cpu->samples[cpu->sample_ptr].aperf = aperf;
	cpu->samples[cpu->sample_ptr].mperf = mperf;
	cpu->samples[cpu->sample_ptr].tsc = tsc;
	cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
	cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
	cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc;

	intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);

	cpu->prev_aperf = aperf;
	cpu->prev_mperf = mperf;
	cpu->prev_tsc = tsc;
}

static inline void intel_pstate_set_sample_time(struct cpudata *cpu)