Cleanup removing usage of in_atomic(). Particularly, now target drivers and dev handl...
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 31 Oct 2008 10:49:25 +0000 (10:49 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 31 Oct 2008 10:49:25 +0000 (10:49 +0000)
WARNING! This commit changes external SCST interface, so it can break compilation of your out of SCST SVN tree target driver or dev handler. To fix it, simply supply the preferred exection context to scst_cmd_done() and/or scst_tgt_cmd_done().

Thanks to Bart Van Assche <bart.vanassche@gmail.com> for pointing on it.

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

15 files changed:
iscsi-scst/kernel/iscsi.c
mpt/mpt_scst.c
qla2x00t/qla2x00-target/qla2x00t.c
qla_isp/linux/isp_scst.c
scst/include/scst.h
scst/src/dev_handlers/scst_disk.c
scst/src/dev_handlers/scst_modisk.c
scst/src/dev_handlers/scst_tape.c
scst/src/dev_handlers/scst_user.c
scst/src/dev_handlers/scst_vdisk.c
scst/src/scst_lib.c
scst/src/scst_priv.h
scst/src/scst_targ.c
scst_local/scst_local.c
srpt/src/ib_srpt.c

index b7c6a2e..31763f8 100644 (file)
@@ -240,7 +240,8 @@ void cmnd_done(struct iscsi_cmnd *cmnd)
                        switch (cmnd->scst_state) {
                        case ISCSI_CMD_STATE_PROCESSED:
                                TRACE_DBG("cmd %p PROCESSED", cmnd);
-                               scst_tgt_cmd_done(cmnd->scst_cmd);
+                               scst_tgt_cmd_done(cmnd->scst_cmd,
+                                       SCST_CONTEXT_DIRECT);
                                break;
                        case ISCSI_CMD_STATE_AFTER_PREPROC:
                        {
@@ -1148,12 +1149,6 @@ static int iscsi_pre_exec(struct scst_cmd *scst_cmd)
        EXTRACHECKS_BUG_ON(scst_cmd_atomic(scst_cmd));
 
        if (scst_cmd_get_data_direction(scst_cmd) == SCST_DATA_READ) {
-               if (!(req->conn->ddigest_type & DIGEST_NONE))
-                       scst_set_long_xmit(scst_cmd);
-#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
-               else if (cmnd_hdr(req)->data_length > 8*1024)
-                       scst_set_long_xmit(scst_cmd);
-#endif
                EXTRACHECKS_BUG_ON(!list_empty(&req->rx_ddigest_cmd_list));
                goto out;
        }
@@ -2504,8 +2499,7 @@ static void iscsi_preprocessing_done(struct scst_cmd *scst_cmd)
  * upon entrance in this function, because otherwise it could be destroyed
  * inside as a result of iscsi_send(), which releases sent commands.
  */
-static void iscsi_try_local_processing(struct iscsi_conn *conn,
-       bool single_only)
+static void iscsi_try_local_processing(struct iscsi_conn *conn)
 {
        int local;
 
@@ -2532,11 +2526,9 @@ static void iscsi_try_local_processing(struct iscsi_conn *conn,
 
        if (local) {
                int rc = 1;
-               while (test_write_ready(conn)) {
+
+               if (test_write_ready(conn))
                        rc = iscsi_send(conn);
-                       if ((rc <= 0) || single_only)
-                               break;
-               }
 
                spin_lock_bh(&iscsi_wr_lock);
 #ifdef CONFIG_SCST_EXTRACHECKS
@@ -2565,11 +2557,6 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
        u8 *sense = scst_cmd_get_sense_buffer(scst_cmd);
        int sense_len = scst_cmd_get_sense_buffer_len(scst_cmd);
        int old_state = req->scst_state;
-#if 0 /* temp. ToDo */
-       bool single_only = !scst_get_long_xmit(scst_cmd);
-#else
-       bool single_only = 0;
-#endif
 
        if (scst_cmd_atomic(scst_cmd))
                return SCST_TGT_RES_NEED_THREAD_CTX;
@@ -2678,7 +2665,7 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
 
        conn_get_ordered(conn);
        req_cmnd_release(req);
-       iscsi_try_local_processing(conn, single_only);
+       iscsi_try_local_processing(conn);
        conn_put(conn);
 
 out:
index 1853f75..4b284e3 100644 (file)
@@ -280,7 +280,8 @@ static void mpt_on_free_cmd(struct scst_cmd *scst_cmd);
 static void mpt_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd);
 static int mpt_handle_task_mgmt(MPT_STM_PRIV * priv, u32 reply_word,
                int task_mgmt, int lun);
-static int mpt_send_cmd_to_scst(struct mpt_cmd *cmd, int context);
+static int mpt_send_cmd_to_scst(struct mpt_cmd *cmd,
+       enum scst_exec_context context);
 
 static struct scst_tgt_template tgt_template = {
        .name = MYNAM,
@@ -634,7 +635,7 @@ mpt_alloc_session_done(struct scst_session *scst_sess, void *data, int result)
 }
 
 static int
-mpt_send_cmd_to_scst(struct mpt_cmd *cmd, int context)
+mpt_send_cmd_to_scst(struct mpt_cmd *cmd, enum scst_exec_context context)
 {
        int res = 0;
 
@@ -708,14 +709,20 @@ void
 stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
 {
        MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
-       int index;
-       int init_index;
+       int index, init_index;
+       enum scst_exec_context context;
        struct scst_cmd *scst_cmd;
        struct mpt_cmd *cmd;
        volatile int *io_state;
 
        TRACE_ENTRY();
 
+#ifdef DEBUG_WORK_IN_THREAD
+       context = SCST_CONTEXT_THREAD;
+#else
+       context = SCST_CONTEXT_TASKLET;
+#endif
+
        index = GET_IO_INDEX(reply_word);
        init_index = GET_INITIATOR_INDEX(reply_word);
        scst_cmd = priv->scst_cmd[index];
@@ -742,14 +749,10 @@ stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
                  scst_cmd, index, cmd, mpt_state_string[cmd->state]);
 
        if (cmd->state == MPT_STATE_NEED_DATA) {
-               int context = SCST_CONTEXT_TASKLET;
                int rx_status = SCST_RX_STATUS_SUCCESS;
 
                cmd->state = MPT_STATE_DATA_IN;
 
-#ifdef DEBUG_WORK_IN_THREAD
-               context = SCST_CONTEXT_THREAD;
-#endif
                TRACE_DBG("Data received, context %x, rx_status %d",
                                context, rx_status);
 
@@ -804,7 +807,7 @@ stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
                                        atomic_set(&priv->pending_sense[init_index],
                                                MPT_STATUS_SENSE_IDLE);
                                        /* ToDo: check and set scst_set_delivery_status(), if necessary */
-                                       scst_tgt_cmd_done(scst_cmd);
+                                       scst_tgt_cmd_done(scst_cmd, context);
                                        break;
 
                                /* we tried to send status and sense
@@ -815,7 +818,7 @@ stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
                                        atomic_set(&priv->pending_sense[init_index],
                                                MPT_STATUS_SENSE_HANDLE_RQ);
                                        /* ToDo: check and set scst_set_delivery_status(), if necessary */
-                                       scst_tgt_cmd_done(scst_cmd);
+                                       scst_tgt_cmd_done(scst_cmd, context);
                                        break;
 
                                /* we've handled REQUEST_SENSE ourselves and
@@ -834,12 +837,12 @@ stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
                                        /* nothing much to do here, we aren't
                                         * handling cached sense/status */
                                        /* ToDo: check and set scst_set_delivery_status(), if necessary */
-                                       scst_tgt_cmd_done(scst_cmd);
+                                       scst_tgt_cmd_done(scst_cmd, context);
                                        break;
                        }
                } else {
                        /* ToDo: check and set scst_set_delivery_status(), if necessary */
-                       scst_tgt_cmd_done(scst_cmd);
+                       scst_tgt_cmd_done(scst_cmd, context);
                }
 
                goto out;
@@ -1686,7 +1689,7 @@ mpt_xmit_response(struct scst_cmd *scst_cmd)
 
  out_tgt_free:
        /* ToDo: check and set scst_set_delivery_status(), if necessary */
-       scst_tgt_cmd_done(scst_cmd);
+       scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
        goto out;
 }
 
@@ -1769,7 +1772,7 @@ static int mpt_rdy_to_xfer(struct scst_cmd *scst_cmd)
                TRACE_DBG("cmd %p while session %p is shutting down",
                          prm.cmd, sess);
                scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR_FATAL,
-                            SCST_CONTEXT_THREAD);
+                            SCST_CONTEXT_SAME);
                res = SCST_TGT_RES_SUCCESS;
                goto out;
        }
index a0632db..3ef2d10 100644 (file)
@@ -954,9 +954,11 @@ out_unlock:
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        if (do_tgt_cmd_done) {
-               if (!in_interrupt())
+               if (!in_interrupt()) {
                        msleep(250);
-               scst_tgt_cmd_done(cmd->scst_cmd);
+                       scst_tgt_cmd_done(cmd->scst_cmd, SCST_CONTEXT_DIRECT);
+               } else
+                       scst_tgt_cmd_done(cmd->scst_cmd, SCST_CONTEXT_TASKLET);
                /* !! At this point cmd could be already freed !! */
        }
 
@@ -1004,10 +1006,17 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
        struct scst_cmd *scst_cmd;
        struct q2t_cmd *cmd;
        uint16_t loop_id = -1;
+       enum scst_exec_context context;
        int err = 0;
 
        TRACE_ENTRY();
 
+#ifdef CONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
+       context = SCST_CONTEXT_THREAD;
+#else
+       context = SCST_CONTEXT_TASKLET;
+#endif
+
        if (ctio != NULL)
                loop_id = GET_TARGET_ID(ha, ctio);
 
@@ -1109,7 +1118,6 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                }
                goto out_free;
        } else if (cmd->state == Q2T_STATE_NEED_DATA) {
-               int context = SCST_CONTEXT_TASKLET;
                int rx_status = SCST_RX_STATUS_SUCCESS;
 
                cmd->state = Q2T_STATE_DATA_IN;
@@ -1117,10 +1125,6 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                if (status != CTIO_SUCCESS)
                        rx_status = SCST_RX_STATUS_ERROR;
 
-#ifdef CONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
-               context = SCST_CONTEXT_THREAD;
-#endif
-
                TRACE_DBG("Data received, context %x, rx_status %d",
                      context, rx_status);
 
@@ -1148,7 +1152,7 @@ out_free:
                TRACE_MGMT_DBG("%s", "Finishing failed CTIO");
                scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED);
        }
