From bba1b629679ae8933d174a392e3792883436bdae Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 2 Nov 2022 17:36:33 +0800 Subject: [PATCH] sched/fair: optimize find_energy_efficient_cpu() for EAS scheduler When EAS can not find a best_energy_cpu, consider a idlest cpu as a backup if it is a little power increased(<3.1%). Test NenaMark2.apk on RK3588 EVB1 board: without this patch: min-fps=57, avg-fps=59.4 with this patch: min-fps=60, avg-fps=60 Change-Id: Ibc99282c21fa32cbed1d4f5dcc66c76a6b120b70 Signed-off-by: Liang Chen --- kernel/sched/fair.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5784ddbcee8f..193adbff97f7 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6681,6 +6681,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd) static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sync) { unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX; + unsigned long best_delta2 = ULONG_MAX; struct root_domain *rd = cpu_rq(smp_processor_id())->rd; int max_spare_cap_cpu_ls = prev_cpu, best_idle_cpu = -1; unsigned long max_spare_cap_ls = 0, target_cap; @@ -6777,8 +6778,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy max_spare_cap_cpu = cpu; } - if (!latency_sensitive) - continue; + if (!IS_ENABLED(CONFIG_ROCKCHIP_PERFORMANCE)) { + if (!latency_sensitive) + continue; + } if (idle_cpu(cpu)) { cpu_cap = capacity_orig_of(cpu); @@ -6795,9 +6798,19 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy min_exit_lat = idle->exit_latency; target_cap = cpu_cap; best_idle_cpu = cpu; + if (IS_ENABLED(CONFIG_ROCKCHIP_PERFORMANCE)) { + best_delta2 = compute_energy(p, cpu, pd); + best_delta2 -= base_energy_pd; + } } else if (spare_cap > max_spare_cap_ls) { max_spare_cap_ls = spare_cap; max_spare_cap_cpu_ls = cpu; + if (IS_ENABLED(CONFIG_ROCKCHIP_PERFORMANCE)) { + if (best_idle_cpu == -1) { + best_delta2 = compute_energy(p, cpu, pd); + best_delta2 -= base_energy_pd; + } + } } } @@ -6825,26 +6838,33 @@ unlock: if (prev_delta == ULONG_MAX) return best_energy_cpu; - /* - * when select ROCKCHIP_PERFORMANCE_LOW: - * Pick best_energy_cpu immediately if prev_cpu is big cpu and - * best_energy_cpu is little cpu, so that tasks can migrate from - * big cpu to little cpu easier to save power. - */ + if ((prev_delta - best_delta) > ((prev_delta + base_energy) >> 4)) + return best_energy_cpu; + if (IS_ENABLED(CONFIG_ROCKCHIP_PERFORMANCE)) { struct cpumask *cpul_mask = rockchip_perf_get_cpul_mask(); struct cpumask *cpub_mask = rockchip_perf_get_cpub_mask(); int level = rockchip_perf_get_level(); + /* + * when select ROCKCHIP_PERFORMANCE_LOW: + * Pick best_energy_cpu if prev_cpu is big cpu and best_energy_cpu + * is little cpu, so that tasks can migrate from big cpu to little + * cpu easier to save power. + */ if ((level == ROCKCHIP_PERFORMANCE_LOW) && cpul_mask && cpub_mask && cpumask_test_cpu(prev_cpu, cpub_mask) && cpumask_test_cpu(best_energy_cpu, cpul_mask)) { return best_energy_cpu; } - } - if ((prev_delta - best_delta) > ((prev_delta + base_energy) >> 4)) - return best_energy_cpu; + /* + * Pick the idlest cpu if it is a little power increased(<3.1%). + */ + if ((best_delta2 <= prev_delta) || + ((best_delta2 - prev_delta) < ((prev_delta + base_energy) >> 5))) + return best_idle_cpu >= 0 ? best_idle_cpu : max_spare_cap_cpu_ls; + } return prev_cpu;