sched/walt: print per cluster energy

Per cluster energy contribution is essential to debug energy evaluation.
Add code to print it.

Change-Id: Ifbe80d125b09facd358933ab3537260fea0584ac
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2021-06-14 14:15:49 -07:00 committed by Rishabh Bhatnagar
parent 32eccdc2bf
commit 8d553f6471
3 changed files with 89 additions and 18 deletions

View File

@ -881,9 +881,11 @@ TRACE_EVENT(sched_cpu_util,
__field(int, reserved)
__field(int, high_irq_load)
__field(unsigned int, nr_rtg_high_prio_tasks)
__field(u64, prs_gprs)
),
TP_fast_assign(
struct walt_rq *wrq = (struct walt_rq *) cpu_rq(cpu)->android_vendor_data1;
__entry->cpu = cpu;
__entry->nr_running = cpu_rq(cpu)->nr_running;
__entry->cpu_util = cpu_util(cpu);
@ -898,15 +900,16 @@ TRACE_EVENT(sched_cpu_util,
__entry->reserved = is_reserved(cpu);
__entry->high_irq_load = sched_cpu_high_irqload(cpu);
__entry->nr_rtg_high_prio_tasks = walt_nr_rtg_high_prio(cpu);
__entry->prs_gprs = wrq->prev_runnable_sum + wrq->grp_time.prev_runnable_sum;
),
TP_printk("cpu=%d nr_running=%d cpu_util=%ld cpu_util_cum=%ld capacity_curr=%u capacity=%u capacity_orig=%u idle_exit_latency=%u irqload=%llu online=%u, inactive=%u, reserved=%u, high_irq_load=%u nr_rtg_hp=%u",
TP_printk("cpu=%d nr_running=%d cpu_util=%ld cpu_util_cum=%ld capacity_curr=%u capacity=%u capacity_orig=%u idle_exit_latency=%u irqload=%llu online=%u, inactive=%u, reserved=%u, high_irq_load=%u nr_rtg_hp=%u prs_gprs=%llu",
__entry->cpu, __entry->nr_running, __entry->cpu_util,
__entry->cpu_util_cum, __entry->capacity_curr,
__entry->capacity, __entry->capacity_orig,
__entry->idle_exit_latency, __entry->irqload, __entry->online,
__entry->inactive, __entry->reserved, __entry->high_irq_load,
__entry->nr_rtg_high_prio_tasks)
__entry->nr_rtg_high_prio_tasks, __entry->prs_gprs)
);
TRACE_EVENT(sched_compute_energy,
@ -915,10 +918,11 @@ TRACE_EVENT(sched_compute_energy,
unsigned long eval_energy,
unsigned long prev_energy,
unsigned long best_energy,
unsigned long best_energy_cpu),
unsigned long best_energy_cpu,
struct compute_energy_output *o),
TP_ARGS(p, eval_cpu, eval_energy, prev_energy, best_energy,
best_energy_cpu),
best_energy_cpu, o),
TP_STRUCT__entry(
__field(int, pid)
@ -930,6 +934,18 @@ TRACE_EVENT(sched_compute_energy,
__field(unsigned long, eval_energy)
__field(int, best_energy_cpu)
__field(unsigned long, best_energy)
__field(unsigned int, cluster_first_cpu0)
__field(unsigned int, cluster_first_cpu1)
__field(unsigned int, cluster_first_cpu2)
__field(unsigned long, s0)
__field(unsigned long, s1)
__field(unsigned long, s2)
__field(unsigned long, m0)
__field(unsigned long, m1)
__field(unsigned long, m2)
__field(u16, c0)
__field(u16, c1)
__field(u16, c2)
),
TP_fast_assign(
@ -942,12 +958,27 @@ TRACE_EVENT(sched_compute_energy,
__entry->eval_energy = eval_energy;
__entry->best_energy_cpu = best_energy_cpu;
__entry->best_energy = best_energy;
__entry->cluster_first_cpu0 = o->cluster_first_cpu[0];
__entry->cluster_first_cpu1 = o->cluster_first_cpu[1];
__entry->cluster_first_cpu2 = o->cluster_first_cpu[2];
__entry->s0 = o->sum_util[0];
__entry->s1 = o->sum_util[1];
__entry->s2 = o->sum_util[2];
__entry->m0 = o->max_util[0];
__entry->m1 = o->max_util[1];
__entry->m2 = o->max_util[2];
__entry->c0 = o->cost[0];
__entry->c1 = o->cost[1];
__entry->c2 = o->cost[2];
),
TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d prev_energy=%lu eval_cpu=%d eval_energy=%lu best_energy_cpu=%d best_energy=%lu",
TP_printk("pid=%d comm=%s util=%lu prev_cpu=%d prev_energy=%lu eval_cpu=%d eval_energy=%lu best_energy_cpu=%d best_energy=%lu, fcpu s m c = %u %u %u %u, %u %u %u %u, %u %u %u %u",
__entry->pid, __entry->comm, __entry->util, __entry->prev_cpu,
__entry->prev_energy, __entry->eval_cpu, __entry->eval_energy,
__entry->best_energy_cpu, __entry->best_energy)
__entry->best_energy_cpu, __entry->best_energy,
__entry->cluster_first_cpu0, __entry->s0, __entry->m0, __entry->c0,
__entry->cluster_first_cpu1, __entry->s1, __entry->m1, __entry->c1,
__entry->cluster_first_cpu2, __entry->s2, __entry->m2, __entry->c2)
)
TRACE_EVENT(sched_task_util,

View File

@ -894,4 +894,10 @@ extern __read_mostly unsigned int walt_scale_demand_divisor;
#define scale_demand(d) ((d)/walt_scale_demand_divisor)
void create_util_to_cost(void);
struct compute_energy_output {
unsigned long sum_util[MAX_CLUSTERS];
unsigned long max_util[MAX_CLUSTERS];
u16 cost[MAX_CLUSTERS];
unsigned int cluster_first_cpu[MAX_CLUSTERS];
};
#endif /* _WALT_H */

View File

@ -497,7 +497,8 @@ cpu_util_next_walt_prs(int cpu, struct task_struct *p, int dst_cpu, bool prev_ds
* a capacity state satisfying the max utilization of the domain.
*/
static inline unsigned long walt_em_cpu_energy(struct em_perf_domain *pd,
unsigned long max_util, unsigned long sum_util)
unsigned long max_util, unsigned long sum_util,
struct compute_energy_output *output, unsigned int x)
{
unsigned long scale_cpu;
int cpu;
@ -563,6 +564,12 @@ static inline unsigned long walt_em_cpu_energy(struct em_perf_domain *pd,
max_util = 1023;
wrq = (struct walt_rq *) cpu_rq(cpu)->android_vendor_data1;
if (output) {
output->cost[x] = wrq->cluster->util_to_cost[max_util];
output->max_util[x] = max_util;
output->sum_util[x] = sum_util;
}
return wrq->cluster->util_to_cost[max_util] * sum_util / scale_cpu;
}
@ -574,7 +581,8 @@ static inline unsigned long walt_em_cpu_energy(struct em_perf_domain *pd,
* task.
*/
static long
walt_pd_compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd, u64 *prs)
walt_pd_compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd, u64 *prs,
struct compute_energy_output *output, unsigned int x)
{
struct cpumask *pd_mask = perf_domain_span(pd);
unsigned long max_util = 0, sum_util = 0;
@ -602,21 +610,28 @@ walt_pd_compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *p
max_util = scale_demand(max_util);
sum_util = scale_demand(sum_util);
return walt_em_cpu_energy(pd->em_pd, max_util, sum_util);
if (output)
output->cluster_first_cpu[x] = cpumask_first(pd_mask);
return walt_em_cpu_energy(pd->em_pd, max_util, sum_util, output, x);
}
static inline long
walt_compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd,
cpumask_t *candidates, u64 *prs)
cpumask_t *candidates, u64 *prs, struct compute_energy_output *output)
{
long energy = 0;
unsigned int x = 0;
for (; pd; pd = pd->next) {
struct cpumask *pd_mask = perf_domain_span(pd);
if (cpumask_intersects(candidates, pd_mask)
|| cpumask_test_cpu(task_cpu(p), pd_mask))
energy += walt_pd_compute_energy(p, dst_cpu, pd, prs);
|| cpumask_test_cpu(task_cpu(p), pd_mask)) {
energy += walt_pd_compute_energy(p, dst_cpu, pd, prs, output, x);
x++;
}
}
return energy;
@ -673,6 +688,7 @@ int walt_find_energy_efficient_cpu(struct task_struct *p, int prev_cpu,
int start_cpu, order_index, end_index;
int max_cap_cpu = -1;
bool energy_eval_needed = true;
struct compute_energy_output output;
if (walt_is_many_wakeup(sibling_count_hint) && prev_cpu != cpu &&
cpumask_test_cpu(prev_cpu, &p->cpus_mask))
@ -750,20 +766,38 @@ int walt_find_energy_efficient_cpu(struct task_struct *p, int prev_cpu,
if (p->state == TASK_WAKING)
delta = task_util(p);
if (cpumask_test_cpu(prev_cpu, &p->cpus_mask) && !__cpu_overutilized(prev_cpu, delta))
prev_energy = best_energy =
walt_compute_energy(p, prev_cpu, pd, candidates, fbt_env.prs);
else
if (cpumask_test_cpu(prev_cpu, &p->cpus_mask) && !__cpu_overutilized(prev_cpu, delta)) {
if (trace_sched_compute_energy_enabled()) {
memset(&output, 0, sizeof(output));
prev_energy = walt_compute_energy(p, prev_cpu, pd, candidates, fbt_env.prs,
&output);
} else {
prev_energy = walt_compute_energy(p, prev_cpu, pd, candidates, fbt_env.prs,
NULL);
}
best_energy = prev_energy;
trace_sched_compute_energy(p, prev_cpu, prev_energy, 0, 0, 0, &output);
} else {
prev_energy = best_energy = ULONG_MAX;
}
/* Select the best candidate energy-wise. */
for_each_cpu(cpu, candidates) {
if (cpu == prev_cpu)
continue;
cur_energy = walt_compute_energy(p, cpu, pd, candidates, fbt_env.prs);
if (trace_sched_compute_energy_enabled()) {
memset(&output, 0, sizeof(output));
cur_energy = walt_compute_energy(p, cpu, pd, candidates, fbt_env.prs,
&output);
} else {
cur_energy = walt_compute_energy(p, cpu, pd, candidates, fbt_env.prs,
NULL);
}
trace_sched_compute_energy(p, cpu, cur_energy,
prev_energy, best_energy, best_energy_cpu);
prev_energy, best_energy, best_energy_cpu, &output);
if (cur_energy < best_energy) {
best_energy = cur_energy;