-       scst_tgt_cmd_done(scst_cmd);
+       scst_tgt_cmd_done(scst_cmd, context);
        goto out;
 }
 
@@ -1209,7 +1213,7 @@ static int q2t_do_send_cmd_to_scst(scsi_qla_host_t *ha, struct q2t_cmd *cmd)
        struct q2t_sess *sess = cmd->sess;
        uint16_t lun;
        scst_data_direction dir = SCST_DATA_NONE;
-       int context;
+       enum scst_exec_context context;
 
        TRACE_ENTRY();
 
index f725daa..1355f6c 100644 (file)
@@ -642,7 +642,7 @@ scsi_target_done_cmd(tmd_cmd_t *tmd)
         if (unlikely(xact->td_error)) {
             scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED);
         }
-        scst_tgt_cmd_done(scst_cmd);
+        scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_TASKLET);
         return;
     }
 
@@ -658,7 +658,7 @@ scsi_target_done_cmd(tmd_cmd_t *tmd)
                 if (unlikely(xact->td_error)) {
                     scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED);
                 }
-                scst_tgt_cmd_done(scst_cmd);
+                scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_TASKLET);
             }
         } else {
             ; /* we don't have all data, do nothing */
@@ -669,7 +669,7 @@ scsi_target_done_cmd(tmd_cmd_t *tmd)
         if (unlikely(xact->td_error)) {
             scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED);
         }
-        scst_tgt_cmd_done(scst_cmd);
+        scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_TASKLET);
     } else {
         Eprintk("don't know what to do with TMD_DONE[%llx] cdb0 %x hf %x lf %x xfrlen %d totlen %d moved %d\n",
                 tmd->cd_tagval, tmd->cd_cdb[0], xact->td_hflags, xact->td_lflags, xact->td_xfrlen, tmd->cd_totlen, tmd->cd_moved);
@@ -1106,7 +1106,7 @@ isp_rdy_to_xfer(struct scst_cmd *scst_cmd)
         if (unlikely(bc->enable == 0)) {
             SDprintk("%s: TMD[%llx] Chan %d not enabled\n", __FUNCTION__, tmd->cd_tagval, tmd->cd_channel);
             up_read(&bc->disable_sem);
-            scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR, SCST_CONTEXT_TASKLET);
+            scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR, SCST_CONTEXT_SAME);
             return (0);
         }
 
