From c3a77a0d45e23e16adb5a7892a1b1c445d749ff0 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Thu, 10 Apr 2008 10:57:30 +0000 Subject: [PATCH] Critical fix: - Fixes hang on HEAD OF QUEUE commands under high load git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@333 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scsi_tgt.h | 5 ++++- scst/src/scst_lib.c | 4 ++++ scst/src/scst_targ.c | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/scst/include/scsi_tgt.h b/scst/include/scsi_tgt.h index 121fc6a96..e6577b4a5 100644 --- a/scst/include/scsi_tgt.h +++ b/scst/include/scsi_tgt.h @@ -1082,9 +1082,12 @@ struct scst_cmd */ unsigned int preprocessing_only:1; - /* Set if scst_cmd_set_sn() was called */ + /* Set if cmd's SN was set */ unsigned int sn_set:1; + /* Set if hq_cmd_count was incremented */ + unsigned int hq_cmd_inced:1; + /* * Set if scst_cmd_init_stage1_done() called and the target wants * that the SN for the cmd won't be assigned until scst_restart_cmd() diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 39f448770..889f537df 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -3045,6 +3045,9 @@ void scst_on_hq_cmd_response(struct scst_cmd *cmd) TRACE_ENTRY(); + if (!cmd->hq_cmd_inced) + goto out; + spin_lock_irq(&tgt_dev->sn_lock); tgt_dev->hq_cmd_count--; spin_unlock_irq(&tgt_dev->sn_lock); @@ -3059,6 +3062,7 @@ void scst_on_hq_cmd_response(struct scst_cmd *cmd) if (tgt_dev->hq_cmd_count == 0) scst_make_deferred_commands_active(tgt_dev, cmd); +out: TRACE_EXIT(); return; } diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 36c57e889..b0a4a5dd1 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -2725,11 +2725,15 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd) struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; unsigned long flags; + TRACE_ENTRY(); + if (scst_is_implicit_hq(cmd)) { TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "Implicit HQ cmd %p", cmd); cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE; } + EXTRACHECKS_BUG_ON(cmd->sn_set || cmd->hq_cmd_inced); + /* Optimized for lockless fast path */ scst_check_debug_sn(cmd); @@ -2817,6 +2821,7 @@ ordered: spin_lock_irqsave(&tgt_dev->sn_lock, flags); tgt_dev->hq_cmd_count++; spin_unlock_irqrestore(&tgt_dev->sn_lock, flags); + cmd->hq_cmd_inced = 1; goto out; default: @@ -2833,6 +2838,7 @@ ordered: cmd->sn_set = 1; out: + TRACE_EXIT(); return; }