sched: walt: Serialize check_for_migration across all CPUs

check_for_migration may select the same destination cpu for two separate
tasks running on two separate cpus, resulting in those two tasks being
packed onto the same higher-capacity CPU. Avoid this situation by
serializing check_for_migration with a global spinlock.

Change-Id: I4ec439bcbcdc0a52a5289f239a6160baa7e50da0
Signed-off-by: Puja Gupta <pujag@codeaurora.org>
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index db8d37f..e0ab4d6 100755
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -11119,6 +11119,7 @@
 
 #if defined(CONFIG_SCHED_WALT)
 
+static DEFINE_RAW_SPINLOCK(migration_lock);
 void check_for_migration(struct rq *rq, struct task_struct *p)
 {
 	int new_cpu;
@@ -11130,6 +11131,7 @@
 		    rq->curr->nr_cpus_allowed == 1)
 			return;
 
+		raw_spin_lock(&migration_lock);
 		rcu_read_lock();
 		new_cpu = energy_aware_wake_cpu(p, cpu, 0);
 		rcu_read_unlock();
@@ -11137,11 +11139,14 @@
 			active_balance = kick_active_balance(rq, p, new_cpu);
 			if (active_balance) {
 				mark_reserved(new_cpu);
+				raw_spin_unlock(&migration_lock);
 				stop_one_cpu_nowait(cpu,
 					active_load_balance_cpu_stop, rq,
 					&rq->active_balance_work);
+				return;
 			}
 		}
+		raw_spin_unlock(&migration_lock);
 	}
 }