Commit 904d9dcd authored by Zeng Heng's avatar Zeng Heng
Browse files

cpufreq: CPPC: keep target core awake when reading its cpufreq rate

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I73EPL



--------------------------------

As ARM AMU's document says, all counters are subject to any changes
in clock frequency, including clock stopping caused by the WFI and WFE
instructions.

Therefore, using smp_call_on_cpu() to trigger target CPU to
read self's AMU counters, which ensures the counters are working
properly during calculation.

Signed-off-by: default avatarZeng Heng <zengheng4@huawei.com>
parent 09f90a26
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1588,6 +1588,7 @@ bool cpu_has_amu_feat(int cpu)
{
	return cpumask_test_cpu(cpu, &amu_cpus);
}
EXPORT_SYMBOL(cpu_has_amu_feat);

int get_cpu_with_amu_feat(void)
{
+20 −6
Original line number Diff line number Diff line
@@ -350,23 +350,37 @@ static int cppc_get_rate_from_fbctrs(struct cppc_cpudata *cpu,
	return cppc_cpufreq_perf_to_khz(cpu, delivered_perf);
}

static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
static int cppc_get_perf_ctrs_sample(void *val)
{
	struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0};
	struct cppc_cpudata *cpu = all_cpu_data[cpunum];
	int cpunum = smp_processor_id();
	struct cppc_perf_fb_ctrs *fb_ctrs = val;
	int ret;

	ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t0);
	ret = cppc_get_perf_ctrs(cpunum, fb_ctrs);
	if (ret)
		return ret;

	udelay(2); /* 2usec delay between sampling */

	ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t1);
	return cppc_get_perf_ctrs(cpunum, fb_ctrs + 1);
}

static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
{
	struct cppc_perf_fb_ctrs fb_ctrs[2] = {0};
	struct cppc_cpudata *cpu = all_cpu_data[cpunum];
	int ret;

	if (cpu_has_amu_feat(cpunum))
		ret = smp_call_on_cpu(cpunum, cppc_get_perf_ctrs_sample,
				      fb_ctrs, false);
	else
		ret = cppc_get_perf_ctrs_sample(fb_ctrs);

	if (ret)
		return ret;

	return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
	return cppc_get_rate_from_fbctrs(cpu, fb_ctrs[0], fb_ctrs[1]);
}

static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)