@@ -1128,7 +1128,7 @@ isp_xmit_response(struct scst_cmd *scst_cmd)
 
     if (unlikely(scst_cmd_aborted(scst_cmd))) {
         scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED);
-        scst_tgt_cmd_done(scst_cmd);
+        scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
         return (0);
     }
 
@@ -1205,7 +1205,7 @@ out:
     if (unlikely(bc->enable == 0)) {
         SDprintk("%s: TMD[%llx] Chan %d not enabled\n", __FUNCTION__, tmd->cd_tagval, tmd->cd_channel);
         up_read(&bc->disable_sem);
-        scst_tgt_cmd_done(scst_cmd);
+        scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
         return (0);
     }
 
index f7c122d..fd4d5ab 100644 (file)
@@ -173,35 +173,40 @@ typedef _Bool bool;
 #define SCST_ATOMIC                  1
 
 /*************************************************************
- ** Values for pref_context parameter of scst_cmd_init_done() and
- ** scst_rx_data()
+ ** Values for pref_context parameter of scst_cmd_init_done(),
+ ** scst_rx_data(), scst_restart_cmd(), scst_tgt_cmd_done()
+ ** and scst_cmd_done()
  *************************************************************/
 
-/*
- * Direct cmd's processing (i.e. regular function calls in the current
- * context) sleeping is not allowed
- */
-#define SCST_CONTEXT_DIRECT_ATOMIC   0
+enum scst_exec_context {
+       /*
+        * Direct cmd's processing (i.e. regular function calls in the current
+        * context) sleeping is not allowed
+        */
+       SCST_CONTEXT_DIRECT_ATOMIC,
 
-/*
- * Direct cmd's processing (i.e. regular function calls in the current
- * context), sleeping is allowed, no restrictions
- */
-#define SCST_CONTEXT_DIRECT          1
+       /*
       * Direct cmd's processing (i.e. regular function calls in the current
       * context), sleeping is allowed, no restrictions
       */
+       SCST_CONTEXT_DIRECT,
 
-/* Tasklet or thread context required for cmd's processing */
-#define SCST_CONTEXT_TASKLET         2
+       /* Tasklet or thread context required for cmd's processing */
+       SCST_CONTEXT_TASKLET,
 
-/* Thread context required for cmd's processing */
-#define SCST_CONTEXT_THREAD          3
+       /* Thread context required for cmd's processing */
+       SCST_CONTEXT_THREAD,
 
-/*
- * SCST internal flag, which specifies that context is processable, i.e. the
- * next command in the active list will be processed after the current one.
- *
- * Target drivers must never use it!!
- */
-#define SCST_CONTEXT_PROCESSABLE     0x100
+       /*
+        * Context is the same as it was in previous call of the corresponding
+        * callback. For example, if dev handler's exec() does sync. data
+        * reading this value should be used for scst_cmd_done(). The same is
+        * true if scst_tgt_cmd_done() called directly from target driver's
+        * xmit_response(). Not allowed in scst_cmd_init_done() and
+        * scst_cmd_init_stage1_done().
+        */
+       SCST_CONTEXT_SAME
+};
 
 /*************************************************************
  ** Values for status parameter of scst_rx_data()
@@ -705,7 +710,10 @@ struct scst_dev_type {
        /* Set, if no /proc files should be automatically created by SCST */
        unsigned no_proc:1;
 
-       /* Set, if exec() is synchronous */
+       /*
+        * Should be set, if exec() is synchronous. This is a hint to SCST core
+        * to optimize commands order management.
+        */
        unsigned exec_sync:1;
 
        /*
@@ -742,8 +750,8 @@ struct scst_dev_type {
         * by scst_cmd_atomic(): it is true if the function called in the
         * atomic (non-sleeping) context.
         *
-        * If this function provides sync execution, you must set above
-        * exec_sync flag and should consider to setup dedicated threads by
+        * If this function provides sync execution, you should set
+        * exec_sync flag and consider to setup dedicated threads by
         * setting threads_num > 0.
         *
         * !! If this function is implemented, scst_check_local_events() !!
@@ -1001,6 +1009,7 @@ struct scst_cmd {
        /*************************************************************
         ** Cmd's flags
         *************************************************************/
+
        /*
         * Set if expected_sn should be incremented, i.e. cmd was sent
         * for execution
@@ -1022,12 +1031,6 @@ struct scst_cmd {
        /* Set if this command contains status */
        unsigned int is_send_status:1;
 
-       /*
-        * Set if the cmd is being processed in the processable context. See
-        * comment for SCST_CONTEXT_PROCESSABLE for what it means.
-        */
-       unsigned int context_processable:1;
-
        /* Set if cmd is being retried */
        unsigned int retry:1;
 
