>From c442238814d46930794d4ace4d577f05278f9508 Mon Sep 17 00:00:00 2001
From: Alex Shi <alex.shi@linaro.org>
Date: Fri, 25 Sep 2015 02:31:18 +0800
Subject: [PATCH] sched/find_idlest_cpu: use the idle cpu in interrupting

Use the interrupting idle cpu instead of the shallowest one could
save cpu power.
But need to measure the latency change, since the shallowest idle
cpu's wakeup time could compete with interrupt job.
---
 kernel/sched/fair.c      | 19 +++++++++++++++++++
 kernel/time/tick-sched.c |  2 +-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 6e2e348..7eefdeb 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -34,6 +34,7 @@
 #include <trace/events/sched.h>
 
 #include "sched.h"
+#include "../time/tick-sched.h"
 
 /*
  * Targeted preemption latency for CPU-bound tasks:
@@ -4726,6 +4727,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p,
 /*
  * find_idlest_cpu - find the idlest cpu among the cpus in group.
  */
+DECLARE_PER_CPU(struct tick_sched, tick_cpu_sched);
 static int
 find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
 {
@@ -4734,6 +4736,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
 	u64 latest_idle_timestamp = 0;
 	int least_loaded_cpu = this_cpu;
 	int shallowest_idle_cpu = -1;
+	int interrupted_idle = -1;
 	int i;
 
 	/* Traverse only the allowed CPUs */
@@ -4741,6 +4744,19 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
 		if (idle_cpu(i)) {
 			struct rq *rq = cpu_rq(i);
 			struct cpuidle_state *idle = idle_get_state(rq);
+
+#ifdef CONFIG_NO_HZ_COMMON
+			struct tick_sched *ts = &per_cpu(tick_cpu_sched, i);
+			if (ts->inidle && !ts->idle_active) {
+				/* idle cpu doing irq */
+				interrupted_idle = i;
+				break;
+			} else if (!ts->inidle) {
+				 /* the cpu resched */
+				interrupted_idle = i;
+				continue;
+			} else
+#endif
 			if (idle && idle->exit_latency < min_exit_latency) {
 				/*
 				 * We give priority to a CPU whose idle state
@@ -4769,6 +4785,9 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
 		}
 	}
 
+	if (interrupted_idle != -1)
+		return interrupted_idle;
+
 	return shallowest_idle_cpu != -1 ? shallowest_idle_cpu : least_loaded_cpu;
 }
 
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 7c7ec45..7a89b7f 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -34,7 +34,7 @@
 /*
  * Per cpu nohz control structure
  */
-static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
+DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
 
 /*
  * The time, when the last jiffy update happened. Protected by jiffies_lock.
-- 
1.9.1

