sched/walt: Update CPU capacity based on cpufreq constraints

The cpufreq constraints must be reflected in the capacity of
a CPU. Add a hook for cpufreq limits to implement this.

Change-Id: I779cb16bd66ea99c16e55faea7383e034d22440a
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
This commit is contained in:
Pavankumar Kondeti 2021-03-08 11:13:53 +05:30 committed by Rishabh Bhatnagar
parent 54adb8abcc
commit a1ccf98f6f
2 changed files with 29 additions and 19 deletions

View File

@ -16,6 +16,7 @@
#include <trace/hooks/sched.h>
#include <trace/hooks/cpufreq.h>
#include <trace/events/power.h>
#include "walt.h"
#include "trace.h"
@ -732,13 +733,6 @@ static void update_rq_load_subtractions(int index, struct rq *rq,
wrq->load_subs[index].new_subs += sub_load;
}
static inline struct walt_sched_cluster *cpu_cluster(int cpu)
{
struct walt_rq *wrq = (struct walt_rq *) cpu_rq(cpu)->android_vendor_data1;
return wrq->cluster;
}
static void update_cluster_load_subtractions(struct task_struct *p,
int cpu, u64 ws, bool new_task)
{
@ -2306,6 +2300,7 @@ static struct walt_sched_cluster *alloc_new_cluster(const struct cpumask *cpus)
INIT_LIST_HEAD(&cluster->list);
cluster->cur_freq = 1;
cluster->max_freq = 1;
cluster->max_possible_freq = 1;
raw_spin_lock_init(&cluster->load_lock);
@ -2511,6 +2506,7 @@ static void walt_update_cluster_topology(void)
if (policy) {
cluster->max_possible_freq = policy->cpuinfo.max_freq;
cluster->max_freq = policy->max;
for_each_cpu(i, &cluster->cpus) {
wrq = (struct walt_rq *) cpu_rq(i)->android_vendor_data1;
cpumask_copy(&wrq->freq_domain_cpumask,
@ -3630,6 +3626,14 @@ static void android_rvh_wake_up_new_task(void *unused, struct task_struct *new)
add_new_task_to_grp(new);
}
static void walt_cpu_frequency_limits(void *unused, struct cpufreq_policy *policy)
{
if (unlikely(walt_disabled))
return;
cpu_cluster(policy->cpu)->max_freq = policy->max;
}
/*
* The intention of this hook is to update cpu_capacity_orig as well as
* (*capacity), otherwise we will end up capacity_of() > capacity_orig_of().
@ -3639,6 +3643,7 @@ static void android_rvh_update_cpu_capacity(void *unused, int cpu, unsigned long
unsigned long max_capacity = arch_scale_cpu_capacity(cpu);
unsigned long thermal_pressure = arch_scale_thermal_pressure(cpu);
unsigned long thermal_cap;
struct walt_sched_cluster *cluster;
if (unlikely(walt_disabled))
return;
@ -3651,18 +3656,13 @@ static void android_rvh_update_cpu_capacity(void *unused, int cpu, unsigned long
thermal_cap = max_capacity - thermal_pressure;
/*
* TODO:
* Thermal is taken care now. but what about limits via
* cpufreq max. we don't have arch_scale_max_freq_capacity()
* in 5.10 now.
*
* Two options:
* #1 either port that max_frq_cap patch to AOSP
* #2 register for cpufreq policy updates..
*/
cpu_rq(cpu)->cpu_capacity_orig = min(cpu_rq(cpu)->cpu_capacity_orig,
thermal_cap);
cluster = cpu_cluster(cpu);
/* reduce the max_capacity under cpufreq constraints */
if (cluster->max_freq != cluster->max_possible_freq)
max_capacity = mult_frac(max_capacity, cluster->max_freq,
cluster->max_possible_freq);
cpu_rq(cpu)->cpu_capacity_orig = min(max_capacity, thermal_cap);
*capacity = cpu_rq(cpu)->cpu_capacity_orig;
}
@ -3983,6 +3983,7 @@ static void register_walt_hooks(void)
register_trace_android_rvh_ttwu_cond(android_rvh_ttwu_cond, NULL);
register_trace_android_rvh_sched_exec(android_rvh_sched_exec, NULL);
register_trace_android_rvh_build_perf_domains(android_rvh_build_perf_domains, NULL);
register_trace_cpu_frequency_limits(walt_cpu_frequency_limits, NULL);
}
atomic64_t walt_irq_work_lastq_ws;

View File

@ -127,9 +127,11 @@ struct walt_sched_cluster {
int id;
/*
* max_possible_freq = maximum supported by hardware
* max_freq = max freq as per cpufreq limits
*/
unsigned int cur_freq;
unsigned int max_possible_freq;
unsigned int max_freq;
u64 aggr_grp_load;
};
@ -226,6 +228,13 @@ extern struct list_head cluster_head;
#define for_each_sched_cluster(cluster) \
list_for_each_entry_rcu(cluster, &cluster_head, list)
static inline struct walt_sched_cluster *cpu_cluster(int cpu)
{
struct walt_rq *wrq = (struct walt_rq *) cpu_rq(cpu)->android_vendor_data1;
return wrq->cluster;
}
static inline u32 cpu_cycles_to_freq(u64 cycles, u64 period)
{
return div64_u64(cycles, period);