@@ -1110,16 +1113,6 @@ struct scst_cmd {
        /* Set if increment expected_sn in cmd->scst_cmd_done() */
        unsigned int inc_expected_sn_on_done:1;
 
-       /*
-        * Set if xmit_response() is going to need a considerable processing
-        * time. Processing time is considerable, if it's > context switch time
-        * (about 1 usec on modern systems). It's needed to trigger other
-        * threads to start processing other outstanding commands without
-        * waiting XMIT for the current one to finish. E.g., it should be set
-        * if iSCSI data digest used and cmd has READ direction.
-        */
-       unsigned int long_xmit:1;
-
        /* Set if tgt_sn field is valid */
        unsigned int tgt_sn_set:1;
 
@@ -1197,7 +1190,8 @@ struct scst_cmd {
        int data_len;
 
        /* Completition routine */
-       void (*scst_cmd_done) (struct scst_cmd *cmd, int next_state);
+       void (*scst_cmd_done) (struct scst_cmd *cmd, int next_state,
+               enum scst_exec_context pref_context);
 
        struct sgv_pool_obj *sgv;       /* sgv object */
 
@@ -1778,7 +1772,8 @@ struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
  * with multiple connections per session seems to be an exception. For it, some
  * mutex/lock shall be used for the serialization.
  */
-void scst_cmd_init_done(struct scst_cmd *cmd, int pref_context);
+void scst_cmd_init_done(struct scst_cmd *cmd,
+       enum scst_exec_context pref_context);
 
 /*
  * Notifies SCST that the driver finished the first stage of the command
@@ -1790,7 +1785,7 @@ void scst_cmd_init_done(struct scst_cmd *cmd, int pref_context);
  * See also scst_cmd_init_done() comment for the serialization requirements.
  */
 static inline void scst_cmd_init_stage1_done(struct scst_cmd *cmd,
-       int pref_context, int set_sn)
+       enum scst_exec_context pref_context, int set_sn)
 {
        cmd->preprocessing_only = 1;
        cmd->set_sn_on_restart_cmd = !set_sn;
@@ -1807,7 +1802,8 @@ static inline void scst_cmd_init_stage1_done(struct scst_cmd *cmd,
  *
  * See also scst_cmd_init_done() comment for the serialization requirements.
  */
-void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context);
+void scst_restart_cmd(struct scst_cmd *cmd, int status,
+       enum scst_exec_context pref_context);
 
 /*
  * Notifies SCST that the driver received all the necessary data
@@ -1817,15 +1813,18 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context);
  * The third argument sets preferred command execition context
  * (see SCST_CONTEXT_* constants for details)
  */
-void scst_rx_data(struct scst_cmd *cmd, int status, int pref_context);
+void scst_rx_data(struct scst_cmd *cmd, int status,
+       enum scst_exec_context pref_context);
 
 /*
  * Notifies SCST that the driver sent the response and the command
  * can be freed now. Don't forget to set the delivery status, if it
  * isn't success, using scst_set_delivery_status() before calling
- * this function.
+ * this function. The third argument sets preferred command execition
+ * context (see SCST_CONTEXT_* constants for details)
  */
-void scst_tgt_cmd_done(struct scst_cmd *cmd);
+void scst_tgt_cmd_done(struct scst_cmd *cmd,
+       enum scst_exec_context pref_context);
 
 /*
  * Creates new management command sends it for execution.
@@ -2295,24 +2294,6 @@ static inline void scst_set_delivery_status(struct scst_cmd *cmd,
        cmd->delivery_status = delivery_status;
 }
 
-/*
- * Get/set/clear functions for cmd's long XMIT flag.
- */
-static inline int scst_get_long_xmit(struct scst_cmd *cmd)
-{
-       return cmd->long_xmit;
-}
-
-static inline void scst_set_long_xmit(struct scst_cmd *cmd)
-{
-       cmd->long_xmit = 1;
-}
-
-static inline void scst_clear_long_xmit(struct scst_cmd *cmd)
-{
-       cmd->long_xmit = 0;
-}
-
 /*
  * Get/Set function for mgmt cmd's target private data
  */
@@ -2464,11 +2445,9 @@ void scst_resume_activity(void);
 
 /*
  * Main SCST commands processing routing. Must be used only by dev handlers.
- * Argument context sets the execution context, only SCST_CONTEXT_DIRECT and
- * SCST_CONTEXT_DIRECT_ATOMIC with optional SCST_CONTEXT_PROCESSABLE flag
- * are allowed.
+ * Argument atomic is true if function called in atomic context.
  */
-void scst_process_active_cmd(struct scst_cmd *cmd, int context);
+void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic);
 
 /*
  * Checks if command can be executed (reservations, etc.) or there are local
index 4fd9076..e7c5fd6 100644 (file)
@@ -374,7 +374,7 @@ out:
 
 out_done:
        res = SCST_EXEC_COMPLETED;
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        goto out;
 }
 
index 0d8439e..0a24cdc 100644 (file)
@@ -396,7 +396,7 @@ out:
 
 out_done:
        res = SCST_EXEC_COMPLETED;
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        goto out;
 }
 
index 0422e5d..0430c90 100644 (file)
@@ -420,7 +420,7 @@ out:
 
 out_done:
        res = SCST_EXEC_COMPLETED;
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        goto out;
 }
 
index e1c9daa..a2b2d67 100644 (file)
@@ -1148,7 +1148,7 @@ static int dev_user_process_reply_alloc(struct scst_user_cmd *ucmd,
        }
 
 out_process:
-       scst_process_active_cmd(cmd, SCST_CONTEXT_DIRECT);
+       scst_process_active_cmd(cmd, false);
 
        TRACE_EXIT_RES(res);
        return res;
@@ -1196,7 +1196,7 @@ static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd,
        cmd->data_len = preply->data_len;
 
 out_process:
-       scst_process_active_cmd(cmd, SCST_CONTEXT_DIRECT);
+       scst_process_active_cmd(cmd, false);
 
        TRACE_EXIT_RES(res);
        return res;
@@ -1326,7 +1326,7 @@ static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd,
 
 out_compl:
        cmd->completed = 1;
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_DIRECT);
        /* !! At this point cmd can be already freed !! */
 
 out:
@@ -1520,8 +1520,7 @@ static int dev_user_process_scst_commands(struct scst_user_dev *dev)
                TRACE_DBG("Deleting cmd %p from active cmd list", cmd);
                list_del(&cmd->cmd_list_entry);
                spin_unlock_irq(&dev->cmd_lists.cmd_list_lock);
-               scst_process_active_cmd(cmd, SCST_CONTEXT_DIRECT |
-                                                SCST_CONTEXT_PROCESSABLE);
+               scst_process_active_cmd(cmd, false);
                spin_lock_irq(&dev->cmd_lists.cmd_list_lock);
                res++;
        }
@@ -1558,7 +1557,8 @@ again:
                                rc = scst_check_local_events(u->cmd);
                                if (unlikely(rc != 0)) {
                                        u->cmd->scst_cmd_done(u->cmd,
-                                               SCST_CMD_STATE_DEFAULT);
+                                               SCST_CMD_STATE_DEFAULT,
+                                               SCST_CONTEXT_DIRECT);
                                        /*
                                         * !! At this point cmd & u can be !!
                                         * !! already freed                !!
@@ -1884,7 +1884,7 @@ static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy,
 
                TRACE_MGMT_DBG("EXEC: unjamming ucmd %p", ucmd);
 
-               if (test_bit(SCST_CMD_ABORTED,  &ucmd->cmd->cmd_flags))
+               if (test_bit(SCST_CMD_ABORTED, &ucmd->cmd->cmd_flags))
                        ucmd->aborted = 1;
                else {
                        if (busy)
@@ -1894,7 +1894,8 @@ static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy,
                                       SCST_LOAD_SENSE(scst_sense_hardw_error));
                }
 
-               ucmd->cmd->scst_cmd_done(ucmd->cmd, SCST_CMD_STATE_DEFAULT);
+               ucmd->cmd->scst_cmd_done(ucmd->cmd, SCST_CMD_STATE_DEFAULT,
+                       SCST_CONTEXT_DIRECT);
                /* !! At this point cmd and ucmd can be already freed !! */
 
                if (flags != NULL)
index 471a4c3..3ecb03e 100644 (file)
@@ -931,7 +931,8 @@ static int vdisk_do_job(struct scst_cmd *cmd)
                if (immed) {
                        scst_cmd_get(cmd);
                        cmd->completed = 1;
-                       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+                       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
+                               SCST_CONTEXT_SAME);
                        vdisk_fsync(thr, loff, data_len, NULL);
                        /* ToDo: vdisk_fsync() error processing */
                        scst_cmd_put(cmd);
@@ -1000,7 +1001,7 @@ out_compl:
        cmd->completed = 1;
 
 out_done:
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
 
 out_thr:
        if (likely(thr != NULL))
@@ -1104,7 +1105,7 @@ out:
        return res;
 
 out_done:
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        goto out;
 }
 
@@ -2282,9 +2283,10 @@ static inline void blockio_check_finish(struct blockio_work *blockio_work)
        if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
                blockio_work->cmd->completed = 1;
                blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
-                       SCST_CMD_STATE_DEFAULT);
+                       SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_DIRECT_ATOMIC);
                kfree(blockio_work);
        }
+       return;
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
index 9ede835..20eb097 100644 (file)
@@ -2480,7 +2480,6 @@ int scst_obtain_device_parameters(struct scst_device *dev)
 
        TRACE_ENTRY();
 
-       sBUG_ON(in_interrupt() || in_atomic());
        EXTRACHECKS_BUG_ON(dev->scsi_dev == NULL);
 
        for (i = 0; i < 5; i++) {
index 21f8261..391ced3 100644 (file)
@@ -125,22 +125,6 @@ extern unsigned long scst_trace_flag;
 
 #define SCST_TGT_RETRY_TIMEOUT               (3/2*HZ)
 
-static inline int scst_get_context(void)
-{
-       if (in_irq())
-               return SCST_CONTEXT_TASKLET;
-       if (irqs_disabled())
-               return SCST_CONTEXT_THREAD;
-       if (in_softirq() || in_atomic())
-               return SCST_CONTEXT_DIRECT_ATOMIC;
-       return SCST_CONTEXT_DIRECT;
-}
-
-static inline bool scst_is_context_gfp_atomic(void)
-{
-       return  irqs_disabled() || in_atomic() || in_interrupt();
-}
-
 extern unsigned int scst_max_cmd_mem;
 extern unsigned int scst_max_dev_cmd_mem;
 
@@ -246,10 +230,7 @@ static inline void scst_make_deferred_commands_active(
                spin_lock_irq(&c->cmd_lists->cmd_list_lock);
                list_add_tail(&c->cmd_list_entry,
                        &c->cmd_lists->active_cmd_list);
-#if 0 /* temp. ToDo */
-               if (!curr_cmd->context_processable || curr_cmd->long_xmit)
-#endif
-                       wake_up(&c->cmd_lists->cmd_list_waitQ);
+               wake_up(&c->cmd_lists->cmd_list_waitQ);
                spin_unlock_irq(&c->cmd_lists->cmd_list_lock);
        }
 
@@ -316,8 +297,8 @@ static inline void scst_destroy_cmd(struct scst_cmd *cmd)
        return;
 }
 
-void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context,
-       int check_retries);
+void scst_proccess_redirect_cmd(struct scst_cmd *cmd,
+       enum scst_exec_context context, int check_retries);
 void scst_check_retries(struct scst_tgt *tgt);
 void scst_tgt_retry_timer_fn(unsigned long arg);
 
index 48740d9..9afbbbf 100644 (file)
@@ -99,9 +99,13 @@ out:
 }
 EXPORT_SYMBOL(scst_rx_cmd);
 
-static int scst_init_cmd(struct scst_cmd *cmd, int context)
+/*
+ * No locks, but might be on IRQ. Returns 0 on success, <0 if processing of
+ * this command should be stopped.
+ */
+static int scst_init_cmd(struct scst_cmd *cmd, enum scst_exec_context *context)
 {
-       int rc;
+       int rc, res = 0;
 
        TRACE_ENTRY();
 
@@ -122,23 +126,24 @@ static int scst_init_cmd(struct scst_cmd *cmd, int context)
                goto out;
 
        /* Small context optimization */
-       if (((context == SCST_CONTEXT_TASKLET) ||
-            (context == SCST_CONTEXT_DIRECT_ATOMIC)) &&
-           scst_cmd_is_expected_set(cmd)) {
+       if (((*context == SCST_CONTEXT_TASKLET) ||
+            (*context == SCST_CONTEXT_DIRECT_ATOMIC) ||
+            ((*context == SCST_CONTEXT_SAME) && scst_cmd_atomic(cmd))) &&
+             scst_cmd_is_expected_set(cmd)) {
                if (cmd->expected_data_direction == SCST_DATA_WRITE) {
                        if (!test_bit(SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC,
                                        &cmd->tgt_dev->tgt_dev_flags))
-                               context = SCST_CONTEXT_THREAD;
+                               *context = SCST_CONTEXT_THREAD;
                } else {
                        if (!test_bit(SCST_TGT_DEV_AFTER_INIT_OTH_ATOMIC,
                                        &cmd->tgt_dev->tgt_dev_flags))
-                               context = SCST_CONTEXT_THREAD;
+                               *context = SCST_CONTEXT_THREAD;
                }
        }
 
 out:
-       TRACE_EXIT_RES(context);
-       return context;
+       TRACE_EXIT_RES(res);
+       return res;
 
 out_redirect:
        if (cmd->preprocessing_only) {
@@ -146,14 +151,11 @@ out_redirect:
                 * Poor man solution for single threaded targets, where
                 * blocking receiver at least sometimes means blocking all.
                 */
-               sBUG_ON(context != SCST_CONTEXT_DIRECT);
+               sBUG_ON(*context != SCST_CONTEXT_DIRECT);
                scst_set_busy(cmd);
                scst_set_cmd_abnormal_done_state(cmd);
                /* Keep initiator away from too many BUSY commands */
-               if (!in_interrupt() && !in_atomic())
-                       msleep(50);
-               else
-                       WARN_ON_ONCE(1);
+               msleep(50);
        } else {
                unsigned long flags;
                spin_lock_irqsave(&scst_init_lock, flags);
@@ -164,7 +166,7 @@ out_redirect:
                        scst_init_poll_cnt++;
                spin_unlock_irqrestore(&scst_init_lock, flags);
                wake_up(&scst_init_cmd_list_waitQ);
-               context = -1;
+               res = -1;
        }
        goto out;
 }
@@ -176,10 +178,12 @@ static inline uint64_t scst_sec_to_nsec(time_t sec)
 }
 #endif
 
-void scst_cmd_init_done(struct scst_cmd *cmd, int pref_context)
+void scst_cmd_init_done(struct scst_cmd *cmd,
+       enum scst_exec_context pref_context)
 {
        unsigned long flags;
        struct scst_session *sess = cmd->sess;
+       int rc;
 
        TRACE_ENTRY();
 
@@ -276,8 +280,8 @@ void scst_cmd_init_done(struct scst_cmd *cmd, int pref_context)
 
        cmd->state = SCST_CMD_STATE_INIT;
        /* cmd must be inited here to preserve the order */
-       pref_context = scst_init_cmd(cmd, pref_context);
-       if (unlikely(pref_context < 0))
+       rc = scst_init_cmd(cmd, &pref_context);
+       if (unlikely(rc < 0))
                goto out;
 
 active:
@@ -288,8 +292,12 @@ active:
                break;
 
        case SCST_CONTEXT_DIRECT:
+               scst_process_active_cmd(cmd, false);
+               /* For *NEED_THREAD wake_up() is already done */
+               break;
+
        case SCST_CONTEXT_DIRECT_ATOMIC:
-               scst_process_active_cmd(cmd, pref_context);
+               scst_process_active_cmd(cmd, true);
                /* For *NEED_THREAD wake_up() is already done */
                break;
 
@@ -772,7 +780,8 @@ out_error:
        goto out;
 }
 
-void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context)
+void scst_restart_cmd(struct scst_cmd *cmd, int status, 
+       enum scst_exec_context pref_context)
 {
        TRACE_ENTRY();
 
@@ -805,7 +814,9 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context)
                        scst_cmd_set_sn(cmd);
                /* Small context optimization */
                if ((pref_context == SCST_CONTEXT_TASKLET) ||
-                   (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)) {
+                   (pref_context == SCST_CONTEXT_DIRECT_ATOMIC) ||
+                   ((pref_context == SCST_CONTEXT_SAME) &&
+                    scst_cmd_atomic(cmd))) {
                        if (cmd->data_direction == SCST_DATA_WRITE) {
                                if (!test_bit(SCST_TGT_DEV_AFTER_RESTART_WR_ATOMIC,
                                                &cmd->tgt_dev->tgt_dev_flags))
@@ -976,8 +987,8 @@ out_dev_done:
 }
 
 /* No locks, but might be in IRQ */
-void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context,
-       int check_retries)
+void scst_proccess_redirect_cmd(struct scst_cmd *cmd,
+       enum scst_exec_context context, int check_retries)
 {
        unsigned long flags;
 
@@ -985,14 +996,19 @@ void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context,
 
        TRACE_DBG("Context: %x", context);
 
-       switch (context & ~SCST_CONTEXT_PROCESSABLE) {
+       if (context == SCST_CONTEXT_SAME)
+               context = scst_cmd_atomic(cmd) ? SCST_CONTEXT_DIRECT_ATOMIC :
+                                                SCST_CONTEXT_DIRECT;
+
+       switch (context) {
        case SCST_CONTEXT_DIRECT_ATOMIC:
-               context &= ~SCST_CONTEXT_PROCESSABLE;
-               /* go through */
+               scst_process_active_cmd(cmd, true);
+               break;
+
        case SCST_CONTEXT_DIRECT:
                if (check_retries)
                        scst_check_retries(cmd->tgt);
-               scst_process_active_cmd(cmd, context);
+               scst_process_active_cmd(cmd, false);
                break;
 
        default:
@@ -1025,7 +1041,8 @@ void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context,
        return;
 }
 
-void scst_rx_data(struct scst_cmd *cmd, int status, int pref_context)
+void scst_rx_data(struct scst_cmd *cmd, int status,
+       enum scst_exec_context pref_context)
 {
        TRACE_ENTRY();
 
@@ -1049,7 +1066,9 @@ void scst_rx_data(struct scst_cmd *cmd, int status, int pref_context)
                cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
                /* Small context optimization */
                if ((pref_context == SCST_CONTEXT_TASKLET) ||
-                   (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)) {
+                   (pref_context == SCST_CONTEXT_DIRECT_ATOMIC) ||
+                   ((pref_context == SCST_CONTEXT_SAME) &&
+                    scst_cmd_atomic(cmd))) {
                        if (!test_bit(SCST_TGT_DEV_AFTER_RX_DATA_ATOMIC,
                                        &cmd->tgt_dev->tgt_dev_flags))
                                pref_context = SCST_CONTEXT_THREAD;
@@ -1165,8 +1184,7 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
                cmd->dbl_ua_orig_resp_data_len = cmd->resp_data_len;
                cmd->dbl_ua_orig_data_direction = cmd->data_direction;
 
-               scst_alloc_set_sense(cmd, scst_is_context_gfp_atomic(),
-                                       rq_sense, rq_sense_len);
+               scst_alloc_set_sense(cmd, 1, rq_sense, rq_sense_len);
        }
 
        TRACE(TRACE_SCSI, "cmd%p, result=%x, cmd->status=%x, resid=%d, "
@@ -1181,10 +1199,11 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
 }
 
 /* For small context optimization */
-static inline int scst_optimize_post_exec_context(struct scst_cmd *cmd,
-       int context)
+static inline enum scst_exec_context scst_optimize_post_exec_context(
+       struct scst_cmd *cmd, enum scst_exec_context context)
 {
-       if ((context == SCST_CONTEXT_TASKLET) ||
+       if (((context == SCST_CONTEXT_SAME) && scst_cmd_atomic(cmd)) ||
+           (context == SCST_CONTEXT_TASKLET) ||
            (context == SCST_CONTEXT_DIRECT_ATOMIC)) {
                if (!test_bit(SCST_TGT_DEV_AFTER_EXEC_ATOMIC,
                                &cmd->tgt_dev->tgt_dev_flags))
@@ -1215,6 +1234,7 @@ static void scst_cmd_done(struct scsi_cmnd *scsi_cmd)
 {
        struct scsi_request *req = NULL;
        struct scst_cmd *cmd;
+       enum scst_exec_context context;
 
        TRACE_ENTRY();
 
@@ -1237,8 +1257,15 @@ static void scst_cmd_done(struct scsi_cmnd *scsi_cmd)
 
        cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
 
+       if (in_irq())
+               context = SCST_CONTEXT_TASKLET;
+       else if (irqs_disabled())
+               context = SCST_CONTEXT_THREAD;
+       else
+               context = SCST_CONTEXT_DIRECT_ATOMIC;
+
        scst_proccess_redirect_cmd(cmd,
-               scst_optimize_post_exec_context(cmd, scst_get_context()), 0);
+               scst_optimize_post_exec_context(cmd, context), 0);
 
 out:
        TRACE_EXIT();
@@ -1248,6 +1275,7 @@ out:
 static void scst_cmd_done(void *data, char *sense, int result, int resid)
 {
        struct scst_cmd *cmd;
+       enum scst_exec_context context;
 
        TRACE_ENTRY();
 
@@ -1259,8 +1287,15 @@ static void scst_cmd_done(void *data, char *sense, int result, int resid)
 
        cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
 
+       if (in_irq())
+               context = SCST_CONTEXT_TASKLET;
+       else if (irqs_disabled())
+               context = SCST_CONTEXT_THREAD;
+       else
+               context = SCST_CONTEXT_DIRECT_ATOMIC;
+
        scst_proccess_redirect_cmd(cmd,
-               scst_optimize_post_exec_context(cmd, scst_get_context()), 0);
+               scst_optimize_post_exec_context(cmd, context), 0);
 
 out:
        TRACE_EXIT();
@@ -1268,10 +1303,9 @@ out:
 }
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) */
 
-static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state)
+static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
+       enum scst_exec_context pref_context)
 {
-       int context;
-
        TRACE_ENTRY();
 
 #ifdef CONFIG_SCST_MEASURE_LATENCY
@@ -1317,10 +1351,8 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state)
                scst_set_cmd_abnormal_done_state(cmd);
        }
 #endif
-       context = scst_optimize_post_exec_context(cmd, scst_get_context());
-       if (cmd->context_processable)
-               context |= SCST_CONTEXT_PROCESSABLE;
-       scst_proccess_redirect_cmd(cmd, context, 0);
+       pref_context = scst_optimize_post_exec_context(cmd, pref_context);
+       scst_proccess_redirect_cmd(cmd, pref_context, 0);
 
        TRACE_EXIT();
        return;
@@ -1427,7 +1459,7 @@ out_compl:
 
 out_done:
        /* Report the result */
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
 
        TRACE_EXIT();
        return SCST_EXEC_COMPLETED;
@@ -1520,7 +1552,7 @@ out:
 
 out_done:
        /* Report the result */
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        res = SCST_EXEC_COMPLETED;
        goto out;
 }
@@ -1583,7 +1615,7 @@ out:
 out_done:
        res = SCST_EXEC_COMPLETED;
        /* Report the result */
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        goto out;
 }
 
@@ -1764,9 +1796,6 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
 
        cmd->state = SCST_CMD_STATE_REAL_EXECUTING;
 
-       if (!handler->exec_sync)
-               cmd->context_processable = 0;
-
        if (handler->exec) {
                if (unlikely(!dev->handler->exec_atomic &&
                             scst_cmd_atomic(cmd))) {
@@ -1876,7 +1905,7 @@ out_busy:
 out_done:
        res = SCST_EXEC_COMPLETED;
        /* Report the result */
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        goto out_complete;
 }
 
@@ -1966,7 +1995,7 @@ out:
 
 out_done:
        /* Report the result */
-       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
+       cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
        res = SCST_EXEC_COMPLETED;
        goto out;
 }
@@ -2794,14 +2823,15 @@ out_error:
        goto out;
 }
 
-void scst_tgt_cmd_done(struct scst_cmd *cmd)
+void scst_tgt_cmd_done(struct scst_cmd *cmd,
+       enum scst_exec_context pref_context)
 {
        TRACE_ENTRY();
 
        sBUG_ON(cmd->state != SCST_CMD_STATE_XMIT_WAIT);
 
        cmd->state = SCST_CMD_STATE_FINISHED;
-       scst_proccess_redirect_cmd(cmd, scst_get_context(), 1);
+       scst_proccess_redirect_cmd(cmd, pref_context, 1);
 
        TRACE_EXIT();
        return;
@@ -3238,7 +3268,7 @@ int scst_init_cmd_thread(void *arg)
 }
 
 /* Called with no locks held */
-void scst_process_active_cmd(struct scst_cmd *cmd, int context)
+void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
 {
        int res;
 
@@ -3246,12 +3276,9 @@ void scst_process_active_cmd(struct scst_cmd *cmd, int context)
 
        EXTRACHECKS_BUG_ON(in_irq());
 
-       cmd->context_processable = context | SCST_CONTEXT_PROCESSABLE;
-       context &= ~SCST_CONTEXT_PROCESSABLE;
-       cmd->atomic = (context == SCST_CONTEXT_DIRECT_ATOMIC);
+       cmd->atomic = atomic;
 
-       TRACE_DBG("cmd %p, context_processable %d, atomic %d", cmd,
-               cmd->context_processable, cmd->atomic);
+       TRACE_DBG("cmd %p, atomic %d", cmd, atomic);
 
        do {
                switch (cmd->state) {
@@ -3397,25 +3424,17 @@ EXPORT_SYMBOL(scst_process_active_cmd);
 
 /* Called under cmd_list_lock and IRQs disabled */
 static void scst_do_job_active(struct list_head *cmd_list,
-       spinlock_t *cmd_list_lock, int context)
+       spinlock_t *cmd_list_lock, bool atomic)
 {
        TRACE_ENTRY();
 
-#ifdef CONFIG_SCST_EXTRACHECKS
-       {
-               int c = context & ~SCST_CONTEXT_PROCESSABLE;
-               sBUG_ON((c != SCST_CONTEXT_DIRECT_ATOMIC) &&
-                       (c != SCST_CONTEXT_DIRECT));
-       }
-#endif
-
        while (!list_empty(cmd_list)) {
                struct scst_cmd *cmd = list_entry(cmd_list->next, typeof(*cmd),
                                        cmd_list_entry);
                TRACE_DBG("Deleting cmd %p from active cmd list", cmd);
                list_del(&cmd->cmd_list_entry);
                spin_unlock_irq(cmd_list_lock);
-               scst_process_active_cmd(cmd, context);
+               scst_process_active_cmd(cmd, atomic);
                spin_lock_irq(cmd_list_lock);
        }
 
@@ -3471,8 +3490,7 @@ int scst_cmd_thread(void *arg)
                }
 
                scst_do_job_active(&p_cmd_lists->active_cmd_list,
-                       &p_cmd_lists->cmd_list_lock, SCST_CONTEXT_DIRECT |
-                                               SCST_CONTEXT_PROCESSABLE);
+                       &p_cmd_lists->cmd_list_lock, false);
        }
        spin_unlock_irq(&p_cmd_lists->cmd_list_lock);
 
