Patch "libiscsi: Fix host busy blocking during connection teardown" has been added to the 4.1-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
libiscsi: Fix host busy blocking during connection teardown
to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
libiscsi-fix-host-busy-blocking-during-connection-teardown.patch
and it can be found in the queue-4.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
660d0831d1494a6837b2f810d08b5be092c1f31dMon Sep 17 00:00:00 2001
From: John Soni Jose <[email protected]>
Date: Wed, 24 Jun 2015 06:41:58 +0530
Subject: libiscsi: Fix host busy blocking during connection teardown
From: John Soni Jose <[email protected]>
commit 660d0831d1494a6837b2f810d08b5be092c1f31d upstream.
In case of hw iscsi offload, an host can have N-number of active connections. There can be IO's running on some connections which make host->host_busy always TRUE. Now if logout from a connection is tried then the code gets into an infinite loop as host->host_busy is always TRUE.
iscsi_conn_teardown(....)
{
.........
/*
* Block until all in-progress commands for this connection
* time out or fail.
*/
for (;;) {
spin_lock_irqsave(session->host->host_lock, flags);
if (!atomic_read(&session->host->host_busy)) { /* OK for ERL == 0 */
spin_unlock_irqrestore(session->host->host_lock, flags);
break;
}
spin_unlock_irqrestore(session->host->host_lock, flags);
msleep_interruptible(500);
iscsi_conn_printk(KERN_INFO, conn, "iscsi conn_destroy(): "
"host_busy %d host_failed %d\n",
atomic_read(&session->host->host_busy),
session->host->host_failed);
................
...............
}}
This is not an issue with software-iscsi/iser as each cxn is a separate host.
Fix:
Acquiring eh_mutex in iscsi_conn_teardown() before setting session->state = ISCSI_STATE_TERMINATE.
--- drivers/scsi/libiscsi.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-)
drivers/scsi/libiscsi.c +2 -23
@@ -2941,10 +2941,10 @@ void iscsi_conn_teardown(struct iscsi_cl {struct iscsi_conn *conn = cls_conn->dd_data;struct iscsi_session *session = conn->session; -unsigned long flags;del_timer_sync (&conn->transport_timer); +mutex_lock (&session->eh_mutex);spin_lock_bh (&session->frwd_lock); conn->c_stage =ISCSI_CONN_CLEANUP_WAIT ;if (session->leadconn == conn) {
@@ -2956,28 +2956,6 @@ void iscsi_conn_teardown(struct iscsi_cl }spin_unlock_bh (&session->frwd_lock); -/* -* Block until all in-progress commands for this connection -* time out or fail. -*/ -for (;;) { -spin_lock_irqsave (session->host->host_lock, flags); -if (!atomic_read (&session->host->host_busy)) {/* OK for ERL == 0 */ -spin_unlock_irqrestore (session->host->host_lock, flags); -break ; - } -spin_unlock_irqrestore (session->host->host_lock, flags); -msleep_interruptible (500 ); -iscsi_conn_printk (KERN_INFO , conn,"iscsi conn_destroy(): " -"host_busy %d host_failed %d\n" , -atomic_read (&session->host->host_busy), - session->host->host_failed); -/* -* force eh_abort() to unblock -*/ -wake_up (&conn->ehwait); - } -/* flush queued up work because we free the connection below */ iscsi_suspend_tx (conn);
@@ -2994,6 +2972,7 @@ void iscsi_conn_teardown(struct iscsi_clif (session->leadconn == conn) session->leadconn =NULL ;spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&session->eh_mutex);iscsi_destroy_conn (cls_conn); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.1/libiscsi-fix-host-busy-blocking-during-connection-teardown.patch