]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Revert "qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT"
authorNicholas Bellinger <nab@linux-iscsi.org>
Tue, 11 Jul 2017 17:50:00 +0000 (10:50 -0700)
committerNicholas Bellinger <nab@linux-iscsi.org>
Tue, 11 Jul 2017 17:56:38 +0000 (10:56 -0700)
This reverts commit 5f572526a18418258bfa137e3353656c25439500.

As reported by Pascal here:

http://www.spinics.net/lists/target-devel/msg15808.html

there still appears to be another issue related to this change
to drop the original bogus tcm_qla2xxx_free_cmd() usage from
tcm_qla2xxx_handle_data_work() and tcm_qla2xxx_aborted_task().

So revert this for now, until Pascal can verify with further
debug in place to understand what's going on.

Reported-by: Pascal de Bruijn <p.debruijn@unilogic.nl>
Cc: Pascal de Bruijn <p.debruijn@unilogic.nl>
Cc: Himanshu Madhani <himanshu.madhani@cavium.com>
Cc: Quinn Tran <quinn.tran@cavium.com>
Cc: <stable@vger.kernel.org> # 3.10+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla2xxx/qla_target.h
drivers/scsi/qla2xxx/tcm_qla2xxx.c

index 8f8ece9008011ab5c10965d463d9b8df51433ff9..401e245477d4c4c9836c8c55467744f9d7313122 100644 (file)
@@ -4079,8 +4079,6 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
        cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
        memset(cmd, 0, sizeof(struct qla_tgt_cmd));
 
-       init_completion(&cmd->write_pending_abort_comp);
-
        memcpy(&cmd->atio, atio, sizeof(*atio));
        cmd->state = QLA_TGT_STATE_NEW;
        cmd->tgt = vha->vha_tgt.qla_tgt;
@@ -5085,8 +5083,6 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
 
        qlt_incr_num_pend_cmds(vha);
        INIT_LIST_HEAD(&cmd->cmd_list);
-       init_completion(&cmd->write_pending_abort_comp);
-
        memcpy(&cmd->atio, atio, sizeof(*atio));
 
        cmd->tgt = vha->vha_tgt.qla_tgt;
index 939e93c5d3aeff486324c530f75c277530b7c9c2..d64420251194eb5fa634a36699ecf07c69e09edd 100644 (file)
@@ -868,7 +868,6 @@ struct qla_tgt_cmd {
        unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
 
        spinlock_t cmd_lock;
-       struct completion write_pending_abort_comp;
        /* to save extra sess dereferences */
        unsigned int conf_compl_supported:1;
        unsigned int sg_mapped:1;
index 8c1bf9b14bb2f2d66e4e3eceb1bc5dd0fbe1dbeb..75aeb9fdfd06e9a3422c898ae5815ae2b539061e 100644 (file)
@@ -415,7 +415,6 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
 
 static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd)
 {
-       struct qla_tgt_cmd *cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
        unsigned long flags;
        /*
         * Check for WRITE_PENDING status to determine if we need to wait for
@@ -425,7 +424,8 @@ static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd)
        if (se_cmd->t_state == TRANSPORT_WRITE_PENDING ||
            se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
                spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
-               wait_for_completion(&cmd->write_pending_abort_comp);
+               wait_for_completion_timeout(&se_cmd->t_transport_stop_comp,
+                                               50);
                return 0;
        }
        spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
@@ -501,6 +501,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
 static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 {
        struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+       unsigned long flags;
 
        /*
         * Ensure that the complete FCP WRITE payload has been received.
@@ -508,6 +509,17 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
         */
        cmd->cmd_in_wq = 0;
 
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
+       cmd->data_work = 1;
+       if (cmd->aborted) {
+               cmd->data_work_free = 1;
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
+               tcm_qla2xxx_free_cmd(cmd);
+               return;
+       }
+       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+
        cmd->vha->tgt_counters.qla_core_ret_ctio++;
        if (!cmd->write_data_transferred) {
                /*
@@ -515,7 +527,7 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
                 * waiting upon completion in tcm_qla2xxx_write_pending_status()
                 */
                if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
-                       complete(&cmd->write_pending_abort_comp);
+                       complete(&cmd->se_cmd.t_transport_stop_comp);
                        return;
                }
 
@@ -741,13 +753,31 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
        qlt_xmit_tm_rsp(mcmd);
 }
 
+#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
 static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 {
        struct qla_tgt_cmd *cmd = container_of(se_cmd,
                                struct qla_tgt_cmd, se_cmd);
+       unsigned long flags;
 
        if (qlt_abort_cmd(cmd))
                return;
+
+       spin_lock_irqsave(&cmd->cmd_lock, flags);
+       if ((cmd->state == QLA_TGT_STATE_NEW)||
+           ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
+               DATA_WORK_NOT_FREE(cmd))) {
+               cmd->data_work_free = 1;
+               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+               /*
+                * cmd has not reached fw, Use this trigger to free it.
+                */
+               tcm_qla2xxx_free_cmd(cmd);
+               return;
+       }
+       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+       return;
+
 }
 
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,