[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1396009796-31598-4-git-send-email-daniel.lezcano@linaro.org>
Date: Fri, 28 Mar 2014 13:29:56 +0100
From: Daniel Lezcano <daniel.lezcano@...aro.org>
To: linux-kernel@...r.kernel.org, mingo@...e.hu, peterz@...radead.org
Cc: rjw@...ysocki.net, nicolas.pitre@...aro.org,
linux-pm@...r.kernel.org, alex.shi@...aro.org,
vincent.guittot@...aro.org, morten.rasmussen@....com
Subject: [RFC PATCHC 3/3] sched/fair: use the idle state info to choose the idlest cpu
As we know in which idle state the cpu is, we can investigate the following:
1. when did the cpu entered the idle state ? the longer the cpu is idle, the
deeper it is idle
2. what exit latency is ? the greater the exit latency is, the deeper it is
With both information, when all cpus are idle, we can choose the idlest cpu.
When one cpu is not idle, the old check against weighted load applies.
Signed-off-by: Daniel Lezcano <daniel.lezcano@...aro.org>
---
kernel/sched/fair.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 16042b5..068e503 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -23,6 +23,7 @@
#include <linux/latencytop.h>
#include <linux/sched.h>
#include <linux/cpumask.h>
+#include <linux/cpuidle.h>
#include <linux/slab.h>
#include <linux/profile.h>
#include <linux/interrupt.h>
@@ -4336,20 +4337,53 @@ static int
find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
{
unsigned long load, min_load = ULONG_MAX;
- int idlest = -1;
+ unsigned int min_exit_latency = UINT_MAX;
+ u64 idle_stamp, min_idle_stamp = ULONG_MAX;
+
+ struct rq *rq;
+ struct cpuidle_power *power;
+
+ int cpu_idle = -1;
+ int cpu_busy = -1;
int i;
/* Traverse only the allowed CPUs */
for_each_cpu_and(i, sched_group_cpus(group), tsk_cpus_allowed(p)) {
- load = weighted_cpuload(i);
- if (load < min_load || (load == min_load && i == this_cpu)) {
- min_load = load;
- idlest = i;
+ if (idle_cpu(i)) {
+
+ rq = cpu_rq(i);
+ power = rq->power;
+ idle_stamp = rq->idle_stamp;
+
+ /* The cpu is idle since a shorter time */
+ if (idle_stamp < min_idle_stamp) {
+ min_idle_stamp = idle_stamp;
+ cpu_idle = i;
+ continue;
+ }
+
+ /* The cpu is idle but the exit_latency is shorter */
+ if (power && power->exit_latency < min_exit_latency) {
+ min_exit_latency = power->exit_latency;
+ cpu_idle = i;
+ continue;
+ }
+ } else {
+
+ load = weighted_cpuload(i);
+
+ if (load < min_load ||
+ (load == min_load && i == this_cpu)) {
+ min_load = load;
+ cpu_busy = i;
+ continue;
+ }
}
}
- return idlest;
+ /* Busy cpus are considered less idle than idle cpus ;) */
+ return cpu_busy != -1 ? cpu_busy : cpu_idle;
}
/*
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists