| From 266405d05df6f842f9d6cbc7e15cf03600e1265c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 5 Nov 2021 17:10:47 -0500 |
| Subject: scsi: iscsi: Unblock session then wake up error handler |
| |
| From: Mike Christie <michael.christie@oracle.com> |
| |
| [ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ] |
| |
| We can race where iscsi_session_recovery_timedout() has woken up the error |
| handler thread and it's now setting the devices to offline, and |
| session_recovery_timedout()'s call to scsi_target_unblock() is also trying |
| to set the device's state to transport-offline. We can then get a mix of |
| states. |
| |
| For the case where we can't relogin we want the devices to be in |
| transport-offline so when we have repaired the connection |
| __iscsi_unblock_session() can set the state back to running. |
| |
| Set the device state then call into libiscsi to wake up the error handler. |
| |
| Link: https://lore.kernel.org/r/20211105221048.6541-2-michael.christie@oracle.com |
| Reviewed-by: Lee Duncan <lduncan@suse.com> |
| Signed-off-by: Mike Christie <michael.christie@oracle.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/scsi_transport_iscsi.c | 6 +++--- |
| 1 file changed, 3 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c |
| index 9906a3b562e93..269277c1d9dcc 100644 |
| --- a/drivers/scsi/scsi_transport_iscsi.c |
| +++ b/drivers/scsi/scsi_transport_iscsi.c |
| @@ -1896,12 +1896,12 @@ static void session_recovery_timedout(struct work_struct *work) |
| } |
| spin_unlock_irqrestore(&session->lock, flags); |
| |
| - if (session->transport->session_recovery_timedout) |
| - session->transport->session_recovery_timedout(session); |
| - |
| ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n"); |
| scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE); |
| ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n"); |
| + |
| + if (session->transport->session_recovery_timedout) |
| + session->transport->session_recovery_timedout(session); |
| } |
| |
| static void __iscsi_unblock_session(struct work_struct *work) |
| -- |
| 2.33.0 |
| |