mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
scsi: ufs: core: Fix synchronization between scsi_unjam_host() and ufshcd_queuecommand()
The SCSI error handler calls scsi_unjam_host() which can call the queue function ufshcd_queuecommand() indirectly. The error handler changes the state to UFSHCD_STATE_RESET while running, but error interrupts that happen while the error handler is running could change the state to UFSHCD_STATE_EH_SCHEDULED_NON_FATAL which would allow requests to go through ufshcd_queuecommand() even though the error handler is running. Block that hole by checking whether the error handler is in progress. Link: https://lore.kernel.org/r/20211008084048.257498-1-adrian.hunter@intel.com Reviewed-by: Asutosh Das <asutoshd@codeaurora.org> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
9561f58442
commit
d489f18ad1
1 changed files with 12 additions and 0 deletions
|
@ -2686,7 +2686,19 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
|
|||
|
||||
switch (hba->ufshcd_state) {
|
||||
case UFSHCD_STATE_OPERATIONAL:
|
||||
break;
|
||||
case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL:
|
||||
/*
|
||||
* SCSI error handler can call ->queuecommand() while UFS error
|
||||
* handler is in progress. Error interrupts could change the
|
||||
* state from UFSHCD_STATE_RESET to
|
||||
* UFSHCD_STATE_EH_SCHEDULED_NON_FATAL. Prevent requests
|
||||
* being issued in that case.
|
||||
*/
|
||||
if (ufshcd_eh_in_progress(hba)) {
|
||||
err = SCSI_MLQUEUE_HOST_BUSY;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case UFSHCD_STATE_EH_SCHEDULED_FATAL:
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue