summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMurthy Bhat <Murthy.Bhat@microchip.com>2024-08-27 20:54:59 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2024-08-29 04:10:34 +0200
commit4e0a51716dae782822b5df6c3b29cc0915a9f802 (patch)
tree1a86f9dd9c417bfba78baca77be543bedab23102
parentscsi: smartpqi: add new controller PCI IDs (diff)
downloadlinux-4e0a51716dae782822b5df6c3b29cc0915a9f802.tar.xz
linux-4e0a51716dae782822b5df6c3b29cc0915a9f802.zip
scsi: smartpqi: fix rare system hang during LUN reset
Correct a rare case where in a LUN reset occurs on a device and I/O requests for other devices persist in the driver's internal request queue. Part of a LUN reset involves waiting for our internal request queue to empty before proceeding. The internal request queue contains requests not yet sent down to the controller. We were clearing the requests queued for the LUN undergoing a reset, but not all of the queued requests. Causing a hang. For all requests in our internal request queue: Complete requests with DID_RESET for queued requests for the device undergoing a reset. Complete requests with DID_REQUEUE for all other queued requests. Reviewed-by: Scott Benesh <scott.benesh@microchip.com> Reviewed-by: Scott Teel <scott.teel@microchip.com> Reviewed-by: Mike McGowen <mike.mcgowen@microchip.com> Signed-off-by: Murthy Bhat <Murthy.Bhat@microchip.com> Signed-off-by: Don Brace <don.brace@microchip.com> Link: https://lore.kernel.org/r/20240827185501.692804-6-don.brace@microchip.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 46bef2cf95c4..d1d117d5d08d 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -6200,14 +6200,12 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
continue;
scsi_device = scmd->device->hostdata;
- if (scsi_device != device)
- continue;
-
- if ((u8)scmd->device->lun != lun)
- continue;
list_del(&io_request->request_list_entry);
- set_host_byte(scmd, DID_RESET);
+ if (scsi_device == device && (u8)scmd->device->lun == lun)
+ set_host_byte(scmd, DID_RESET);
+ else
+ set_host_byte(scmd, DID_REQUEUE);
pqi_free_io_request(io_request);
scsi_dma_unmap(scmd);
pqi_scsi_done(scmd);