summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/tcm_qla2xxx.c
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@cavium.com>2018-05-01 09:01:53 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2018-05-08 00:46:12 -0400
commit84905dfe78d28b597a1c991bfc05722a8fba1184 (patch)
tree51171d8e5653388676053435f302c170e8fdbf25 /drivers/scsi/qla2xxx/tcm_qla2xxx.c
parentfc31b7a803bfe6548a445bd48039b56728d3ac3c (diff)
downloadlinux-84905dfe78d28b597a1c991bfc05722a8fba1184.tar.gz
linux-84905dfe78d28b597a1c991bfc05722a8fba1184.tar.bz2
linux-84905dfe78d28b597a1c991bfc05722a8fba1184.zip
scsi: qla2xxx: Fix TMF and Multi-Queue config
For target mode, task management command is queued to specific cpu base on where the SCSI command is residing. This prevent race condition of task management command getting ahead of regular scsi command. Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/tcm_qla2xxx.c')
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index aadfeaac3898..34ea4a8f98d2 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -630,6 +630,32 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, u64 lun,
transl_tmr_func, GFP_ATOMIC, tag, flags);
}
+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;
+ 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_unlock_irqrestore(&sess->se_sess->sess_cmd_lock, flags);
+
+ return cmd;
+}
+
static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
{
struct qla_tgt_cmd *cmd = container_of(se_cmd,
@@ -1608,6 +1634,7 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
* Calls into tcm_qla2xxx used by qla2xxx LLD I/O path.
*/
static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
+ .find_cmd_by_tag = tcm_qla2xxx_find_cmd_by_tag,
.handle_cmd = tcm_qla2xxx_handle_cmd,
.handle_data = tcm_qla2xxx_handle_data,
.handle_tmr = tcm_qla2xxx_handle_tmr,