Patch "target: Fix remote-port TMR ABORT + se_cmd fabric stop" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
target: Fix remote-port TMR ABORT + se_cmd fabric stop
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-remote-port-tmr-abort-se_cmd-fabric-stop.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 <[email protected]> know about it.
Quoted 1 line
From
0f4a943168f31d29a1701908931acaba518b131aMon Sep 17 00:00:00 2001
From: Nicholas Bellinger <[email protected]>
Date: Tue, 19 Jan 2016 15:23:02 -0800
Subject: target: Fix remote-port TMR ABORT + se_cmd fabric stop
From: Nicholas Bellinger <[email protected]>
commit 0f4a943168f31d29a1701908931acaba518b131a upstream.
To address the bug where fabric driver level shutdown of se_cmd occurs at the same time when TMR CMD_T_ABORTED is happening resulting in a -1 ->cmd_kref, this patch adds a CMD_T_FABRIC_STOP bit that is used to determine when TMR + driver I_T nexus shutdown is happening concurrently.
It changes target_sess_cmd_list_set_waiting() to obtain se_cmd->cmd_kref + set CMD_T_FABRIC_STOP, and drop local reference in target_wait_for_sess_cmds() and invoke extra target_put_sess_cmd() during Task Aborted Status (TAS) when necessary.
Also, it adds a new target_wait_free_cmd() wrapper around transport_wait_for_tasks() for the special case within transport_generic_free_cmd() to set CMD_T_FABRIC_STOP, and is now aware of CMD_T_ABORTED + CMD_T_TAS status bits to know when an extra transport_put_cmd() during TAS is required.
Note transport_generic_free_cmd() is expected to block on cmd->cmd_wait_comp in order to follow what iscsi-target expects during iscsi_conn context se_cmd shutdown.
--- drivers/target/target_core_tmr.c | 57 +++++++++---- drivers/target/target_core_transport.c | 137 +++++++++++++++++++++++++-------- include/target/target_core_base.h | 2 3 files changed, 148 insertions(+), 48 deletions(-)
drivers/target/target_core_tmr.c +40 -17
@@ -82,16 +82,18 @@ void core_tmr_release_req(kfree (tmr); } -static void core_tmr_handle_tas_abort ( -struct se_session *tmr_sess, -struct se_cmd *cmd, -int tas) +static void core_tmr_handle_tas_abort (struct se_cmd *cmd,int tas) { -bool remove = true; +unsigned long flags; +bool remove = true, send_tas;/* * TASK ABORTED status (TAS) bit support -*/ -if (tmr_sess && tmr_sess != cmd->se_sess && tas) { +*/ +spin_lock_irqsave (&cmd->t_state_lock, flags); + send_tas = (cmd->transport_state &CMD_T_TAS ); +spin_unlock_irqrestore (&cmd->t_state_lock, flags); + +if (send_tas) { remove = false;transport_send_task_abort (cmd); }
@@ -114,7 +116,8 @@ static int target_check_cdb_and_preempt(return 1 ; } -static bool __target_check_io_state (struct se_cmd *se_cmd) +static bool __target_check_io_state (struct se_cmd *se_cmd, +struct se_session *tmr_sess,int tas) {struct se_session *sess = se_cmd->se_sess;
@@ -122,21 +125,33 @@ static bool __target_check_io_state(struWARN_ON_ONCE (!irqs_disabled ());/* * If command already reached CMD_T_COMPLETE state within -* target_complete_cmd(), this se_cmd has been passed to -* fabric driver and will not be aborted. +* target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown, +* this se_cmd has been passed to fabric driver and will +* not be aborted. * * Otherwise, obtain a local se_cmd->cmd_kref now for TMR * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as * long as se_cmd->cmd_kref is still active unless zero. */ spin_lock (&se_cmd->t_state_lock); -if (se_cmd->transport_state &CMD_T_COMPLETE ) { -pr_debug ("Attempted to abort io tag: %u already complete," +if (se_cmd->transport_state & (CMD_T_COMPLETE |CMD_T_FABRIC_STOP )) { +pr_debug ("Attempted to abort io tag: %u already complete or" +" fabric stop, skipping\n" , + se_cmd->se_tfo->get_task_tag (se_cmd)); +spin_unlock (&se_cmd->t_state_lock); +return false; + } +if (sess->sess_tearing_down || se_cmd->cmd_wait_set) { +pr_debug ("Attempted to abort io tag: %u already shutdown," " skipping\n" , se_cmd->se_tfo->get_task_tag (se_cmd));spin_unlock (&se_cmd->t_state_lock);return false; } se_cmd->transport_state |=CMD_T_ABORTED ; + +if ((tmr_sess != se_cmd->se_sess) && tas) + se_cmd->transport_state |=CMD_T_TAS ; +spin_unlock (&se_cmd->t_state_lock);return kref_get_unless_zero (&se_cmd->cmd_kref);
@@ -164,7 +179,7 @@ void core_tmr_abort_task(printk ("ABORT_TASK: Found referenced %s task_tag: %u\n" , se_cmd->se_tfo->get_fabric_name (), ref_tag); -if (!__target_check_io_state (se_cmd)) { +if (!__target_check_io_state (se_cmd, se_sess,0 )) {spin_unlock_irqrestore (&se_sess->sess_cmd_lock, flags);target_put_sess_cmd (se_sess, se_cmd); goto out;
@@ -234,7 +249,8 @@ static void core_tmr_drain_tmr_list(spin_lock (&sess->sess_cmd_lock);spin_lock (&cmd->t_state_lock); -if (!(cmd->transport_state &CMD_T_ACTIVE )) { +if (!(cmd->transport_state &CMD_T_ACTIVE ) || + (cmd->transport_state &CMD_T_FABRIC_STOP )) {spin_unlock (&cmd->t_state_lock);spin_unlock (&sess->sess_cmd_lock);continue ;
@@ -244,15 +260,22 @@ static void core_tmr_drain_tmr_list(spin_unlock (&sess->sess_cmd_lock);continue ; } +if (sess->sess_tearing_down || cmd->cmd_wait_set) { +spin_unlock (&cmd->t_state_lock); +spin_unlock (&sess->sess_cmd_lock); +continue ; + } cmd->transport_state |=CMD_T_ABORTED ;spin_unlock (&cmd->t_state_lock); rc =kref_get_unless_zero (&cmd->cmd_kref); -spin_unlock (&sess->sess_cmd_lock);if (!rc) {printk ("LUN_RESET TMR: non-zero kref_get_unless_zero\n" ); +spin_unlock (&sess->sess_cmd_lock);continue ; } +spin_unlock (&sess->sess_cmd_lock); +list_move_tail (&tmr_p->tmr_list, &drain_tmr_list); }spin_unlock_irqrestore (&dev->se_tmr_lock, flags);
@@ -329,7 +352,7 @@ static void core_tmr_drain_state_list(continue ;spin_lock (&sess->sess_cmd_lock); - rc =__target_check_io_state (cmd); + rc =__target_check_io_state (cmd, tmr_sess, tas);spin_unlock (&sess->sess_cmd_lock);if (!rc)continue ;
@@ -368,7 +391,7 @@ static void core_tmr_drain_state_list(cancel_work_sync (&cmd->work);transport_wait_for_tasks (cmd); -core_tmr_handle_tas_abort (tmr_sess, cmd, tas); +core_tmr_handle_tas_abort (cmd, tas);target_put_sess_cmd (cmd->se_sess, cmd); } }
drivers/target/target_core_transport.c +106 -31
233 lines not on this page · raw message
include/target/target_core_base.h +2 -0
@@ -528,6 +528,8 @@ struct se_cmd {#define CMD_T_DEV_ACTIVE (1 << 7)#define CMD_T_REQUEST_STOP (1 << 8)#define CMD_T_BUSY (1 << 9) +#define CMD_T_TAS (1 << 10) +#define CMD_T_FABRIC_STOP (1 << 11)spinlock_t t_state_lock;struct completion t_transport_stop_comp;
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/target-fix-task-aborted-status-tas-handling.patch queue-3.14/target-add-tfo-abort_task-for-aborted-task-resources-release.patch queue-3.14/target-fix-remote-port-tmr-abort-se_cmd-fabric-stop.patch queue-3.14/target-fix-lun_reset-active-tmr-descriptor-handling.patch queue-3.14/target-fix-write_same-discard-conversion-to-linux-512b-sectors.patch queue-3.14/target-fix-race-with-scf_send_delayed_tas-handling.patch queue-3.14/target-fix-lun_reset-active-i-o-handling-for-ack_kref.patch queue-3.14/target-fix-tas-handling-for-multi-session-se_node_acls.patch