Re: [PATCH] target: Fix for hang of Ordered task in TCM

2016-06-08 Thread Nicholas A. Bellinger
On Wed, 2016-06-08 at 14:43 -0500, Bryant G. Ly wrote:



> 
> Hi Nic,
> 
> So I was testing the ibmvscsi target driver and I ran into some problems
> again with UA stuff and it looks like you didnt remove the UA checks from
> target_setup_cmd_from_cdb? Was that intentional? I thought we agreed to move
> it completely to target_execute_cmd and not have both?
> 
> Let me know.
> 

Ah yes, the version of the patch I've been using for future target-core
developments was missing the removal in target_setup_cmd_from_cdb().

Applied the proper version to target-pending/master here:

https://git.kernel.org/cgit/linux/kernel/git/nab/target-pending.git/commit/?id=15ce22fa491aa3bab7acd89ac40a9fc27aeed915

Thanks for the heads up!

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] target: Fix for hang of Ordered task in TCM

2016-06-08 Thread Bryant G. Ly
From: Nicholas Bellinger 

If a command with a Simple task attribute is failed due to a Unit
Attention, then a subsequent command with an Ordered task attribute
will hang forever.  The reason for this is that the Unit Attention
status is checked for in target_setup_cmd_from_cdb, before the call
to target_execute_cmd, which calls target_handle_task_attr, which
in turn increments dev->simple_cmds.

However, transport_generic_request_failure still calls
transport_complete_task_attr, which will decrement dev->simple_cmds.
In this case, simple_cmds is now -1.  So when a command with the
Ordered task attribute is sent, target_handle_task_attr sees that
dev->simple_cmds is not 0, so it decides it can't execute the
command until all the (nonexistent) Simple commands have completed.

Reported-by: Michael Cyr 
Signed-off-by: Nicholas Bellinger 
Signed-off-by: Bryant G. Ly 
---
 drivers/target/target_core_internal.h  |  1 +
 drivers/target/target_core_sbc.c   |  2 +-
 drivers/target/target_core_transport.c | 62 +++---
 include/target/target_core_fabric.h|  1 -
 4 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/target/target_core_internal.h 
b/drivers/target/target_core_internal.h
index fc91e85..e2c970a 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -146,6 +146,7 @@ sense_reason_t  target_cmd_size_check(struct se_cmd 
*cmd, unsigned int size);
 void   target_qf_do_work(struct work_struct *work);
 bool   target_check_wce(struct se_device *dev);
 bool   target_check_fua(struct se_device *dev);
+void   __target_execute_cmd(struct se_cmd *, bool);
 
 /* target_core_stat.c */
 void   target_stat_setup_dev_default_groups(struct se_device *);
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a9057aa..04f616b 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -602,7 +602,7 @@ static sense_reason_t compare_and_write_callback(struct 
se_cmd *cmd, bool succes
cmd->transport_state |= CMD_T_ACTIVE|CMD_T_BUSY|CMD_T_SENT;
spin_unlock_irq(&cmd->t_state_lock);
 
-   __target_execute_cmd(cmd);
+   __target_execute_cmd(cmd, false);
 
kfree(buf);
return ret;
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index e887635..7c4ea39 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1303,23 +1303,6 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned 
char *cdb)
 
trace_target_sequencer_start(cmd);
 
-   /*
-* Check for an existing UNIT ATTENTION condition
-*/
-   ret = target_scsi3_ua_check(cmd);
-   if (ret)
-   return ret;
-
-   ret = target_alua_state_check(cmd);
-   if (ret)
-   return ret;
-
-   ret = target_check_reservation(cmd);
-   if (ret) {
-   cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
-   return ret;
-   }
-
ret = dev->transport->parse_cdb(cmd);
if (ret == TCM_UNSUPPORTED_SCSI_OPCODE)
pr_warn_ratelimited("%s/%s: Unsupported SCSI Opcode 0x%02x, 
sending CHECK_CONDITION.\n",
@@ -1762,20 +1745,45 @@ queue_full:
 }
 EXPORT_SYMBOL(transport_generic_request_failure);
 
-void __target_execute_cmd(struct se_cmd *cmd)
+void __target_execute_cmd(struct se_cmd *cmd, bool do_checks)
 {
sense_reason_t ret;
 
-   if (cmd->execute_cmd) {
-   ret = cmd->execute_cmd(cmd);
-   if (ret) {
-   spin_lock_irq(&cmd->t_state_lock);
-   cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT);
-   spin_unlock_irq(&cmd->t_state_lock);
+   if (!cmd->execute_cmd) {
+   ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+   goto err;
+   }
+   if (do_checks) {
+   /*
+* Check for an existing UNIT ATTENTION condition after
+* target_handle_task_attr() has done SAM task attr
+* checking, and possibly have already defered execution
+* out to target_restart_delayed_cmds() context.
+*/
+   ret = target_scsi3_ua_check(cmd);
+   if (ret)
+   goto err;
+
+   ret = target_alua_state_check(cmd);
+   if (ret)
+   goto err;
 
-   transport_generic_request_failure(cmd, ret);
+   ret = target_check_reservation(cmd);
+   if (ret) {
+   cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
+   goto err;
}
}
+
+   ret = cmd->execute_cmd(cmd);
+   if (!ret)
+   return;
+err:
+   spin_lock_irq(&cmd->t_state_lock);
+   cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT);
+   spin_unlock_irq