scsi: ufs: Fix back to back clk gate work
In some rare scenario, inconsistent state b/w clk_gating.state and uic link state is observed when back to back clk_gate_work gets scheduled. Sequence of events: 1. hibern8 enter fails as a part of ufshc_gate_work. 2. Link recovery marks eh_in_progress and schedules the error handler to recovery the failure. 3. Error handler finished its work, it clears eh_in_progress and returns, thus link recovery succeeds 4. THe next retry of hibern8 succeed and sets the clk_gating.state to CLK_OFF. 5. B/w step 2 and 4 when eh_in_progress is already set, if any async thread says IOCTL calls ufshcd_hold, only clk_gating.active_requests increases and it bails out. 6. After async thread finishes its job and calls ufshcd_release. if ufshcd_release() is called after eh_in_progress is cleared, it would schedule the clk_gate_work instead of bailing out. 7. when 2nd gate_work runs after 1st clk gate work is over, since 1st gate work would have set the clk_gating.state as CLKS_OFF, the current gate work sets clk_gating.state to CLKS_ON and bails out. This leaves the clk_gating.state as CLKS_ON and link as hibern8 state which causes inconsistency and causes i/o block and deadloop when new i/o request calls ufshcd_hold functions with sync flag as false and true successfully. Fix this by checking clk_gating.state, if it is already CLKS_OFF, bail from clk_gate_work(). Change-Id: Ia60a4c872c39636c1e5144584025f8938e712202 Signed-off-by:Can Guo <cang@codeaurora.org> Signed-off-by:
Nitin Rawat <nitirawa@codeaurora.org>
Loading
Please register or sign in to comment