@@ -3501,8 +3519,7 @@ void scst_cmd_tasklet(long p)
        TRACE_ENTRY();
 
        spin_lock_irq(&t->tasklet_lock);
-       scst_do_job_active(&t->tasklet_cmd_list, &t->tasklet_lock,
-               SCST_CONTEXT_DIRECT_ATOMIC);
+       scst_do_job_active(&t->tasklet_cmd_list, &t->tasklet_lock, true);
        spin_unlock_irq(&t->tasklet_lock);
 
        TRACE_EXIT();
index d7ab5f8..af0e8ac 100644 (file)
@@ -928,7 +928,7 @@ static int scst_local_targ_xmit_response(struct scst_cmd *scst_cmd)
 
        if (unlikely(scst_cmd_aborted(scst_cmd))) {
                scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED);
-               scst_tgt_cmd_done(scst_cmd);
+               scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
                printk(KERN_INFO "%s aborted command handled\n", __func__);
                return SCST_TGT_RES_SUCCESS;
        }
@@ -947,7 +947,7 @@ static int scst_local_targ_xmit_response(struct scst_cmd *scst_cmd)
        /*
         * Now tell SCST that the command is done ...
         */
-       scst_tgt_cmd_done(scst_cmd);
+       scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
 
        TRACE_EXIT();
 
index f534179..998fef4 100644 (file)
@@ -654,7 +654,8 @@ static void srpt_handle_err_comp(struct srpt_rdma_ch *ch, struct ib_wc *wc)
                        dir = scst_cmd_get_data_direction(scmnd);
 
                        if (dir == SCST_DATA_NONE)
-                               scst_tgt_cmd_done(scmnd);
+                               scst_tgt_cmd_done(scmnd,
+                                       SCST_CONTEXT_DIRECT_ATOMIC);
                        else {
                                dma_unmap_sg(sdev->device->dma_device,
                                             scst_cmd_get_sg(scmnd),
@@ -674,7 +675,8 @@ static void srpt_handle_err_comp(struct srpt_rdma_ch *ch, struct ib_wc *wc)
                                                     SCST_CONTEXT_THREAD);
                                else if (scmnd->state ==
                                         SCST_CMD_STATE_XMIT_WAIT)
-                                       scst_tgt_cmd_done(scmnd);
+                                       scst_tgt_cmd_done(scmnd,
+                                               SCST_CONTEXT_DIRECT_ATOMIC);
                        }
                } else
                        srpt_reset_ioctx(ch, ioctx);
@@ -683,7 +685,8 @@ static void srpt_handle_err_comp(struct srpt_rdma_ch *ch, struct ib_wc *wc)
 }
 
 static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
-                                 struct srpt_ioctx *ioctx)
+                                 struct srpt_ioctx *ioctx,
+                                 enum scst_exec_context context)
 {
        if (ioctx->scmnd) {
                scst_data_direction dir =
@@ -702,7 +705,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
                        ioctx->scmnd->sg_cnt = 0;
                }
 
-               scst_tgt_cmd_done(ioctx->scmnd);
+               scst_tgt_cmd_done(ioctx->scmnd, context);
        } else
                srpt_reset_ioctx(ch, ioctx);
 }
@@ -1041,7 +1044,8 @@ static void srpt_completion(struct ib_cq *cq, void *ctx)
                } else {
                        switch (wc.opcode) {
                        case IB_WC_SEND:
-                               srpt_handle_send_comp(ch, ioctx);
+                               srpt_handle_send_comp(ch, ioctx,
+                                       SCST_CONTEXT_DIRECT_ATOMIC);
                                break;
                        case IB_WC_RDMA_WRITE:
                        case IB_WC_RDMA_READ:
@@ -1833,11 +1837,8 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
                else if (ch->state == RDMA_CHANNEL_CONNECTING)
                        ret = SCST_TGT_RES_QUEUE_FULL;
 
-               if (unlikely(scst_cmd_aborted(scmnd))) {
-                       scst_set_delivery_status(scmnd,
-                                                SCST_CMD_DELIVERY_ABORTED);
-                       ret = SCST_TGT_RES_SUCCESS;
-               }
+               if (unlikely(scst_cmd_aborted(scmnd)))
+                       goto out_aborted;
 
                goto out;
        }
@@ -1851,10 +1852,7 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
                printk(KERN_ERR PFX
                       "%s: tag= %lld already get aborted\n",
                       __func__, (unsigned long long)tag);
-               scst_set_delivery_status(ioctx->scmnd,
-                                        SCST_CMD_DELIVERY_ABORTED);
-               scst_tgt_cmd_done(ioctx->scmnd);
-               goto out;
+               goto out_aborted;
        }
 
        dir = scst_cmd_get_data_direction(scmnd);
@@ -1903,6 +1901,12 @@ static int srpt_xmit_response(struct scst_cmd *scmnd)
 
 out:
        return ret;
+
+out_aborted:
+       ret = SCST_TGT_RES_SUCCESS;
+       scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED);
+       scst_tgt_cmd_done(scmnd, SCST_CONTEXT_SAME);
+       goto out;
 }
 
 static void srpt_tsk_mgmt_done(struct scst_mgmt_cmd *mcmnd)
@@ -2070,7 +2074,8 @@ static int srpt_ioctx_thread(void *arg)
                        spin_unlock_irq(&srpt_thread.thread_lock);
                        switch (ioctx->op) {
                        case IB_WC_SEND:
-                               srpt_handle_send_comp(ioctx->ch, ioctx);
+                               srpt_handle_send_comp(ioctx->ch, ioctx,
+                                       SCST_CONTEXT_DIRECT);
                                break;
                        case IB_WC_RDMA_WRITE:
                        case IB_WC_RDMA_READ: