diff options
Diffstat (limited to 'meta-eas/recipes-kernel/linux/linux-renesas/0060-sched-fair-Energy-aware-wake-up-task-placement.patch')
-rw-r--r-- | meta-eas/recipes-kernel/linux/linux-renesas/0060-sched-fair-Energy-aware-wake-up-task-placement.patch | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/meta-eas/recipes-kernel/linux/linux-renesas/0060-sched-fair-Energy-aware-wake-up-task-placement.patch b/meta-eas/recipes-kernel/linux/linux-renesas/0060-sched-fair-Energy-aware-wake-up-task-placement.patch new file mode 100644 index 0000000..d85d6fe --- /dev/null +++ b/meta-eas/recipes-kernel/linux/linux-renesas/0060-sched-fair-Energy-aware-wake-up-task-placement.patch @@ -0,0 +1,104 @@ +From b0ba3376b094bcf111551ee7c5e14183fe15da79 Mon Sep 17 00:00:00 2001 +From: Morten Rasmussen <morten.rasmussen@arm.com> +Date: Wed, 30 Mar 2016 14:29:48 +0100 +Subject: [PATCH 60/92] sched/fair: Energy-aware wake-up task placement + +When the systems is not overutilized, place waking tasks on the most +energy efficient cpu. Previous attempts reduced the search space by +matching task utilization to cpu capacity before consulting the energy +model as this is an expensive operation. The search heuristics didn't +work very well and lacking any better alternatives this patch takes the +brute-force route and tries all potential targets. + +This approach doesn't scale, but it might be sufficient for many +embedded applications while work is continuing on a heuristic that can +minimize the necessary computations. The heuristic must be derrived from +the platform energy model rather than make additional assumptions, such +lower capacity implies better energy efficiency. PeterZ mentioned in the +past that we might be able to derrive some simpler deciding functions +using mathematical (modal?) analysis. + +Signed-off-by: Morten Rasmussen <morten.rasmussen@arm.com> +(cherry picked from commit 8491fd68555c31e596e1888912796184d42138cc) +Signed-off-by: Gaku Inami <gaku.inami.xw@bp.renesas.com> +--- + kernel/sched/fair.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index db732bd..58b468c 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -6148,6 +6148,59 @@ static bool cpu_overutilized(int cpu) + return (capacity_of(cpu) * 1024) < (cpu_util(cpu) * capacity_margin); + } + ++static int select_energy_cpu_brute(struct task_struct *p, int prev_cpu) ++{ ++ int i; ++ int min_diff = 0, energy_cpu = prev_cpu, spare_cpu = prev_cpu; ++ unsigned long max_spare = 0; ++ struct sched_domain *sd; ++ ++ rcu_read_lock(); ++ ++ sd = rcu_dereference(per_cpu(sd_ea, prev_cpu)); ++ ++ if (!sd) ++ return prev_cpu; ++ ++ for_each_cpu_and(i, tsk_cpus_allowed(p), sched_domain_span(sd)) { ++ int diff; ++ unsigned long spare; ++ ++ struct energy_env eenv = { ++ .util_delta = task_util(p), ++ .src_cpu = prev_cpu, ++ .dst_cpu = i, ++ }; ++ ++ spare = capacity_spare_wake(i, p); ++ ++ if (i == prev_cpu) ++ continue; ++ ++ if (spare > max_spare) { ++ max_spare = spare; ++ spare_cpu = i; ++ } ++ ++ if (spare * 1024 < capacity_margin * task_util(p)) ++ continue; ++ ++ diff = energy_diff(&eenv); ++ ++ if (diff < min_diff) { ++ min_diff = diff; ++ energy_cpu = i; ++ } ++ } ++ ++ rcu_read_unlock(); ++ ++ if (energy_cpu == prev_cpu && !cpu_overutilized(prev_cpu)) ++ return prev_cpu; ++ ++ return energy_cpu != prev_cpu ? energy_cpu : spare_cpu; ++} ++ + /* + * select_task_rq_fair: Select target runqueue for the waking task in domains + * that have the 'sd_flag' flag set. In practice, this is SD_BALANCE_WAKE, +@@ -6175,6 +6228,9 @@ static bool cpu_overutilized(int cpu) + && cpumask_test_cpu(cpu, tsk_cpus_allowed(p)); + } + ++ if (energy_aware() && !(cpu_rq(prev_cpu)->rd->overutilized)) ++ return select_energy_cpu_brute(p, prev_cpu); ++ + rcu_read_lock(); + for_each_domain(cpu, tmp) { + if (!(tmp->flags & SD_LOAD_BALANCE)) +-- +1.9.1 + |