Revert "qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT"
This reverts commit 5f572526a1
.
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>
This commit is contained in:
parent
daf78c3051
commit
55dd8cf216
@ -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];
|
cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
|
||||||
memset(cmd, 0, sizeof(struct qla_tgt_cmd));
|
memset(cmd, 0, sizeof(struct qla_tgt_cmd));
|
||||||
|
|
||||||
init_completion(&cmd->write_pending_abort_comp);
|
|
||||||
|
|
||||||
memcpy(&cmd->atio, atio, sizeof(*atio));
|
memcpy(&cmd->atio, atio, sizeof(*atio));
|
||||||
cmd->state = QLA_TGT_STATE_NEW;
|
cmd->state = QLA_TGT_STATE_NEW;
|
||||||
cmd->tgt = vha->vha_tgt.qla_tgt;
|
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);
|
qlt_incr_num_pend_cmds(vha);
|
||||||
INIT_LIST_HEAD(&cmd->cmd_list);
|
INIT_LIST_HEAD(&cmd->cmd_list);
|
||||||
init_completion(&cmd->write_pending_abort_comp);
|
|
||||||
|
|
||||||
memcpy(&cmd->atio, atio, sizeof(*atio));
|
memcpy(&cmd->atio, atio, sizeof(*atio));
|
||||||
|
|
||||||
cmd->tgt = vha->vha_tgt.qla_tgt;
|
cmd->tgt = vha->vha_tgt.qla_tgt;
|
||||||
|
@ -868,7 +868,6 @@ struct qla_tgt_cmd {
|
|||||||
unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
|
unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
|
||||||
|
|
||||||
spinlock_t cmd_lock;
|
spinlock_t cmd_lock;
|
||||||
struct completion write_pending_abort_comp;
|
|
||||||
/* to save extra sess dereferences */
|
/* to save extra sess dereferences */
|
||||||
unsigned int conf_compl_supported:1;
|
unsigned int conf_compl_supported:1;
|
||||||
unsigned int sg_mapped:1;
|
unsigned int sg_mapped:1;
|
||||||
|
@ -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)
|
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;
|
unsigned long flags;
|
||||||
/*
|
/*
|
||||||
* Check for WRITE_PENDING status to determine if we need to wait for
|
* 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 ||
|
if (se_cmd->t_state == TRANSPORT_WRITE_PENDING ||
|
||||||
se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
|
se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) {
|
||||||
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
|
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)
|
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, 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.
|
* 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;
|
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++;
|
cmd->vha->tgt_counters.qla_core_ret_ctio++;
|
||||||
if (!cmd->write_data_transferred) {
|
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()
|
* waiting upon completion in tcm_qla2xxx_write_pending_status()
|
||||||
*/
|
*/
|
||||||
if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
|
if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
|
||||||
complete(&cmd->write_pending_abort_comp);
|
complete(&cmd->se_cmd.t_transport_stop_comp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,13 +753,31 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
|
|||||||
qlt_xmit_tm_rsp(mcmd);
|
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)
|
static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct qla_tgt_cmd *cmd = container_of(se_cmd,
|
struct qla_tgt_cmd *cmd = container_of(se_cmd,
|
||||||
struct qla_tgt_cmd, se_cmd);
|
struct qla_tgt_cmd, se_cmd);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (qlt_abort_cmd(cmd))
|
if (qlt_abort_cmd(cmd))
|
||||||
return;
|
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 *,
|
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
|
||||||
|
Loading…
Reference in New Issue
Block a user