diff mbox series

scsi: iscsi: print error info after unlock 'frwd_lock' in iscsi_check_transport_timeouts()

Message ID 20250409012933.3101354-1-yebin@huaweicloud.com (mailing list archive)
State New
Headers show
Series scsi: iscsi: print error info after unlock 'frwd_lock' in iscsi_check_transport_timeouts() | expand

Commit Message

Ye Bin April 9, 2025, 1:29 a.m. UTC
From: Ye Bin <yebin10@huawei.com>

When a timeout occurs in iscsi_check_transport_timeouts(), it may be
accompanied by many storage failures, and there may be many error logs
printed to the serial port in a short period. In the case of a slow
serial port, it may take a long time to output to the serial port in
printk while holding the "&session->frwd_lock" lock. This can cause
other processes to be unable to obtain the "&session->frwd_lock" lock,
triggering a series of issues. To reduce the critical section of the
"&session->frwd_lock" lock, error printing is moved outside the lock.

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 drivers/scsi/libiscsi.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 1ddaf7228340..bbaed4eccfbf 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2252,20 +2252,23 @@  static void iscsi_check_transport_timeouts(struct timer_list *t)
 	if (!recv_timeout)
 		goto done;
 
-	recv_timeout *= HZ;
 	last_recv = conn->last_recv;
 
 	if (iscsi_has_ping_timed_out(conn)) {
+		int ping_timeout = conn->ping_timeout;
+		unsigned long last_ping = conn->last_ping;
+
+		spin_unlock(&session->frwd_lock);
 		iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
-				  "expired, recv timeout %d, last rx %lu, "
+				  "expired, recv timeout %lu, last rx %lu, "
 				  "last ping %lu, now %lu\n",
-				  conn->ping_timeout, conn->recv_timeout,
-				  last_recv, conn->last_ping, jiffies);
-		spin_unlock(&session->frwd_lock);
+				  ping_timeout, recv_timeout,
+				  last_recv, last_ping, jiffies);
 		iscsi_conn_failure(conn, ISCSI_ERR_NOP_TIMEDOUT);
 		return;
 	}
 
+	recv_timeout *= HZ;
 	if (time_before_eq(last_recv + recv_timeout, jiffies)) {
 		/* send a ping to try to provoke some traffic */
 		ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");