mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
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:
[<ffffffda02613964>] queued_spin_lock_slowpath+0x88
[<ffffffda025c94c0>] try_to_wake_up[jt]+0x25c
[<ffffffda025fbe0c>] complete_all+0xb4
[<ffffffd9fdb7635c>] android_rvh_tick_entry[sched_walt]+0x5c
[<ffffffda025d1bdc>] scheduler_tick+0x4b0
Fixes: 4e3e7cc6133d2f7 ("sched: Align window start with tick boundary")
Change-Id: I1e1310c6c5513f38c4fd95b933ff407d740c1112
Signed-off-by: Satya Durga Srinivasu Prabhala <quic_satyap@quicinc.com>
This commit is contained in:
parent
97a7eb4292
commit
318a435b83
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user