From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:35100 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1946912AbcHRNKu (ORCPT ); Thu, 18 Aug 2016 09:10:50 -0400 Subject: Patch "target: Fix race between iscsi-target connection shutdown + ABORT_TASK" has been added to the 3.14-stable tree To: nab@linux-iscsi.org, gregkh@linuxfoundation.org, hare@suse.de, hch@lst.de, himanshu.madhani@qlogic.com, mchristi@redhat.com, quinn.tran@qlogic.com Cc: , From: Date: Thu, 18 Aug 2016 15:09:55 +0200 Message-ID: <1471525795234251@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: This is a note to let you know that I've just added the patch titled target: Fix race between iscsi-target connection shutdown + ABORT_TASK to the 3.14-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: target-fix-race-between-iscsi-target-connection-shutdown-abort_task.patch and it can be found in the queue-3.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >>From 064cdd2d91c2805d788876082f31cc63506f22c3 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 2 Jun 2016 14:56:45 -0700 Subject: target: Fix race between iscsi-target connection shutdown + ABORT_TASK From: Nicholas Bellinger commit 064cdd2d91c2805d788876082f31cc63506f22c3 upstream. This patch fixes a race in iscsit_release_commands_from_conn() -> iscsit_free_cmd() -> transport_generic_free_cmd() + wait_for_tasks=1, where CMD_T_FABRIC_STOP could end up being set after the final kref_put() is called from core_tmr_abort_task() context. This results in transport_generic_free_cmd() blocking indefinately on se_cmd->cmd_wait_comp, because the target_release_cmd_kref() check for CMD_T_FABRIC_STOP returns false. To address this bug, make iscsit_release_commands_from_conn() do list_splice and set CMD_T_FABRIC_STOP early while holding iscsi_conn->cmd_lock. Also make iscsit_aborted_task() only remove iscsi_cmd_t if CMD_T_FABRIC_STOP has not already been set. Finally in target_release_cmd_kref(), only honor fabric_stop if CMD_T_ABORTED has been set. Cc: Mike Christie Cc: Quinn Tran Cc: Himanshu Madhani Cc: Christoph Hellwig Cc: Hannes Reinecke Tested-by: Nicholas Bellinger Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/iscsi/iscsi_target.c | 22 ++++++++++++++++------ drivers/target/target_core_transport.c | 3 ++- 2 files changed, 18 insertions(+), 7 deletions(-) --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -505,7 +505,8 @@ static void iscsit_aborted_task(struct i bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD); spin_lock_bh(&conn->cmd_lock); - if (!list_empty(&cmd->i_conn_node)) + if (!list_empty(&cmd->i_conn_node) && + !(cmd->se_cmd.transport_state & CMD_T_FABRIC_STOP)) list_del_init(&cmd->i_conn_node); spin_unlock_bh(&conn->cmd_lock); @@ -4160,6 +4161,7 @@ transport_err: static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) { + LIST_HEAD(tmp_list); struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL; struct iscsi_session *sess = conn->sess; /* @@ -4168,18 +4170,26 @@ static void iscsit_release_commands_from * has been reset -> returned sleeping pre-handler state. */ spin_lock_bh(&conn->cmd_lock); - list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { + list_splice_init(&conn->conn_cmd_list, &tmp_list); + list_for_each_entry(cmd, &tmp_list, i_conn_node) { + struct se_cmd *se_cmd = &cmd->se_cmd; + + if (se_cmd->se_tfo != NULL) { + spin_lock(&se_cmd->t_state_lock); + se_cmd->transport_state |= CMD_T_FABRIC_STOP; + spin_unlock(&se_cmd->t_state_lock); + } + } + spin_unlock_bh(&conn->cmd_lock); + + list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) { list_del_init(&cmd->i_conn_node); - spin_unlock_bh(&conn->cmd_lock); iscsit_increment_maxcmdsn(cmd, sess); - iscsit_free_cmd(cmd, true); - spin_lock_bh(&conn->cmd_lock); } - spin_unlock_bh(&conn->cmd_lock); } static void iscsit_stop_timers_for_cmds( --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2407,7 +2407,8 @@ static void target_release_cmd_kref(stru } spin_lock(&se_cmd->t_state_lock); - fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP); + fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP) && + (se_cmd->transport_state & CMD_T_ABORTED); spin_unlock(&se_cmd->t_state_lock); if (se_cmd->cmd_wait_set || fabric_stop) { Patches currently in stable-queue which might be from nab@linux-iscsi.org are queue-3.14/target-fix-max_unmap_lba_count-calc-overflow.patch queue-3.14/target-fix-race-between-iscsi-target-connection-shutdown-abort_task.patch