OSDN Git Service

scsi: ufs: Fix a race condition between ufshcd_abort() and eh_work()
authorCan Guo <cang@codeaurora.org>
Wed, 2 Dec 2020 12:04:02 +0000 (04:04 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 7 Dec 2020 23:29:24 +0000 (18:29 -0500)
commit7a7e66c65d4148fc3f23b058405bc9f102414fcb
tree8ad6db852e0314bf3246a3713637e3af0ccef4a5
parent88a92d6ae4fe09b2b27781178c5c9432d27b1ffb
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>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h