From bd887e4a589d5fcd3e20ebc2a75fd59b889a3640 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Thu, 28 Jan 2016 16:19:17 +0530 Subject: [PATCH] sched: fix circular dependency of rq->lock and kswadp waitqueue lock There is a deadlock scenario due to the circular dependency of CPU's rq->lock and kswapd's waitqueue lock. (1) when kswapd is woken up, try_to_wake_up() is called with it's waitqueue lock held. It's previous CPU is offline, so it is woken up on a different CPU. We try to acquire the offline CPU's rq->lock in either cpufreq change callback or fixup_busy_time() (2) At the same time, the offline CPU is coming online and init_idle() is called from __cpu_up(). init_idle() calls __sched_fork() with rq->lock held. A debug object allocation in hrtimer_init() called from __sched_fork() is trying to wakeup the kswapd and attempts to take the waitqueue lock held in the (1) path. Task specific initialization is done in __sched_fork() and rq->lock is not held when it is called for other tasks. The same holds true for the idle task as well. __sched_fork() for the idle task is called only when the CPU is not active. Acquire the rq->lock after calling __sched_fork() in init_idle() to fix this deadlock. CRs-Fixed: 965873 Change-Id: Ib8a265835c29861dba571c9b2a6b7e75b5cb43ee Signed-off-by: Pavankumar Kondeti [satyap: trivial merge conflicts resolution and omitted changes for QHMP] Signed-off-by: Satya Durga Srinivasu Prabhala --- kernel/sched/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d40ace8eafee..8f14efd8ea06 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7868,10 +7868,11 @@ void init_idle(struct task_struct *idle, int cpu) struct rq *rq = cpu_rq(cpu); unsigned long flags; + __sched_fork(0, idle); + raw_spin_lock_irqsave(&idle->pi_lock, flags); raw_spin_lock(&rq->lock); - __sched_fork(0, idle); idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock();