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>
This commit is contained in:
parent
7a649da278
commit
bd887e4a58
1 changed files with 2 additions and 1 deletions
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue