diff options
author | Can Guo <cang@codeaurora.org> | 2020-12-02 04:04:02 -0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2020-12-07 18:29:24 -0500 |
commit | 7a7e66c65d4148fc3f23b058405bc9f102414fcb (patch) | |
tree | 8ad6db852e0314bf3246a3713637e3af0ccef4a5 /drivers/scsi/ufs/ufshcd.h | |
parent | 88a92d6ae4fe09b2b27781178c5c9432d27b1ffb (diff) | |
download | linux-7a7e66c65d4148fc3f23b058405bc9f102414fcb.tar.gz |
scsi: ufs: Fix a race condition between ufshcd_abort() and eh_work()
In current task abort routine, if task abort happens to the device W-LUN, the code directly jumps to ufshcd_eh_host_reset_handler() to perform a full reset and restore then returns FAIL or SUCCESS. Commands sent to the device W-LUN are most likely the SSU cmds sent during UFS PM operations. If such SSU cmd enters task abort routine when ufshcd_eh_host_reset_handler() flushes eh_work, it will get stuck there since err_handler is serialized with PM operations. In order to unblock above call path, we merely clean up the lrb taken by this cmd, queue the eh_work and return SUCCESS. Once the cmd is aborted, the PM operation which sends out the cmd just errors out, then err_handler shall be able to proceed with the full reset and restore. In this scenario, the cmd is aborted even before it is actually cleared by HW, set the lrb->in_use flag to prevent subsequent cmds, including SCSI cmds and dev cmds, from taking the lrb released from abort. The flag shall evetually be cleared in __ufshcd_transfer_req_compl() invoked by the full reset and restore from err_handler. [mkp: conflict with event logging series] Link: https://lore.kernel.org/r/1606910644-21185-3-git-send-email-cang@codeaurora.org Reviewed-by: Asutosh Das <asutoshd@codeaurora.org> Reviewed-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Can Guo <cang@codeaurora.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs/ufshcd.h')
-rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 1d4d3f80caa0..08c8a591e6b0 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -193,6 +193,7 @@ struct ufs_pm_lvl_states { * @crypto_key_slot: the key slot to use for inline crypto (-1 if none) * @data_unit_num: the data unit number for the first block for inline crypto * @req_abort_skip: skip request abort task flag + * @in_use: indicates that this lrb is still in use */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; @@ -222,6 +223,7 @@ struct ufshcd_lrb { #endif bool req_abort_skip; + bool in_use; }; /** |