Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ded1a563 authored by Subhash Jadavani's avatar Subhash Jadavani
Browse files

scsi: ufs: fix deadlock between clock scaling and clock ungating work



There's a deadlock between clock scaling and clock ungating work if hibern8
exit fails while ungating clocks.

ufshcd_exec_dev_cmd() in clock ungating work blocks at taking
"clk_scaling_lock" unless clock scaling work completes which had taken
"clock_scaling_lock" and it will never be released hence this is a
deadlock.

Clock ungating context:
----------------------
-000|__switch_to()
-001|context_switch(inline)
-001|__schedule()
-002|schedule()
-003|rwsem_down_read_failed()
-004|down_read()
-005|ufshcd_get_dev_cmd_tag(inline)
-005|ufshcd_exec_dev_cmd()
-006|ufshcd_verify_dev_init()
-007|ufshcd_probe_hba()
-008|ufshcd_host_reset_and_restore()
-009|ufshcd_link_recovery()
-010|ufshcd_uic_hibern8_exit()
-011|ufshcd_ungate_work()
-012|static_key_count(inline)
-012|static_key_false(inline)
-012|trace_workqueue_execute_end(inline)
-012|process_one_work()
-013|process_scheduled_works(inline)
-013|worker_thread()
-014|kthread()
-015|ret_from_fork(asm)
 -->|exception
-016|NSX:0xF0440E59300(asm)
 ---|end of frame

Clock scaling context:
----------------------
-000|__switch_to()
-001|context_switch(inline)
-001|__schedule()
-002|schedule()
-003|schedule_timeout()
-004|do_wait_for_common(inline)
-004|__wait_for_common(inline)
-004|wait_for_common()
-005|wait_for_completion()
-006|flush_work()
-007|ufshcd_hold()
-008|ufshcd_hold_all()
-009|ufshcd_wait_for_doorbell_clr()
-010|ufshcd_clock_scaling_prepare(inline)
-010|ufshcd_devfreq_scale()
-011|ufshcd_devfreq_target()
-012|update_devfreq()
-013|devfreq_monitor()
-014|static_key_count(inline)
-014|static_key_false(inline)
-014|trace_workqueue_execute_end(inline)
-014|process_one_work()
-015|worker_thread()
-016|kthread()
-017|ret_from_fork(asm)
 -->|exception
-018|NSR:0x2A714C(asm)
---|end of frame

This change is fixing this by moving ufshcd_hold_all() in
ufshcd_devfreq_scale() to the beginning of the function so that
clk_scaling_lock is acquired only after clock ungating completes.

CRs-Fixed: 963407
Change-Id: I83788c3212baeab31cf1bf877ca0aaf9005ca661
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent 459abfee
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment