- Now only sent for execution commands are counted to wait for in TM commands
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 6 Mar 2009 19:01:16 +0000 (19:01 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 6 Mar 2009 19:01:16 +0000 (19:01 +0000)
 - TM debug fixes and cleanups

git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@691 d57e44dd-8a1f-0410-8b47-8ef2f437770f

scst/include/scst.h
scst/src/Makefile
scst/src/scst_lib.c
scst/src/scst_targ.c

index 24a510f..95c7b18 100644 (file)
@@ -360,11 +360,14 @@ 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               2
+#define SCST_CMD_NO_RESP               3
 
 /* Set if the cmd is dead and can be destroyed at any time */
-#define SCST_CMD_CAN_BE_DESTROYED      3
+#define SCST_CMD_CAN_BE_DESTROYED      4
 
 /*************************************************************
  ** Tgt_dev's async. flags (tgt_dev_flags)
@@ -386,10 +389,6 @@ enum scst_exec_context {
 
 #define SCST_TGT_DEV_CLUST_POOL                        11
 
-#ifdef CONFIG_SCST_DEBUG_TM
-#define SCST_TGT_DEV_UNDER_TM_DBG              20
-#endif
-
 /*************************************************************
  ** Name of the entry in /proc
  *************************************************************/
index bd9fe74..6655754 100644 (file)
@@ -128,7 +128,7 @@ EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
 #EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
 
 EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
-#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_TM -UCONFIG_SCST_TM_DBG_GO_OFFLINE
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_TM -DCONFIG_SCST_TM_DBG_GO_OFFLINE
 #EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_RETRY
 #EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_OOM
 #EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_SN
index 021d7ee..8195a31 100644 (file)
@@ -3594,7 +3594,7 @@ static int tm_dbg_passed_cmds_count;
 static int tm_dbg_state;
 static int tm_dbg_on_state_passes;
 static DEFINE_TIMER(tm_dbg_timer, tm_dbg_timer_fn, 0, 0);
-static wait_queue_head_t *tm_dbg_p_cmd_list_waitQ;
+struct scst_tgt_dev *tm_dbg_tgt_dev;
 
 static const int tm_dbg_on_state_num_passes[] = { 5, 1, 0x7ffffff };
 
@@ -3603,29 +3603,35 @@ static void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
 {
        if ((acg_dev->acg == scst_default_acg) && (acg_dev->lun == 0)) {
                unsigned long flags;
+
+               if (tm_dbg_tgt_dev != NULL)
+                       tm_dbg_deinit_tgt_dev(tm_dbg_tgt_dev);
+
                /* Do TM debugging only for LUN 0 */
                spin_lock_irqsave(&scst_tm_dbg_lock, flags);
-               tm_dbg_p_cmd_list_waitQ =
-                       &tgt_dev->dev->p_cmd_lists->cmd_list_waitQ;
                tm_dbg_state = INIT_TM_DBG_STATE;
                tm_dbg_on_state_passes =
                        tm_dbg_on_state_num_passes[tm_dbg_state];
-               __set_bit(SCST_TGT_DEV_UNDER_TM_DBG, &tgt_dev->tgt_dev_flags);
+               tm_dbg_tgt_dev = tgt_dev;
                PRINT_INFO("LUN 0 connected from initiator %s is under "
-                       "TM debugging", tgt_dev->sess->tgt->tgtt->name);
+                       "TM debugging (tgt_dev %p)",
+                       tgt_dev->sess->initiator_name, tgt_dev);
                spin_unlock_irqrestore(&scst_tm_dbg_lock, flags);
        }
+       return;
 }
 
 static void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev)
 {
-       if (test_bit(SCST_TGT_DEV_UNDER_TM_DBG, &tgt_dev->tgt_dev_flags)) {
+       if (tm_dbg_tgt_dev == tgt_dev) {
                unsigned long flags;
+               TRACE_MGMT_DBG("Deinit TM debugging tgt_dev %p", tgt_dev);
                del_timer_sync(&tm_dbg_timer);
                spin_lock_irqsave(&scst_tm_dbg_lock, flags);
-               tm_dbg_p_cmd_list_waitQ = NULL;
+               tm_dbg_tgt_dev = NULL;
                spin_unlock_irqrestore(&scst_tm_dbg_lock, flags);
        }
+       return;
 }
 
 static void tm_dbg_timer_fn(unsigned long arg)
@@ -3634,7 +3640,8 @@ static void tm_dbg_timer_fn(unsigned long arg)
        tm_dbg_flags.tm_dbg_release = 1;
        /* Used to make sure that all woken up threads see the new value */
        smp_wmb();
-       wake_up_all(tm_dbg_p_cmd_list_waitQ);
+       wake_up_all(&tm_dbg_tgt_dev->dev->p_cmd_lists->cmd_list_waitQ);
+       return;
 }
 
 /* Called under scst_tm_dbg_lock and IRQs off */
@@ -3714,8 +3721,7 @@ static void tm_dbg_change_state(void)
                case TM_DBG_STATE_ABORT:
                        TRACE_MGMT_DBG("%s", "Changing "
                            "tm_dbg_state to RESET");
-                       tm_dbg_state =
-                               TM_DBG_STATE_RESET;
+                       tm_dbg_state = TM_DBG_STATE_RESET;
                        tm_dbg_flags.tm_dbg_blocked = 0;
                        break;
                case TM_DBG_STATE_RESET:
@@ -3723,13 +3729,11 @@ static void tm_dbg_change_state(void)
 #ifdef CONFIG_SCST_TM_DBG_GO_OFFLINE
                            TRACE_MGMT_DBG("%s", "Changing "
                                    "tm_dbg_state to OFFLINE");
-                           tm_dbg_state =
-                               TM_DBG_STATE_OFFLINE;
+                           tm_dbg_state = TM_DBG_STATE_OFFLINE;
 #else
                            TRACE_MGMT_DBG("%s", "Changing "
                                    "tm_dbg_state to ABORT");
-                           tm_dbg_state =
-                               TM_DBG_STATE_ABORT;
+                           tm_dbg_state = TM_DBG_STATE_ABORT;
 #endif
                        break;
                default:
@@ -3740,7 +3744,8 @@ static void tm_dbg_change_state(void)
        }
 
        TRACE_MGMT_DBG("%s", "Deleting timer");
-       del_timer(&tm_dbg_timer);
+       del_timer_sync(&tm_dbg_timer);
+       return;
 }
 
 /* No locks */
@@ -3764,8 +3769,7 @@ int tm_dbg_check_cmd(struct scst_cmd *cmd)
                    (tm_dbg_state == TM_DBG_STATE_ABORT))
                        tm_dbg_change_state();
                spin_unlock_irqrestore(&scst_tm_dbg_lock, flags);
-       } else if (cmd->tgt_dev && test_bit(SCST_TGT_DEV_UNDER_TM_DBG,
-                                       &cmd->tgt_dev->tgt_dev_flags)) {
+       } else if (cmd->tgt_dev && (tm_dbg_tgt_dev == cmd->tgt_dev)) {
                /* Delay 50th command */
                spin_lock_irqsave(&scst_tm_dbg_lock, flags);
                if (tm_dbg_flags.tm_dbg_blocked ||
@@ -3816,6 +3820,7 @@ void tm_dbg_release_cmd(struct scst_cmd *cmd)
                }
        }
        spin_unlock_irqrestore(&scst_tm_dbg_lock, flags);
+       return;
 }
 
 /* Might be called under scst_mutex */
@@ -3824,21 +3829,10 @@ void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn, int force)
        unsigned long flags;
 
        if (dev != NULL) {
-               struct scst_tgt_dev *tgt_dev;
-               bool found = 0;
-
-               spin_lock_bh(&dev->dev_lock);
-               list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-                                           dev_tgt_dev_list_entry) {
-                       if (test_bit(SCST_TGT_DEV_UNDER_TM_DBG,
-                                       &tgt_dev->tgt_dev_flags)) {
-                               found = 1;
-                               break;
-                       }
-               }
-               spin_unlock_bh(&dev->dev_lock);
+               if (tm_dbg_tgt_dev == NULL)
+                       goto out;
 
-               if (!found)
+               if (tm_dbg_tgt_dev->dev != dev)
                        goto out;
        }
 
@@ -3853,8 +3847,8 @@ void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn, int force)
                 * value.
                 */
                smp_wmb();
-               if (tm_dbg_p_cmd_list_waitQ != NULL)
-                       wake_up_all(tm_dbg_p_cmd_list_waitQ);
+               if (tm_dbg_tgt_dev != NULL)
+                       wake_up_all(&tm_dbg_tgt_dev->dev->p_cmd_lists->cmd_list_waitQ);
        } else {
                TRACE_MGMT_DBG("%s: while OFFLINE state, doing nothing", fn);
        }
index 224e635..a9bd93c 100644 (file)
@@ -2087,6 +2087,14 @@ static int scst_exec(struct scst_cmd **active_cmd)
                int rc;
 
                cmd->sent_for_exec = 1;
+               /*
+                * To sync with scst_abort_cmd(). The above assignment must
+                * be before SCST_CMD_ABORTED test, done later in
+                * scst_check_local_events(). It's far from here, so the order
+                * is virtually guaranteed, but let's have it just in case.
+                */
+               smp_mb();
+
                cmd->scst_cmd_done = scst_cmd_done_local;
                cmd->state = SCST_CMD_STATE_LOCAL_EXEC;
 
@@ -3657,6 +3665,9 @@ 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;
@@ -3683,6 +3694,7 @@ void scst_done_cmd_mgmt(struct scst_cmd *cmd)
                }
        }
 
+out_unlock:
        spin_unlock_irqrestore(&scst_mcmd_lock, flags);
 
        if (wake)
@@ -3928,9 +3940,11 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
 
                mcmd->cmd_finish_wait_count++;
 
-               if (!cmd->done) {
-                       TRACE_MGMT_DBG("cmd %p (tag %llu) not done yet",
-                                      cmd, (long long unsigned int)cmd->tag);
+               if (cmd->sent_for_exec && !cmd->done) {
+                       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);
                        mcmd->cmd_done_wait_count++;
                }
        }
@@ -4086,6 +4100,8 @@ static int scst_abort_task_set(struct scst_mgmt_cmd *mcmd)
 
        __scst_abort_task_set(mcmd, tgt_dev);
 
+       tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev->dev, "ABORT TASK SET", 0);
+
        scst_unblock_aborted_cmds(0);
 
        scst_call_dev_task_mgmt_fn(mcmd, tgt_dev, 0);
@@ -4169,6 +4185,8 @@ static int scst_clear_task_set(struct scst_mgmt_cmd *mcmd)
                                        &UA_tgt_devs);
        }
 
+       tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev->dev, "CLEAR TASK SET", 0);
+
        scst_unblock_aborted_cmds(1);
 
        mutex_unlock(&scst_mutex);
@@ -4505,6 +4523,10 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd,
                        rc = scst_call_dev_task_mgmt_fn(mcmd, tgt_dev, 0);
                        if (rc < 0 && mcmd->status == SCST_MGMT_STATUS_SUCCESS)
                                mcmd->status = rc;
+
+                       tm_dbg_task_mgmt(tgt_dev->dev, "NEXUS LOSS SESS or "
+                               "ABORT ALL SESS or UNREG SESS",
+                               (mcmd->fn == SCST_UNREG_SESS_TM));
                }
        }
 
@@ -4584,6 +4606,9 @@ static int scst_abort_all_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd,
                                            (mcmd->status == SCST_MGMT_STATUS_SUCCESS))
                                                mcmd->status = rc;
                                }
+
+                               tm_dbg_task_mgmt(tgt_dev->dev, "NEXUS LOSS or "
+                                       "ABORT ALL", 0);
                        }
                }
        }