From 318a435b83a9fb79d233e2b2d83f85f1c43bcd34 Mon Sep 17 00:00:00 2001 From: Satya Durga Srinivasu Prabhala Date: Thu, 14 Apr 2022 12:16:01 -0700 Subject: [PATCH] sched/walt: fix deadlock due to recursive rq locking complete_all() being called from android_rvh_tick_entry() trace hook implementation to wake up task (kworker) waiting on completion variable. While task waking if scheduler chooses to place the task on same CPU where complete_all() is invoked (from scheduler_tick()), system would run into deadlock as wake up path tries to acquire rq lock of the CPU from ttwu_queue() which was already acquired in scheduler_tick(). Fix the deadlock by moving related code chunk to android_vh_scheduler_tick() trace hook implementation. Call statck for info: [] queued_spin_lock_slowpath+0x88 [] try_to_wake_up[jt]+0x25c [] complete_all+0xb4 [] android_rvh_tick_entry[sched_walt]+0x5c [] scheduler_tick+0x4b0 Fixes: 4e3e7cc6133d2f7 ("sched: Align window start with tick boundary") Change-Id: I1e1310c6c5513f38c4fd95b933ff407d740c1112 Signed-off-by: Satya Durga Srinivasu Prabhala --- kernel/sched/walt/walt.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/kernel/sched/walt/walt.c b/kernel/sched/walt/walt.c index c854281c888d..a6c45b85fd0c 100644 --- a/kernel/sched/walt/walt.c +++ b/kernel/sched/walt/walt.c @@ -4189,22 +4189,13 @@ static void android_rvh_try_to_wake_up_success(void *unused, struct task_struct raw_spin_unlock_irqrestore(&cpu_rq(cpu)->__lock, flags); } -u64 tick_sched_clock; +static u64 tick_sched_clock; static DECLARE_COMPLETION(tick_sched_clock_completion); static void android_rvh_tick_entry(void *unused, struct rq *rq) { u64 wallclock; - if (!tick_sched_clock) { - /* - * Let the window begin 20us prior to the tick, - * that way we are guaranteed a rollover when the tick occurs. - */ - tick_sched_clock = rq_clock(rq) - 20000; - complete_all(&tick_sched_clock_completion); - } - lockdep_assert_held(&rq->__lock); if (unlikely(walt_disabled)) return; @@ -4222,6 +4213,15 @@ static void android_vh_scheduler_tick(void *unused, struct rq *rq) struct walt_related_thread_group *grp; u32 old_load; + if (!tick_sched_clock) { + /* + * Let the window begin 20us prior to the tick, + * that way we are guaranteed a rollover when the tick occurs. + */ + tick_sched_clock = rq_clock(rq) - 20000; + complete(&tick_sched_clock_completion); + } + if (unlikely(walt_disabled)) return; @@ -4442,7 +4442,7 @@ static void walt_init(struct work_struct *work) walt_rt_init(); walt_cfs_init(); walt_halt_init(); - wait_for_completion(&tick_sched_clock_completion); + wait_for_completion_interruptible(&tick_sched_clock_completion); stop_machine(walt_init_stop_handler, NULL, NULL); hdr = register_sysctl_table(walt_base_table);