summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorPavankumar Kondeti <pkondeti@codeaurora.org>2016-01-28 16:19:17 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:30:42 -0700
commitbd887e4a589d5fcd3e20ebc2a75fd59b889a3640 (patch)
tree6b0b4feeefc1520b6c0990eb9ed6ad790c4b5dac /kernel
parent7a649da27817813c3c89dff59797f083acf30004 (diff)
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 <pkondeti@codeaurora.org> [satyap: trivial merge conflicts resolution and omitted changes for QHMP] Signed-off-by: Satya Durga Srinivasu Prabhala <satyap@codeaurora.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/core.c3
1 files changed, 2 insertions, 1 deletions
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();