| From 88b7a5621711544cb7bc4343748a6462eb9dadc8 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 18 May 2021 10:46:23 +0530 |
| Subject: scsi: mpt3sas: Fix deadlock while cancelling the running firmware |
| event |
| |
| From: Suganath Prabu S <suganath-prabu.subramani@broadcom.com> |
| |
| [ Upstream commit e2fac6c44ae06e58ac02181b048af31195883c31 ] |
| |
| Do not cancel current running firmware event work if the event type is |
| different from MPT3SAS_REMOVE_UNRESPONDING_DEVICES. Otherwise a deadlock |
| can be observed while cancelling the current firmware event work if a hard |
| reset operation is called as part of processing the current event. |
| |
| Link: https://lore.kernel.org/r/20210518051625.1596742-2-suganath-prabu.subramani@broadcom.com |
| Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 ++++++++++++++++++++++ |
| 1 file changed, 22 insertions(+) |
| |
| diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c |
| index 7824e77bc6e2..15d1f1fbeee7 100644 |
| --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c |
| +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c |
| @@ -3696,6 +3696,28 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) |
| ioc->fw_events_cleanup = 1; |
| while ((fw_event = dequeue_next_fw_event(ioc)) || |
| (fw_event = ioc->current_event)) { |
| + |
| + /* |
| + * Don't call cancel_work_sync() for current_event |
| + * other than MPT3SAS_REMOVE_UNRESPONDING_DEVICES; |
| + * otherwise we may observe deadlock if current |
| + * hard reset issued as part of processing the current_event. |
| + * |
| + * Orginal logic of cleaning the current_event is added |
| + * for handling the back to back host reset issued by the user. |
| + * i.e. during back to back host reset, driver use to process |
| + * the two instances of MPT3SAS_REMOVE_UNRESPONDING_DEVICES |
| + * event back to back and this made the drives to unregister |
| + * the devices from SML. |
| + */ |
| + |
| + if (fw_event == ioc->current_event && |
| + ioc->current_event->event != |
| + MPT3SAS_REMOVE_UNRESPONDING_DEVICES) { |
| + ioc->current_event = NULL; |
| + continue; |
| + } |
| + |
| /* |
| * Wait on the fw_event to complete. If this returns 1, then |
| * the event was never executed, and we need a put for the |
| -- |
| 2.30.2 |
| |