@@ -2493,6 +2493,8 @@ enum rscn_addr_format {
int generation;
struct se_session *se_sess;
+ struct list_head sess_cmd_list;
+ spinlock_t sess_cmd_lock;
struct kref sess_kref;
struct qla_tgt *tgt;
unsigned long expires;
@@ -4974,6 +4974,9 @@ void qla2x00_set_fcport_state(fc_port_t *fcport, int state)
INIT_LIST_HEAD(&fcport->gnl_entry);
INIT_LIST_HEAD(&fcport->list);
+ INIT_LIST_HEAD(&fcport->sess_cmd_list);
+ spin_lock_init(&fcport->sess_cmd_lock);
+
return fcport;
}
@@ -4292,6 +4292,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
cmd->cmd_type = TYPE_TGT_CMD;
memcpy(&cmd->atio, atio, sizeof(*atio));
+ INIT_LIST_HEAD(&cmd->sess_cmd_list);
cmd->state = QLA_TGT_STATE_NEW;
cmd->tgt = vha->vha_tgt.qla_tgt;
qlt_incr_num_pend_cmds(vha);
@@ -856,6 +856,7 @@ struct qla_tgt_cmd {
uint8_t cmd_type;
uint8_t pad[7];
struct se_cmd se_cmd;
+ struct list_head sess_cmd_list;
struct fc_port *sess;
struct qla_qpair *qpair;
uint32_t reset_count;
@@ -255,6 +255,7 @@ static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
static void tcm_qla2xxx_complete_free(struct work_struct *work)
{
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+ unsigned long flags;
cmd->cmd_in_wq = 0;
@@ -265,6 +266,10 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
cmd->trc_flags |= TRC_CMD_FREE;
cmd->cmd_sent_to_fw = 0;
+ spin_lock_irqsave(&cmd->sess->sess_cmd_lock, flags);
+ list_del_init(&cmd->sess_cmd_list);
+ spin_unlock_irqrestore(&cmd->sess->sess_cmd_lock, flags);
+
transport_generic_free_cmd(&cmd->se_cmd, 0);
}
@@ -451,13 +456,14 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
struct se_portal_group *se_tpg;
struct tcm_qla2xxx_tpg *tpg;
#endif
- int flags = TARGET_SCF_ACK_KREF;
+ int target_flags = TARGET_SCF_ACK_KREF;
+ unsigned long flags;
if (bidi)
- flags |= TARGET_SCF_BIDI_OP;
+ target_flags |= TARGET_SCF_BIDI_OP;
if (se_cmd->cpuid != WORK_CPU_UNBOUND)
- flags |= TARGET_SCF_USE_CPUID;
+ target_flags |= TARGET_SCF_USE_CPUID;
sess = cmd->sess;
if (!sess) {
@@ -479,11 +485,15 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
return 0;
}
#endif
-
cmd->qpair->tgt_counters.qla_core_sbt_cmd++;
+
+ spin_lock_irqsave(&sess->sess_cmd_lock, flags);
+ list_add_tail(&cmd->sess_cmd_list, &sess->sess_cmd_list);
+ spin_unlock_irqrestore(&sess->sess_cmd_lock, flags);
+
return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
- cmd->unpacked_lun, data_length, fcp_task_attr,
- data_dir, flags);
+ cmd->unpacked_lun, data_length, fcp_task_attr,
+ data_dir, target_flags);
}
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
@@ -617,25 +627,20 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, u64 lun,
static struct qla_tgt_cmd *tcm_qla2xxx_find_cmd_by_tag(struct fc_port *sess,
uint64_t tag)
{
- struct qla_tgt_cmd *cmd = NULL;
- struct se_cmd *secmd;
+ struct qla_tgt_cmd *cmd;
unsigned long flags;
if (!sess->se_sess)
return NULL;
- spin_lock_irqsave(&sess->se_sess->sess_cmd_lock, flags);
- list_for_each_entry(secmd, &sess->se_sess->sess_cmd_list, se_cmd_list) {
- /* skip task management functions, including tmr->task_cmd */
- if (secmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
- continue;
-
- if (secmd->tag == tag) {
- cmd = container_of(secmd, struct qla_tgt_cmd, se_cmd);
- break;
- }
+ spin_lock_irqsave(&sess->sess_cmd_lock, flags);
+ list_for_each_entry(cmd, &sess->sess_cmd_list, sess_cmd_list) {
+ if (cmd->se_cmd.tag == tag)
+ goto done;
}
- spin_unlock_irqrestore(&sess->se_sess->sess_cmd_lock, flags);
+ cmd = NULL;
+done:
+ spin_unlock_irqrestore(&sess->sess_cmd_lock, flags);
return cmd;
}
@@ -765,11 +770,19 @@ static void tcm_qla2xxx_queue_tm_rsp(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, se_cmd);
+ struct qla_tgt_cmd *cmd;
+ unsigned long flags;
- if (qlt_abort_cmd(cmd))
+ if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
return;
+
+ cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+
+ spin_lock_irqsave(&cmd->sess->sess_cmd_lock, flags);
+ list_del_init(&cmd->sess_cmd_list);
+ spin_unlock_irqrestore(&cmd->sess->sess_cmd_lock, flags);
+
+ qlt_abort_cmd(cmd);
}
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,