From 1587872d58f3e91fcc83f799e393eda96708385e Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 15 Dec 2009 18:43:19 +0000 Subject: [PATCH] Merge with r1392: Patch from Smadar Gonen with minor changes fixing race in task managmement code if several TM functions affect the same command on different stages of processing. git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/1.0.1.x@1393 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst.h | 10 +++++----- scst/src/scst_targ.c | 14 ++++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index e0c9f83da..e075d8c29 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -388,14 +388,11 @@ enum scst_exec_context { /* Set if the cmd is aborted by other initiator */ #define SCST_CMD_ABORTED_OTHER 1 -/* Set if the cmd is aborted and counted in cmd_done_wait_count */ -#define SCST_CMD_DONE_COUNTED 2 - /* Set if no response should be sent to the target about this cmd */ -#define SCST_CMD_NO_RESP 3 +#define SCST_CMD_NO_RESP 2 /* Set if the cmd is dead and can be destroyed at any time */ -#define SCST_CMD_CAN_BE_DESTROYED 4 +#define SCST_CMD_CAN_BE_DESTROYED 3 /************************************************************* ** Tgt_dev's async. flags (tgt_dev_flags) @@ -1350,6 +1347,9 @@ struct scst_mgmt_cmd_stub { /* List entry in cmd->mgmt_cmd_list */ struct list_head cmd_mgmt_cmd_list_entry; + + /* set if the cmd was counted in mcmd->cmd_done_wait_count */ + unsigned int done_counted:1; }; struct scst_mgmt_cmd { diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index adb7192ac..3b6d449b2 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -3746,13 +3746,14 @@ void scst_done_cmd_mgmt(struct scst_cmd *cmd) spin_lock_irqsave(&scst_mcmd_lock, flags); - if (!test_bit(SCST_CMD_DONE_COUNTED, &cmd->cmd_flags)) - goto out_unlock; - list_for_each_entry(mstb, &cmd->mgmt_cmd_list, cmd_mgmt_cmd_list_entry) { - struct scst_mgmt_cmd *mcmd = mstb->mcmd; + struct scst_mgmt_cmd *mcmd; + if (!mstb->done_counted) + continue; + + mcmd = mstb->mcmd; TRACE_MGMT_DBG("mcmd %p, mcmd->cmd_done_wait_count %d", mcmd, mcmd->cmd_done_wait_count); @@ -3775,7 +3776,6 @@ void scst_done_cmd_mgmt(struct scst_cmd *cmd) } } -out_unlock: spin_unlock_irqrestore(&scst_mcmd_lock, flags); if (wake) @@ -3994,6 +3994,8 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd, "stub failed (mcmd %p, cmd %p)", mcmd, cmd); goto unlock; } + memset(mstb, 0, sizeof(mstb)); + mstb->mcmd = mcmd; /* @@ -4027,7 +4029,7 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd, TRACE_MGMT_DBG("cmd %p (tag %llu) is being executed " "and not done yet", cmd, (long long unsigned int)cmd->tag); - set_bit(SCST_CMD_DONE_COUNTED, &cmd->cmd_flags); + mstb->done_counted = 1; mcmd->cmd_done_wait_count++; } }