Query the current frequency of the core during the scheduler tick. The scheduler subsystem maintains its own copies of the aperf/mperf structure because it will query the frequency more frequently than what the cpufreq subsystem does. This can lead to inaccurate measurements, but it is not problematic here. Co-developed-by: Damien Carver <carverdamien@xxxxxxxxx> Signed-off-by: Damien Carver <carverdamien@xxxxxxxxx> Signed-off-by: Redha Gouicem <redha.gouicem@xxxxxxxxx> --- kernel/sched/core.c | 11 +++++++++++ kernel/sched/sched.h | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index c36dc1ae58be..d6d27a6fc23c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3976,6 +3976,15 @@ unsigned long long task_sched_runtime(struct task_struct *p) return ns; } +struct freq_sample { + unsigned int khz; + ktime_t time; + u64 aperf; + u64 mperf; +}; + +DEFINE_PER_CPU(struct freq_sample, freq_sample); + /* * This function gets called by the timer code, with HZ frequency. * We call it with interrupts disabled. @@ -3996,6 +4005,8 @@ void scheduler_tick(void) update_rq_clock(rq); thermal_pressure = arch_scale_thermal_pressure(cpu_of(rq)); update_thermal_load_avg(rq_clock_thermal(rq), rq, thermal_pressure); + rq->freq = arch_freq_get_on_cpu_from_sample(cpu, + this_cpu_ptr(&freq_sample)); curr->sched_class->task_tick(rq, curr, 0); calc_global_load_tick(rq); psi_task_tick(rq); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 28709f6b0975..7d794ab756d2 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1048,6 +1048,10 @@ struct rq { /* Must be inspected within a rcu lock section */ struct cpuidle_state *idle_state; #endif + + /* Frequency measured at the last tick */ + unsigned int freq; + }; #ifdef CONFIG_FAIR_GROUP_SCHED -- 2.28.0