Discussion:
[PATCH 00/19] qla2xxx/target: Target bug fixes and enchancements.
Saurav Kashyap
2014-09-25 08:09:53 UTC
Permalink
Hi Nicholas/Christoph,

Please apply the following patches at your earliest convenience.

Thanks,
~Saurav

Arun Easi (6):
qla2xxx: Use correct offset to req-q-out for reserve calculation
qla2xxx: Remove verbose messages in target mode.
qla2xxx: Enable SLER conditionally in target mode.
qla2xxx: Add Host reset handling in target mode.
qla2xxx: Handle chip reset in target mode.
qla2xxx: Host reset handling in ABTS path.

Himanshu Madhani (6):
qla2xxx: Fix sparse warnings in tcm_qla2xxx.c
qla2xxx: fix kernel NULL pointer access
qla2xxx: Increase room in request queue for sending priority packets
qla2xxx: fix crash due to task mgmt cmd type
qla2xxx: Do not send SS_RESIDUAL_UNDER with SAM_STAT_BUSY
qla2xxx: Add memory barrier before ringing doorbell.

Quinn Tran (3):
qla2xxx: Add support for QFull throttling and Term Exchange retry
qla2xxx: Fix hang due to cmd_kref not decrementing
Target/transport: SCSI Status Respond being sent to Initiator twice.

Saurav Kashyap (4):
qla2xxx: Add counter for message
qla2xxx: Increase the request queue size to 8K for ISP2031
qla2xxx: Add flags for tracing the target commands.
target: Implement report lun data change unit attention.

drivers/scsi/qla2xxx/qla_dbg.c | 6 +-
drivers/scsi/qla2xxx/qla_def.h | 19 +
drivers/scsi/qla2xxx/qla_gbl.h | 2 +
drivers/scsi/qla2xxx/qla_init.c | 4 +
drivers/scsi/qla2xxx/qla_iocb.c | 15 +-
drivers/scsi/qla2xxx/qla_os.c | 6 +-
drivers/scsi/qla2xxx/qla_target.c | 686 +++++++++++++++++++-------
drivers/scsi/qla2xxx/qla_target.h | 31 ++
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 45 ++-
drivers/target/target_core_fabric_configfs.c | 28 +
drivers/target/target_core_transport.c | 3 +-
11 files changed, 648 insertions(+), 197 deletions(-)
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:09:54 UTC
Permalink
From: Himanshu Madhani <***@qlogic.com>

Signed-off-by: Himanshu Madhani <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index e2beab9..09d2931 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -50,8 +50,12 @@
#include "qla_target.h"
#include "tcm_qla2xxx.h"

-struct workqueue_struct *tcm_qla2xxx_free_wq;
-struct workqueue_struct *tcm_qla2xxx_cmd_wq;
+static struct workqueue_struct *tcm_qla2xxx_free_wq;
+static struct workqueue_struct *tcm_qla2xxx_cmd_wq;
+
+/* Local pointer to allocated TCM configfs fabric module */
+static struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
+static struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;

/*
* Parse WWN.
@@ -734,10 +738,6 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
cmd->sg_mapped = 0;
}

-/* Local pointer to allocated TCM configfs fabric module */
-struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
-struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
-
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *);
/*
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:09:59 UTC
Permalink
This post might be inappropriate. Click to display it.
Christoph Hellwig
2014-09-25 10:14:20 UTC
Permalink
Post by Saurav Kashyap
Sequence level error recovery (aka FC Tape) is not really required
for disk devices. On heavily loaded system, with slow turn around,
a bunch of status enquiries using REC puts additional burden to the
target, so just turn off SLER by default.
I don't think a new compile time flag for this is a good idea. I can
put this in under the assumption that it will basically #if 0 out the
code, but a module or sysfs parameter would be more useful if your
intent is that users ever enable it.
Saurav Kashyap
2014-09-25 10:25:24 UTC
Permalink
Hi Christoph,
Thanks for the feedback. Let me make necessary changes and resubmit the
patch set. As suggested by you, I will also do the separate submission for
qla2xxx and tcm-lio.

Thanks,
~Saurav
Post by Christoph Hellwig
Post by Saurav Kashyap
Sequence level error recovery (aka FC Tape) is not really required
for disk devices. On heavily loaded system, with slow turn around,
a bunch of status enquiries using REC puts additional burden to the
target, so just turn off SLER by default.
I don't think a new compile time flag for this is a good idea. I can
put this in under the assumption that it will basically #if 0 out the
code, but a module or sysfs parameter would be more useful if your
intent is that users ever enable it.
Saurav Kashyap
2014-09-25 08:10:03 UTC
Permalink
From: Arun Easi <***@qlogic.com>

A chip reset can occur after driver submits command to the stack. Abort
command processing if a chip reset has occurred or in progress when you
get a follow up for a command.

Signed-off-by: Arun Easi <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_def.h | 1 +
drivers/scsi/qla2xxx/qla_gbl.h | 1 +
drivers/scsi/qla2xxx/qla_init.c | 4 ++
drivers/scsi/qla2xxx/qla_iocb.c | 11 +++++++
drivers/scsi/qla2xxx/qla_target.c | 56 +++++++++++++++++++++++++++++++++++--
drivers/scsi/qla2xxx/qla_target.h | 2 +
6 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 509dbd5..c9fe4cf 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3446,6 +3446,7 @@ struct qla_hw_data {
struct work_struct board_disable;

struct mr_data_fx00 mr;
+ uint32_t chip_reset;

struct qlt_hw_data tgt;
int allow_cna_fw_dump;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 8257a27..13591de 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -72,6 +72,7 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
+extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *);
extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);

extern fc_port_t *
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 1d66f2f..a4dde7e 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -4575,6 +4575,10 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
/* Requeue all commands in outstanding command list. */
qla2x00_abort_all_cmds(vha, DID_RESET << 16);
}
+
+ ha->chip_reset++;
+ /* memory barrier */
+ wmb();
}

/*
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index c787847..f0edb07 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1858,6 +1858,17 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
}

/* Generic Control-SRB manipulation functions. */
+
+/* hardware_lock assumed to be held. */
+void *
+qla2x00_alloc_iocbs_ready(scsi_qla_host_t *vha, srb_t *sp)
+{
+ if (qla2x00_reset_active(vha))
+ return NULL;
+
+ return qla2x00_alloc_iocbs(vha, sp);
+}
+
void *
qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
{
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index edd9d1b..25af5b7 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -101,6 +101,8 @@ static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
*cmd, struct atio_from_isp *atio, int ha_locked);
static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
struct qla_tgt_srr_imm *imm, int ha_lock);
+static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
+ struct qla_tgt_cmd *cmd);
/*
* Global Variables
*/
@@ -1031,7 +1033,7 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
return;

- resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs(vha, NULL);
+ resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
if (!resp) {
ql_dbg(ql_dbg_tgt, vha, 0xe04a,
"qla_target(%d): %s failed: unable to allocate "
@@ -1102,7 +1104,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
return;

- ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL);
+ ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
if (ctio == NULL) {
ql_dbg(ql_dbg_tgt, vha, 0xe04b,
"qla_target(%d): %s failed: unable to allocate "
@@ -1321,6 +1323,21 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
mcmd, mcmd->fc_tm_rsp, mcmd->flags);

spin_lock_irqsave(&ha->hardware_lock, flags);
+
+ if (qla2x00_reset_active(vha) || mcmd->reset_count != ha->chip_reset) {
+ /*
+ * Either a chip reset is active or this request was from
+ * previous life, just abort the processing.
+ */
+ ql_dbg(ql_dbg_async, vha, 0xe100,
+ "RESET-TMR active/old-count/new-count = %d/%d/%d.\n",
+ qla2x00_reset_active(vha), mcmd->reset_count,
+ ha->chip_reset);
+ ha->tgt.tgt_ops->free_mcmd(mcmd);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ return;
+ }
+
if (mcmd->flags == QLA24XX_MGMT_SEND_NACK)
qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy,
0, 0, 0, 0, 0, 0);
@@ -2264,6 +2281,21 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,

spin_lock_irqsave(&ha->hardware_lock, flags);

+ if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
+ /*
+ * Either a chip reset is active or this request was from
+ * previous life, just abort the processing.
+ */
+ cmd->state = QLA_TGT_STATE_PROCESSED;
+ qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
+ ql_dbg(ql_dbg_async, vha, 0xe101,
+ "RESET-RSP active/old-count/new-count = %d/%d/%d.\n",
+ qla2x00_reset_active(vha), cmd->reset_count,
+ ha->chip_reset);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ return 0;
+ }
+
/* Does F/W have an IOCBs for this request */
res = qlt_check_reserve_free_req(vha, full_req_cnt);
if (unlikely(res))
@@ -2387,6 +2419,21 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)

spin_lock_irqsave(&ha->hardware_lock, flags);

+ if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
+ /*
+ * Either a chip reset is active or this request was from
+ * previous life, just abort the processing.
+ */
+ cmd->state = QLA_TGT_STATE_NEED_DATA;
+ qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
+ ql_dbg(ql_dbg_async, vha, 0xe102,
+ "RESET-XFR active/old-count/new-count = %d/%d/%d.\n",
+ qla2x00_reset_active(vha), cmd->reset_count,
+ ha->chip_reset);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ return 0;
+ }
+
/* Does F/W have an IOCBs for this request */
res = qlt_check_reserve_free_req(vha, prm.req_cnt);
if (res != 0)
@@ -2572,7 +2619,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,

ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha);

- pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
+ pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL);
if (pkt == NULL) {
ql_dbg(ql_dbg_tgt, vha, 0xe050,
"qla_target(%d): %s failed: unable to allocate "
@@ -3300,6 +3347,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
return -ENOMEM;
}

+ cmd->reset_count = vha->hw->chip_reset;
+
INIT_WORK(&cmd->work, qlt_do_work);
queue_work(qla_tgt_wq, &cmd->work);
return 0;
@@ -3333,6 +3382,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
}
mcmd->tmr_func = fn;
mcmd->flags = flags;
+ mcmd->reset_count = vha->hw->chip_reset;

switch (fn) {
case QLA_TGT_CLEAR_ACA:
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index d1d24fb..20e42bd 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -923,6 +923,7 @@ struct qla_tgt_cmd {
uint32_t tag;
uint32_t unpacked_lun;
enum dma_data_direction dma_data_direction;
+ uint32_t reset_count;

uint16_t loop_id; /* to save extra sess dereferences */
struct qla_tgt *tgt; /* to save extra sess dereferences */
@@ -958,6 +959,7 @@ struct qla_tgt_mgmt_cmd {
struct se_cmd se_cmd;
struct work_struct free_work;
unsigned int flags;
+ uint32_t reset_count;
#define QLA24XX_MGMT_SEND_NACK 1
union {
struct atio_from_isp atio;
--
1.7.7
Saurav Kashyap
2014-09-25 08:09:56 UTC
Permalink
From: Arun Easi <***@qlogic.com>

Cc: <***@vger.kernel.org>
Signed-off-by: Arun Easi <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index e44fcb5..bcc449a 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1431,12 +1431,10 @@ static inline void qlt_unmap_sg(struct scsi_qla_host *vha,
static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
uint32_t req_cnt)
{
- struct qla_hw_data *ha = vha->hw;
- device_reg_t __iomem *reg = ha->iobase;
uint32_t cnt;

if (vha->req->cnt < (req_cnt + 2)) {
- cnt = (uint16_t)RD_REG_DWORD(&reg->isp24.req_q_out);
+ cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);

ql_dbg(ql_dbg_tgt, vha, 0xe00a,
"Request ring circled: cnt=%d, vha->->ring_index=%d, "
--
1.7.7
Saurav Kashyap
2014-09-25 08:10:08 UTC
Permalink
From: Quinn Tran <***@qlogic.com>

Signed-off-by: Quinn Tran <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 18 ++++++------------
drivers/scsi/qla2xxx/qla_target.h | 1 +
2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index b07b180..51aa888 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2404,6 +2404,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,


cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */
+ cmd->cmd_sent_to_fw = 1;

qla2x00_start_iocbs(vha, vha->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -2479,6 +2480,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
qlt_load_data_segments(&prm, vha);

cmd->state = QLA_TGT_STATE_NEED_DATA;
+ cmd->cmd_sent_to_fw = 1;

qla2x00_start_iocbs(vha, vha->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -2712,19 +2714,10 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
if (rc == -ENOMEM)
qlt_alloc_qfull_cmd(vha, atio, 0, 0);
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+
done:
- /*
- * Terminate exchange will tell fw to release any active CTIO
- * that's in FW posession and cleanup the exchange.
- *
- * "cmd->state == QLA_TGT_STATE_ABORTED" means CTIO is still
- * down at FW. Free the cmd later when CTIO comes back later
- * w/aborted(0x2) status.
- *
- * "cmd->state != QLA_TGT_STATE_ABORTED" means CTIO is already
- * back w/some err. Free the cmd now.
- */
- if ((rc == 1) && (cmd->state != QLA_TGT_STATE_ABORTED)) {
+ if (cmd && ((cmd->state != QLA_TGT_STATE_ABORTED) ||
+ !cmd->cmd_sent_to_fw)) {
if (!ha_locked && !in_interrupt())
msleep(250); /* just in case */

@@ -3066,6 +3059,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,

se_cmd = &cmd->se_cmd;
tfo = se_cmd->se_tfo;
+ cmd->cmd_sent_to_fw = 0;

if (cmd->sg_mapped)
qlt_unmap_sg(vha, cmd);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 0c768f5..b07b230 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -917,6 +917,7 @@ struct qla_tgt_cmd {
unsigned int ctx_dsd_alloced:1;
unsigned int q_full:1;
unsigned int term_exchg:1;
+ unsigned int cmd_sent_to_fw:1;

struct scatterlist *sg; /* cmd data buffer SG vector */
int sg_cnt; /* SG segments count */
--
1.7.7
Saurav Kashyap
2014-09-25 08:10:12 UTC
Permalink
Signed-off-by: Saurav Kashyap <***@qlogic.com>
Signed-off-by: Giridhar Malavali <***@qlogic.com>
---
drivers/target/target_core_fabric_configfs.c | 28 ++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index 7de9f04..f97866e 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -42,6 +42,7 @@
#include "target_core_internal.h"
#include "target_core_alua.h"
#include "target_core_pr.h"
+#include "target_core_ua.h"

#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \
static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
@@ -326,6 +327,8 @@ static struct config_group *target_fabric_make_mappedlun(
char *buf;
unsigned long mapped_lun;
int ret = 0;
+ struct se_lun *lun;
+ int i = 0;

acl_ci = &group->cg_item;
if (!acl_ci) {
@@ -400,6 +403,16 @@ static struct config_group *target_fabric_make_mappedlun(
goto out;
}
target_stat_setup_mappedlun_default_groups(lacl);
+ spin_lock(&se_tpg->tpg_lun_lock);
+ for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
+ lun = se_tpg->tpg_lun_list[i];
+ if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE)
+ continue;
+ spin_unlock(&se_tpg->tpg_lun_lock);
+ core_scsi3_ua_allocate(se_nacl, lun->unpacked_lun, 0x3f, 0xe);
+ spin_lock(&se_tpg->tpg_lun_lock);
+ }
+ spin_unlock(&se_tpg->tpg_lun_lock);

kfree(buf);
return &lacl->se_lun_group;
@@ -419,6 +432,8 @@ static void target_fabric_drop_mappedlun(
struct config_item *df_item;
struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
int i;
+ struct se_lun *lun;
+ struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;

ml_stat_grp = &lacl->ml_stat_grps.stat_group;
for (i = 0; ml_stat_grp->default_groups[i]; i++) {
@@ -437,6 +452,19 @@ static void target_fabric_drop_mappedlun(
kfree(lacl_cg->default_groups);

config_item_put(item);
+
+ spin_lock(&se_tpg->tpg_lun_lock);
+ for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
+ lun = se_tpg->tpg_lun_list[i];
+ if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE)
+ continue;
+ spin_unlock(&se_tpg->tpg_lun_lock);
+ core_scsi3_ua_allocate(lacl->se_lun_nacl, lun->unpacked_lun,
+ 0x3f, 0xe);
+ spin_lock(&se_tpg->tpg_lun_lock);
+ }
+ spin_unlock(&se_tpg->tpg_lun_lock);
+
}

static void target_fabric_nacl_base_release(struct config_item *item)
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:10:07 UTC
Permalink
From: Himanshu Madhani <***@qlogic.com>

Signed-off-by: Himanshu Madhani <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index fed7fef..b07b180 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -4308,12 +4308,6 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
*/
ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
ctio24->u.status1.scsi_status = cpu_to_le16(status);
- ctio24->u.status1.residual = get_unaligned((uint32_t *)
- &atio->u.isp24.fcp_cmnd.add_cdb[
- atio->u.isp24.fcp_cmnd.add_cdb_len]);
- if (ctio24->u.status1.residual != 0)
- ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER;
-
qla2x00_start_iocbs(vha, vha->req);
return 0;
}
--
1.7.7
Saurav Kashyap
2014-09-25 08:10:09 UTC
Permalink
Signed-off-by: Saurav Kashyap <***@qlogic.com>
Signed-off-by: Giridhar Malavali <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 30 ++++++++++++++++++++++++++----
drivers/scsi/qla2xxx/qla_target.h | 24 ++++++++++++++++++++++++
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 24 ++++++++++++++++++++++++
3 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 51aa888..137ad54 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1718,6 +1718,7 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
se_cmd, cmd->tag);

cmd->state = QLA_TGT_STATE_ABORTED;
+ cmd->cmd_flags |= BIT_6;

qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);

@@ -2784,10 +2785,13 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
__func__, &cmd->se_cmd,
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));

+ BUG_ON(cmd->cmd_in_wq);
+
if (!cmd->q_full)
qlt_decr_num_pend_cmds(cmd->vha);

BUG_ON(cmd->sg_mapped);
+ cmd->jiffies_at_free = get_jiffies_64();
if (unlikely(cmd->free_sg))
kfree(cmd->sg);

@@ -2795,6 +2799,7 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
WARN_ON(1);
return;
}
+ cmd->jiffies_at_free = get_jiffies_64();
percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
}
EXPORT_SYMBOL(qlt_free_cmd);
@@ -2808,6 +2813,7 @@ static int qlt_prepare_srr_ctio(struct scsi_qla_host *vha,
struct qla_tgt_srr_imm *imm;

tgt->ctio_srr_id++;
+ cmd->cmd_flags |= BIT_15;

ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019,
"qla_target(%d): CTIO with SRR status received\n", vha->vp_idx);
@@ -2993,6 +2999,7 @@ qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
dump_stack();
}

+ cmd->cmd_flags |= BIT_12;
ha->tgt.tgt_ops->free_cmd(cmd);
}

@@ -3147,6 +3154,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
*/
if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
(cmd->state != QLA_TGT_STATE_ABORTED)) {
+ cmd->cmd_flags |= BIT_13;
if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
return;
}
@@ -3235,6 +3243,8 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
uint32_t data_length;
int ret, fcp_task_attr, data_dir, bidi = 0;

+ cmd->cmd_in_wq = 0;
+ cmd->cmd_flags |= BIT_1;
if (tgt->tgt_stop)
goto out_term;

@@ -3278,6 +3288,7 @@ out_term:
* cmd has not sent to target yet, so pass NULL as the second
* argument to qlt_send_term_exchange() and free the memory here.
*/
+ cmd->cmd_flags |= BIT_2;
spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_send_term_exchange(vha, NULL, &cmd->atio, 1);

@@ -3425,8 +3436,13 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
return -ENOMEM;
}

+ cmd->cmd_flags = 0;
+ cmd->jiffies_at_alloc = get_jiffies_64();
+
cmd->reset_count = vha->hw->chip_reset;

+ cmd->cmd_in_wq = 1;
+ cmd->cmd_flags |= BIT_0;
INIT_WORK(&cmd->work, qlt_do_work);
queue_work(qla_tgt_wq, &cmd->work);
return 0;
@@ -3888,8 +3904,10 @@ static void qlt_handle_srr(struct scsi_qla_host *vha,
qlt_send_notify_ack(vha, ntfy,
0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (xmit_type & QLA_TGT_XMIT_DATA)
+ if (xmit_type & QLA_TGT_XMIT_DATA) {
+ cmd->cmd_flags |= BIT_8;
qlt_rdy_to_xfer(cmd);
+ }
} else {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf066,
"qla_target(%d): SRR for out data for cmd "
@@ -3907,8 +3925,10 @@ static void qlt_handle_srr(struct scsi_qla_host *vha,
}

/* Transmit response in case of status and data-in cases */
- if (resp)
+ if (resp) {
+ cmd->cmd_flags |= BIT_7;
qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status);
+ }

return;

@@ -3921,8 +3941,10 @@ out_reject:
if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
cmd->state = QLA_TGT_STATE_DATA_IN;
dump_stack();
- } else
+ } else {
+ cmd->cmd_flags |= BIT_9;
qlt_send_term_exchange(vha, cmd, &cmd->atio, 1);
+ }
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

@@ -4036,7 +4058,7 @@ static void qlt_prepare_srr_imm(struct scsi_qla_host *vha,

tgt->imm_srr_id++;

- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02d, "qla_target(%d): SRR received\n",
+ ql_log(ql_log_warn, vha, 0xf02d, "qla_target(%d): SRR received\n",
vha->vp_idx);

imm = kzalloc(sizeof(*imm), GFP_ATOMIC);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index b07b230..8ff330f 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -918,6 +918,7 @@ struct qla_tgt_cmd {
unsigned int q_full:1;
unsigned int term_exchg:1;
unsigned int cmd_sent_to_fw:1;
+ unsigned int cmd_in_wq:1;

struct scatterlist *sg; /* cmd data buffer SG vector */
int sg_cnt; /* SG segments count */
@@ -940,6 +941,29 @@ struct qla_tgt_cmd {
uint32_t blk_sz;
struct crc_context *ctx;

+ uint64_t jiffies_at_alloc;
+ uint64_t jiffies_at_free;
+ /* BIT_0 - Atio Arrival / schedule to work
+ * BIT_1 - qlt_do_work
+ * BIT_2 - qlt_do work failed
+ * BIT_3 - xfer rdy/tcm_qla2xxx_write_pending
+ * BIT_4 - read respond/tcm_qla2xx_queue_data_in
+ * BIT_5 - status respond / tcm_qla2xx_queue_status
+ * BIT_6 - tcm request to abort/Term exchange.
+ * pre_xmit_response->qlt_send_term_exchange
+ * BIT_7 - SRR received (qlt_handle_srr->qlt_xmit_response)
+ * BIT_8 - SRR received (qlt_handle_srr->qlt_rdy_to_xfer)
+ * BIT_9 - SRR received (qla_handle_srr->qlt_send_term_exchange)
+ * BIT_10 - Data in - hanlde_data->tcm_qla2xxx_handle_data
+ * BIT_11 - Data actually going to TCM : tcm_qla2xx_handle_data_work
+ * BIT_12 - good completion - qlt_ctio_do_completion -->free_cmd
+ * BIT_13 - Bad completion -
+ * qlt_ctio_do_completion --> qlt_term_ctio_exchange
+ * BIT_14 - Back end data received/sent.
+ * BIT_15 - SRR prepare ctio
+ * BIT_16 - complete free
+ */
+ uint32_t cmd_flags;
};

struct qla_tgt_sess_work_param {
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 9f95407..031b296 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -390,6 +390,11 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
{
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);

+ cmd->cmd_in_wq = 0;
+
+ WARN_ON(cmd->cmd_flags & BIT_16);
+
+ cmd->cmd_flags |= BIT_16;
transport_generic_free_cmd(&cmd->se_cmd, 0);
}

@@ -400,6 +405,7 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
*/
static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
{
+ cmd->cmd_in_wq = 1;
INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
}
@@ -409,6 +415,13 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
*/
static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
{
+ struct qla_tgt_cmd *cmd;
+
+ if ((se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) == 0) {
+ cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+ cmd->cmd_flags |= BIT_14;
+ }
+
return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
}

@@ -571,6 +584,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
* Ensure that the complete FCP WRITE payload has been received.
* Otherwise return an exception via CHECK_CONDITION status.
*/
+ cmd->cmd_in_wq = 0;
+ cmd->cmd_flags |= BIT_11;
if (!cmd->write_data_transferred) {
/*
* Check if se_cmd has already been aborted via LUN_RESET, and
@@ -599,6 +614,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
*/
static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
{
+ cmd->cmd_flags |= BIT_10;
+ cmd->cmd_in_wq = 1;
INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
}
@@ -642,6 +659,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
struct qla_tgt_cmd *cmd = container_of(se_cmd,
struct qla_tgt_cmd, se_cmd);

+ cmd->cmd_flags |= BIT_4;
cmd->bufflen = se_cmd->data_length;
cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
@@ -649,6 +667,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
cmd->sg_cnt = se_cmd->t_data_nents;
cmd->sg = se_cmd->t_data_sg;
cmd->offset = 0;
+ cmd->cmd_flags |= BIT_3;

cmd->prot_sg_cnt = se_cmd->t_prot_nents;
cmd->prot_sg = se_cmd->t_prot_sg;
@@ -674,6 +693,11 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
cmd->offset = 0;
cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
+ if (cmd->cmd_flags & BIT_5) {
+ pr_crit("Bit_5 already set for cmd = %p.\n", cmd);
+ dump_stack();
+ }
+ cmd->cmd_flags |= BIT_5;

if (se_cmd->data_direction == DMA_FROM_DEVICE) {
/*
--
1.7.7
Saurav Kashyap
2014-09-25 08:10:10 UTC
Permalink
From: Himanshu Madhani <***@qlogic.com>

Signed-off-by: Himanshu Madhani <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 137ad54..7abf2de 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1035,6 +1035,8 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
"qla_target(%d): Sending 24xx Notify Ack %d\n",
vha->vp_idx, nack->u.isp24.status);

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);
}

@@ -1112,6 +1114,8 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,

vha->vha_tgt.qla_tgt->abts_resp_expected++;

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);
}

@@ -1157,6 +1161,8 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
CTIO7_FLAGS_TERMINATE);
ctio->u.status1.ox_id = cpu_to_le16(entry->fcp_hdr_le.ox_id);

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);

qlt_24xx_send_abts_resp(vha, (struct abts_recv_from_24xx *)entry,
@@ -1328,6 +1334,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
ctio->u.status1.response_len = __constant_cpu_to_le16(8);
ctio->u.status1.sense_data[0] = resp_code;

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(ha, ha->req);
}

@@ -2407,6 +2415,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */
cmd->cmd_sent_to_fw = 1;

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

@@ -2483,6 +2493,8 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
cmd->state = QLA_TGT_STATE_NEED_DATA;
cmd->cmd_sent_to_fw = 1;

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

@@ -2691,6 +2703,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
if (ctio24->u.status1.residual != 0)
ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER;

+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);
return ret;
}
@@ -4324,6 +4338,8 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
*/
ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
ctio24->u.status1.scsi_status = cpu_to_le16(status);
+ /* Memory Barrier */
+ wmb();
qla2x00_start_iocbs(vha, vha->req);
return 0;
}
--
1.7.7
Saurav Kashyap
2014-09-25 08:10:06 UTC
Permalink
From: Quinn Tran <***@qlogic.com>

Through the qla target code, the qlt_send_term_exchange() routine
is used in various different places to cleanup an exchange. For the
case of IOCB request queue is full, the exchange is left unhandled/
dangling. Existing code does not have re-try logic to cleanup the
exchange. This patch add retry logic to cleanup the exchange before
letting new commands through.

For the case of FW running out of exchanges, driver need to reply
SAM_STAT_BUSY to the initiators. This patch add a pending queue
for the busy reply in case IOCB queue is unable to handle the cmd.

Cc: <***@vger.kernel.org>
Signed-off-by: Quinn Tran <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_dbg.c | 4 +-
drivers/scsi/qla2xxx/qla_def.h | 17 ++
drivers/scsi/qla2xxx/qla_os.c | 2 +
drivers/scsi/qla2xxx/qla_target.c | 297 ++++++++++++++++++++++++++++++++++++-
drivers/scsi/qla2xxx/qla_target.h | 4 +
5 files changed, 316 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 09b335e..1b5c7a6 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -19,7 +19,7 @@
* | Device Discovery | 0x2016 | 0x2020-0x2022, |
* | | | 0x2011-0x2012, |
* | | | 0x2099-0x20a4 |
- * | Queue Command and IO tracing | 0x3059 | 0x3006-0x300b |
+ * | Queue Command and IO tracing | 0x3059 | 0x300b |
* | | | 0x3027-0x3028 |
* | | | 0x303d-0x3041 |
* | | | 0x302d,0x3033 |
@@ -67,7 +67,7 @@
* | | | 0xd031-0xd0ff |
* | | | 0xd101-0xd1fe |
* | | | 0xd214-0xd2fe |
- * | Target Mode | 0xe078 | |
+ * | Target Mode | 0xe079 | |
* | Target Mode Management | 0xf072 | 0xf002 |
* | | | 0xf046-0xf049 |
* | Target Mode Task Management | 0x1000b | |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 6e3b4f5..bd4f1f3 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2776,6 +2776,9 @@ struct qla_statistics {
uint32_t control_requests;

uint64_t jiffies_at_last_reset;
+ uint32_t stat_max_pend_cmds;
+ uint32_t stat_max_qfull_cmds_alloc;
+ uint32_t stat_max_qfull_cmds_dropped;
};

struct bidi_statistics {
@@ -2898,8 +2901,22 @@ struct qlt_hw_data {
uint8_t saved_add_firmware_options[2];

uint8_t tgt_node_name[WWN_SIZE];
+
+ struct list_head q_full_list;
+ uint32_t num_pend_cmds;
+ uint32_t num_qfull_cmds_alloc;
+ uint32_t num_qfull_cmds_dropped;
+ spinlock_t q_full_lock;
+ uint32_t leak_exchg_thresh_hold;
};

+#define MAX_QFULL_CMDS_ALLOC 8192
+#define Q_FULL_THRESH_HOLD_PERCENT 90
+#define Q_FULL_THRESH_HOLD(ha) \
+ ((ha->fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT)
+
+#define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */
+
/*
* Qlogic host adapter specific data structure.
*/
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 366ccf4..2485200 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2397,6 +2397,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"Memory allocated for ha=%p.\n", ha);
ha->pdev = pdev;
ha->tgt.enable_class_2 = ql2xenableclass2;
+ INIT_LIST_HEAD(&ha->tgt.q_full_list);
+ spin_lock_init(&ha->tgt.q_full_lock);

/* Clear our data area */
ha->bars = bars;
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 2c36b6c..fed7fef 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -54,6 +54,8 @@ MODULE_PARM_DESC(qlini_mode,

int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;

+static int temp_sam_status = SAM_STAT_BUSY;
+
/*
* From scsi/fc/fc_fcp.h
*/
@@ -103,6 +105,8 @@ static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
struct qla_tgt_srr_imm *imm, int ha_lock);
static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
struct qla_tgt_cmd *cmd);
+static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
+ struct atio_from_isp *atio, uint16_t status, int qfull);
/*
* Global Variables
*/
@@ -180,6 +184,27 @@ struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha,
return NULL;
}

+static inline void qlt_incr_num_pend_cmds(struct scsi_qla_host *vha)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
+
+ vha->hw->tgt.num_pend_cmds++;
+ if (vha->hw->tgt.num_pend_cmds > vha->hw->qla_stats.stat_max_pend_cmds)
+ vha->hw->qla_stats.stat_max_pend_cmds =
+ vha->hw->tgt.num_pend_cmds;
+ spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
+}
+static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
+ vha->hw->tgt.num_pend_cmds--;
+ spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
+}
+
void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
struct atio_from_isp *atio)
{
@@ -2678,10 +2703,14 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,

if (ha_locked) {
rc = __qlt_send_term_exchange(vha, cmd, atio);
+ if (rc == -ENOMEM)
+ qlt_alloc_qfull_cmd(vha, atio, 0, 0);
goto done;
}
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
rc = __qlt_send_term_exchange(vha, cmd, atio);
+ if (rc == -ENOMEM)
+ qlt_alloc_qfull_cmd(vha, atio, 0, 0);
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
done:
/*
@@ -2706,6 +2735,53 @@ done:
return;
}

+static void qlt_init_term_exchange(struct scsi_qla_host *vha)
+{
+ struct list_head free_list;
+ struct qla_tgt_cmd *cmd, *tcmd;
+
+ vha->hw->tgt.leak_exchg_thresh_hold =
+ (vha->hw->fw_xcb_count/100) * LEAK_EXCHG_THRESH_HOLD_PERCENT;
+
+ cmd = tcmd = NULL;
+ if (!list_empty(&vha->hw->tgt.q_full_list)) {
+ INIT_LIST_HEAD(&free_list);
+ list_splice_init(&vha->hw->tgt.q_full_list, &free_list);
+
+ list_for_each_entry_safe(cmd, tcmd, &free_list, cmd_list) {
+ list_del(&cmd->cmd_list);
+ /* This cmd was never sent to TCM. There is no need
+ * to schedule free or call free_cmd
+ */
+ qlt_free_cmd(cmd);
+ vha->hw->tgt.num_qfull_cmds_alloc--;
+ }
+ }
+ vha->hw->tgt.num_qfull_cmds_dropped = 0;
+}
+
+static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
+{
+ uint32_t total_leaked;
+
+ total_leaked = vha->hw->tgt.num_qfull_cmds_dropped;
+
+ if (vha->hw->tgt.leak_exchg_thresh_hold &&
+ (total_leaked > vha->hw->tgt.leak_exchg_thresh_hold)) {
+
+ ql_dbg(ql_dbg_tgt, vha, 0xe079,
+ "Chip reset due to exchange starvation: %d/%d.\n",
+ total_leaked, vha->hw->fw_xcb_count);
+
+ if (IS_P3P_TYPE(vha->hw))
+ set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+ else
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ }
+
+}
+
void qlt_free_cmd(struct qla_tgt_cmd *cmd)
{
struct qla_tgt_sess *sess = cmd->sess;
@@ -2715,6 +2791,9 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
__func__, &cmd->se_cmd,
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));

+ if (!cmd->q_full)
+ qlt_decr_num_pend_cmds(cmd->vha);
+
BUG_ON(cmd->sg_mapped);
if (unlikely(cmd->free_sg))
kfree(cmd->sg);
@@ -3073,7 +3152,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
* level.
*/
if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
- (cmd->state != QLA_TGT_STATE_ABORTED)) {
+ (cmd->state != QLA_TGT_STATE_ABORTED)) {
if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
return;
}
@@ -3109,6 +3188,7 @@ skip_term:
dump_stack();
}

+
ha->tgt.tgt_ops->free_cmd(cmd);
}

@@ -3206,6 +3286,8 @@ out_term:
*/
spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_send_term_exchange(vha, NULL, &cmd->atio, 1);
+
+ qlt_decr_num_pend_cmds(vha);
percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -3236,6 +3318,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
memcpy(&cmd->atio, atio, sizeof(*atio));
cmd->state = QLA_TGT_STATE_NEW;
cmd->tgt = vha->vha_tgt.qla_tgt;
+ qlt_incr_num_pend_cmds(vha);
cmd->vha = vha;
cmd->se_cmd.map_tag = tag;
cmd->sess = sess;
@@ -4179,7 +4262,7 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
* This function sends busy to ISP 2xxx or 24xx.
*/
-static void qlt_send_busy(struct scsi_qla_host *vha,
+static int __qlt_send_busy(struct scsi_qla_host *vha,
struct atio_from_isp *atio, uint16_t status)
{
struct ctio7_to_24xx *ctio24;
@@ -4191,7 +4274,7 @@ static void qlt_send_busy(struct scsi_qla_host *vha,
atio->u.isp24.fcp_hdr.s_id);
if (!sess) {
qlt_send_term_exchange(vha, NULL, atio, 1);
- return;
+ return 0;
}
/* Sending marker isn't necessary, since we called from ISR */

@@ -4200,7 +4283,7 @@ static void qlt_send_busy(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_io, vha, 0x3063,
"qla_target(%d): %s failed: unable to allocate "
"request packet", vha->vp_idx, __func__);
- return;
+ return -ENOMEM;
}

pkt->entry_count = 1;
@@ -4232,6 +4315,189 @@ static void qlt_send_busy(struct scsi_qla_host *vha,
ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER;

qla2x00_start_iocbs(vha, vha->req);
+ return 0;
+}
+
+/*
+ * This routine is used to allocate a command for either a QFull condition
+ * (ie reply SAM_STAT_BUSY) or to terminate an exchange that did not go
+ * out previously.
+ */
+static void
+qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
+ struct atio_from_isp *atio, uint16_t status, int qfull)
+{
+ struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
+ struct qla_hw_data *ha = vha->hw;
+ struct qla_tgt_sess *sess;
+ struct se_session *se_sess;
+ struct qla_tgt_cmd *cmd;
+ int tag;
+
+ if (unlikely(tgt->tgt_stop)) {
+ ql_dbg(ql_dbg_io, vha, 0x300a,
+ "New command while device %p is shutting down\n", tgt);
+ return;
+ }
+
+ if ((vha->hw->tgt.num_qfull_cmds_alloc + 1) > MAX_QFULL_CMDS_ALLOC) {
+ vha->hw->tgt.num_qfull_cmds_dropped++;
+ if (vha->hw->tgt.num_qfull_cmds_dropped >
+ vha->hw->qla_stats.stat_max_qfull_cmds_dropped)
+ vha->hw->qla_stats.stat_max_qfull_cmds_dropped =
+ vha->hw->tgt.num_qfull_cmds_dropped;
+
+ ql_dbg(ql_dbg_io, vha, 0x3068,
+ "qla_target(%d): %s: QFull CMD dropped[%d]\n",
+ vha->vp_idx, __func__,
+ vha->hw->tgt.num_qfull_cmds_dropped);
+
+ qlt_chk_exch_leak_thresh_hold(vha);
+ return;
+ }
+
+ sess = ha->tgt.tgt_ops->find_sess_by_s_id
+ (vha, atio->u.isp24.fcp_hdr.s_id);
+ if (!sess)
+ return;
+
+ se_sess = sess->se_sess;
+
+ tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
+ if (tag < 0)
+ return;
+
+ cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
+ if (!cmd) {
+ ql_dbg(ql_dbg_io, vha, 0x3009,
+ "qla_target(%d): %s: Allocation of cmd failed\n",
+ vha->vp_idx, __func__);
+
+ vha->hw->tgt.num_qfull_cmds_dropped++;
+ if (vha->hw->tgt.num_qfull_cmds_dropped >
+ vha->hw->qla_stats.stat_max_qfull_cmds_dropped)
+ vha->hw->qla_stats.stat_max_qfull_cmds_dropped =
+ vha->hw->tgt.num_qfull_cmds_dropped;
+
+ qlt_chk_exch_leak_thresh_hold(vha);
+ return;
+ }
+
+ memset(cmd, 0, sizeof(struct qla_tgt_cmd));
+
+ qlt_incr_num_pend_cmds(vha);
+ INIT_LIST_HEAD(&cmd->cmd_list);
+ memcpy(&cmd->atio, atio, sizeof(*atio));
+
+ cmd->tgt = vha->vha_tgt.qla_tgt;
+ cmd->vha = vha;
+ cmd->reset_count = vha->hw->chip_reset;
+ cmd->q_full = 1;
+
+ if (qfull) {
+ cmd->q_full = 1;
+ /* NOTE: borrowing the state field to carry the status */
+ cmd->state = status;
+ } else
+ cmd->term_exchg = 1;
+
+ list_add_tail(&cmd->cmd_list, &vha->hw->tgt.q_full_list);
+
+ vha->hw->tgt.num_qfull_cmds_alloc++;
+ if (vha->hw->tgt.num_qfull_cmds_alloc >
+ vha->hw->qla_stats.stat_max_qfull_cmds_alloc)
+ vha->hw->qla_stats.stat_max_qfull_cmds_alloc =
+ vha->hw->tgt.num_qfull_cmds_alloc;
+}
+
+int
+qlt_free_qfull_cmds(struct scsi_qla_host *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ unsigned long flags;
+ struct qla_tgt_cmd *cmd, *tcmd;
+ struct list_head free_list;
+ int rc = 0;
+
+ if (list_empty(&ha->tgt.q_full_list))
+ return 0;
+
+ INIT_LIST_HEAD(&free_list);
+
+ spin_lock_irqsave(&vha->hw->hardware_lock, flags);
+
+ if (list_empty(&ha->tgt.q_full_list)) {
+ spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+ return 0;
+ }
+
+ list_for_each_entry_safe(cmd, tcmd, &ha->tgt.q_full_list, cmd_list) {
+ if (cmd->q_full)
+ /* cmd->state is a borrowed field to hold status */
+ rc = __qlt_send_busy(vha, &cmd->atio, cmd->state);
+ else if (cmd->term_exchg)
+ rc = __qlt_send_term_exchange(vha, NULL, &cmd->atio);
+
+ if (rc == -ENOMEM)
+ break;
+
+ if (cmd->q_full)
+ ql_dbg(ql_dbg_io, vha, 0x3006,
+ "%s: busy sent for ox_id[%04x]\n", __func__,
+ be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
+ else if (cmd->term_exchg)
+ ql_dbg(ql_dbg_io, vha, 0x3007,
+ "%s: Term exchg sent for ox_id[%04x]\n", __func__,
+ be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
+ else
+ ql_dbg(ql_dbg_io, vha, 0x3008,
+ "%s: Unexpected cmd in QFull list %p\n", __func__,
+ cmd);
+
+ list_del(&cmd->cmd_list);
+ list_add_tail(&cmd->cmd_list, &free_list);
+
+ /* piggy back on hardware_lock for protection */
+ vha->hw->tgt.num_qfull_cmds_alloc--;
+ }
+ spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+
+ cmd = NULL;
+
+ list_for_each_entry_safe(cmd, tcmd, &free_list, cmd_list) {
+ list_del(&cmd->cmd_list);
+ /* This cmd was never sent to TCM. There is no need
+ * to schedule free or call free_cmd
+ */
+ qlt_free_cmd(cmd);
+ }
+ return rc;
+}
+
+static void
+qlt_send_busy(struct scsi_qla_host *vha,
+ struct atio_from_isp *atio, uint16_t status)
+{
+ int rc = 0;
+
+ rc = __qlt_send_busy(vha, atio, status);
+ if (rc == -ENOMEM)
+ qlt_alloc_qfull_cmd(vha, atio, status, 1);
+}
+
+static int
+qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
+ struct atio_from_isp *atio)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t status;
+
+ if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
+ return 0;
+
+ status = temp_sam_status;
+ qlt_send_busy(vha, atio, status);
+ return 1;
}

/* ha->hardware_lock supposed to be held on entry */
@@ -4266,10 +4532,19 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL);
break;
}
- if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0))
+
+
+
+ if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
+ rc = qlt_chk_qfull_thresh_hold(vha, atio);
+ if (rc != 0) {
+ tgt->irq_cmd_count--;
+ return;
+ }
rc = qlt_handle_cmd_for_atio(vha, atio);
- else
+ } else {
rc = qlt_handle_task_mgmt(vha, atio);
+ }
if (unlikely(rc != 0)) {
if (rc == -ESRCH) {
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
@@ -4364,6 +4639,12 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
break;
}

+ rc = qlt_chk_qfull_thresh_hold(vha, atio);
+ if (rc != 0) {
+ tgt->irq_cmd_count--;
+ return;
+ }
+
rc = qlt_handle_cmd_for_atio(vha, atio);
if (unlikely(rc != 0)) {
if (rc == -ESRCH) {
@@ -4901,6 +5182,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
qlt_release(vha->vha_tgt.qla_tgt);
return 0;
}
+
+ /* free left over qfull cmds */
+ qlt_init_term_exchange(vha);
+
mutex_lock(&qla_tgt_mutex);
list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry);
mutex_unlock(&qla_tgt_mutex);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 20e42bd..0c768f5 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -915,6 +915,8 @@ struct qla_tgt_cmd {
unsigned int aborted:1; /* Needed in case of SRR */
unsigned int write_data_transferred:1;
unsigned int ctx_dsd_alloced:1;
+ unsigned int q_full:1;
+ unsigned int term_exchg:1;

struct scatterlist *sg; /* cmd data buffer SG vector */
int sg_cnt; /* SG segments count */
@@ -928,6 +930,7 @@ struct qla_tgt_cmd {
uint16_t loop_id; /* to save extra sess dereferences */
struct qla_tgt *tgt; /* to save extra sess dereferences */
struct scsi_qla_host *vha;
+ struct list_head cmd_list;

struct atio_from_isp atio;
/* t10dif */
@@ -1091,5 +1094,6 @@ extern int qlt_stop_phase1(struct qla_tgt *);
extern void qlt_stop_phase2(struct qla_tgt *);
extern irqreturn_t qla83xx_msix_atio_q(int, void *);
extern void qlt_83xx_iospace_config(struct qla_hw_data *);
+extern int qlt_free_qfull_cmds(struct scsi_qla_host *);

#endif /* __QLA_TARGET_H */
--
1.7.7
Saurav Kashyap
2014-09-25 08:10:11 UTC
Permalink
From: Quinn Tran <***@qlogic.com>

During temporary resource starvation at lower transport layer, command
is placed on queue full retry path, which expose this problem. The TCM
Qfull handling send the same cmd twice to lower layer. The 1st time
led to cmd normal free path. The 2nd time cause Null pointer access.

Signed-off-by: Quinn Tran <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/target/target_core_transport.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 7fa62fc..ab61014 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1877,8 +1877,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) {
trace_target_cmd_complete(cmd);
ret = cmd->se_tfo->queue_status(cmd);
- if (ret)
- goto out;
+ goto out;
}

switch (cmd->data_direction) {
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:10:02 UTC
Permalink
From: Arun Easi <***@qlogic.com>

Signed-off-by: Arun Easi <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_dbg.c | 2 +-
drivers/scsi/qla2xxx/qla_gbl.h | 1 +
drivers/scsi/qla2xxx/qla_os.c | 2 +
drivers/scsi/qla2xxx/qla_target.c | 74 +++++++++++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index f3b6570..09b335e 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -68,7 +68,7 @@
* | | | 0xd101-0xd1fe |
* | | | 0xd214-0xd2fe |
* | Target Mode | 0xe078 | |
- * | Target Mode Management | 0xf072 | 0xf002-0xf003 |
+ * | Target Mode Management | 0xf072 | 0xf002 |
* | | | 0xf046-0xf049 |
* | Target Mode Task Management | 0x1000b | |
* ----------------------------------------------------------------------
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index cc9e088..8257a27 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -765,4 +765,5 @@ extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
extern int qla8044_abort_isp(scsi_qla_host_t *);
extern int qla8044_check_fw_alive(struct scsi_qla_host *);

+extern void qlt_host_reset_handler(struct qla_hw_data *ha);
#endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 70445bc..437dc90 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1362,6 +1362,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
struct qla_hw_data *ha = vha->hw;
struct req_que *req;

+ qlt_host_reset_handler(ha);
+
spin_lock_irqsave(&ha->hardware_lock, flags);
for (que = 0; que < ha->max_req_queues; que++) {
req = ha->req_q_map[que];
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 4989bf7..edd9d1b 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2838,6 +2838,80 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
return cmd;
}

+/* hardware_lock should be held by caller. */
+static void
+qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t handle;
+
+ if (cmd->sg_mapped)
+ qlt_unmap_sg(vha, cmd);
+
+ handle = qlt_make_handle(vha);
+
+ /* TODO: fix debug message type and ids. */
+ if (cmd->state == QLA_TGT_STATE_PROCESSED) {
+ ql_dbg(ql_dbg_io, vha, 0xff00,
+ "HOST-ABORT: handle=%d, state=PROCESSED.\n", handle);
+ } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
+ cmd->write_data_transferred = 0;
+ cmd->state = QLA_TGT_STATE_DATA_IN;
+
+ ql_dbg(ql_dbg_io, vha, 0xff01,
+ "HOST-ABORT: handle=%d, state=DATA_IN.\n", handle);
+
+ ha->tgt.tgt_ops->handle_data(cmd);
+ return;
+ } else if (cmd->state == QLA_TGT_STATE_ABORTED) {
+ ql_dbg(ql_dbg_io, vha, 0xff02,
+ "HOST-ABORT: handle=%d, state=ABORTED.\n", handle);
+ } else {
+ ql_dbg(ql_dbg_io, vha, 0xff03,
+ "HOST-ABORT: handle=%d, state=BAD(%d).\n", handle,
+ cmd->state);
+ dump_stack();
+ }
+
+ ha->tgt.tgt_ops->free_cmd(cmd);
+}
+
+void
+qlt_host_reset_handler(struct qla_hw_data *ha)
+{
+ struct qla_tgt_cmd *cmd;
+ unsigned long flags;
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ scsi_qla_host_t *vha = NULL;
+ struct qla_tgt *tgt = base_vha->vha_tgt.qla_tgt;
+ uint32_t i;
+
+ if (!base_vha->hw->tgt.tgt_ops)
+ return;
+
+ if (!tgt || qla_ini_mode_enabled(base_vha)) {
+ ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003,
+ "Target mode disabled\n");
+ return;
+ }
+
+ ql_dbg(ql_dbg_tgt_mgt, vha, 0xff10,
+ "HOST-ABORT-HNDLR: base_vha->dpc_flags=%lx.\n",
+ base_vha->dpc_flags);
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ for (i = 1; i < DEFAULT_OUTSTANDING_COMMANDS + 1; i++) {
+ cmd = qlt_get_cmd(base_vha, i);
+ if (!cmd)
+ continue;
+ /* ha->tgt.cmds entry is cleared by qlt_get_cmd. */
+ vha = cmd->vha;
+ qlt_abort_cmd_on_host_reset(vha, cmd);
+ }
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+
/*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:10:01 UTC
Permalink
From: Himanshu Madhani <***@qlogic.com>

tcm_qla2xxx_get_task_tag incorrectly assume command is
qla_tgt_cmd. Add check to see if it's a scsi cmd or
task mgmt command.

Signed-off-by: Quinn Tran <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 09d2931..9f95407 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -515,8 +515,13 @@ static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl)

static u32 tcm_qla2xxx_get_task_tag(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;
+
+ /* check for task mgmt cmd */
+ if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+ return 0xffffffff;
+
+ cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);

return cmd->tag;
}
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:10:04 UTC
Permalink
From: Arun Easi <***@qlogic.com>

ABTS path takes path similar to regular task management, but
reset_count was not initialized when allocating mcmd causing
the response to get dropped in qlt_xmit_tm_rsp. Fix this by
initializing reset_count correctly.

Signed-off-by: Arun Easi <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 25af5b7..2c36b6c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1180,6 +1180,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,

mcmd->sess = sess;
memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
+ mcmd->reset_count = vha->hw->chip_reset;

rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, TMR_ABORT_TASK,
abts->exchange_addr_to_abort);
@@ -3518,6 +3519,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,

lun = a->u.isp24.fcp_cmnd.lun;
unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
+ mcmd->reset_count = vha->hw->chip_reset;

rc = ha->tgt.tgt_ops->handle_tmr(mcmd, unpacked_lun, TMR_ABORT_TASK,
le16_to_cpu(iocb->u.isp2x.seq_id));
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:09:58 UTC
Permalink
From: Arun Easi <***@qlogic.com>

Turning logging bits for target mode ON dumps quite a lot verbose
messages, remove those and change some of the IO path logging to
use IO bits.

Signed-off-by: Arun Easi <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 154 ++++---------------------------------
1 files changed, 16 insertions(+), 138 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index bcc449a..c64266a 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1397,8 +1397,6 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
}
}

- ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n",
- prm->seg_cnt, prm->req_cnt);
return 0;

out_err:
@@ -1436,10 +1434,6 @@ static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
if (vha->req->cnt < (req_cnt + 2)) {
cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);

- ql_dbg(ql_dbg_tgt, vha, 0xe00a,
- "Request ring circled: cnt=%d, vha->->ring_index=%d, "
- "vha->req->cnt=%d, req_cnt=%d\n", cnt,
- vha->req->ring_index, vha->req->cnt, req_cnt);
if (vha->req->ring_index < cnt)
vha->req->cnt = cnt - vha->req->ring_index;
else
@@ -1448,7 +1442,7 @@ static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
}

if (unlikely(vha->req->cnt < (req_cnt + 2))) {
- ql_dbg(ql_dbg_tgt, vha, 0xe00b,
+ ql_dbg(ql_dbg_io, vha, 0x305a,
"qla_target(%d): There is no room in the "
"request ring: vha->req->ring_index=%d, vha->req->cnt=%d, "
"req_cnt=%d\n", vha->vp_idx, vha->req->ring_index,
@@ -1489,7 +1483,7 @@ static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha)
if (h > DEFAULT_OUTSTANDING_COMMANDS)
h = 1; /* 0 is QLA_TGT_NULL_HANDLE */
if (h == ha->tgt.current_handle) {
- ql_dbg(ql_dbg_tgt, vha, 0xe04e,
+ ql_dbg(ql_dbg_io, vha, 0x305b,
"qla_target(%d): Ran out of "
"empty cmd slots in ha %p\n", vha->vp_idx, ha);
h = QLA_TGT_NULL_HANDLE;
@@ -1546,9 +1540,6 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
pkt->u.status0.ox_id = cpu_to_le16(temp);
pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);

- ql_dbg(ql_dbg_tgt, vha, 0xe00c,
- "qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n",
- vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, temp);
return 0;
}

@@ -1606,14 +1597,6 @@ static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm,
}
*dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));

- ql_dbg(ql_dbg_tgt, vha, 0xe00d,
- "S/G Segment Cont. phys_addr=%llx:%llx, len=%d\n",
- (long long unsigned int)
- pci_dma_hi32(sg_dma_address(prm->sg)),
- (long long unsigned int)
- pci_dma_lo32(sg_dma_address(prm->sg)),
- (int)sg_dma_len(prm->sg));
-
prm->sg = sg_next(prm->sg);
}
}
@@ -1631,11 +1614,6 @@ static void qlt_load_data_segments(struct qla_tgt_prm *prm,
int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt;

- ql_dbg(ql_dbg_tgt, vha, 0xe00e,
- "iocb->scsi_status=%x, iocb->flags=%x\n",
- le16_to_cpu(pkt24->u.status0.scsi_status),
- le16_to_cpu(pkt24->u.status0.flags));
-
pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen);

/* Setup packet address segment pointer */
@@ -1653,7 +1631,6 @@ static void qlt_load_data_segments(struct qla_tgt_prm *prm,
}

/* If scatter gather */
- ql_dbg(ql_dbg_tgt, vha, 0xe00f, "%s", "Building S/G data segments...");

/* Load command entry data segments */
for (cnt = 0;
@@ -1668,14 +1645,6 @@ static void qlt_load_data_segments(struct qla_tgt_prm *prm,
}
*dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));

- ql_dbg(ql_dbg_tgt, vha, 0xe010,
- "S/G Segment phys_addr=%llx:%llx, len=%d\n",
- (long long unsigned int)pci_dma_hi32(sg_dma_address(
- prm->sg)),
- (long long unsigned int)pci_dma_lo32(sg_dma_address(
- prm->sg)),
- (int)sg_dma_len(prm->sg));
-
prm->sg = sg_next(prm->sg);
}

@@ -1713,10 +1682,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED;
}

- ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u ox_id %04x\n",
- vha->vp_idx, cmd->tag,
- be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
-
prm->cmd = cmd;
prm->tgt = tgt;
prm->rq_result = scsi_status;
@@ -1727,15 +1692,10 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
prm->req_cnt = 1;
prm->add_status_pkt = 0;

- ql_dbg(ql_dbg_tgt, vha, 0xe012, "rq_result=%x, xmit_type=%x\n",
- prm->rq_result, xmit_type);
-
/* Send marker if required */
if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
return -EFAULT;

- ql_dbg(ql_dbg_tgt, vha, 0xe013, "CTIO start: vha(%d)\n", vha->vp_idx);
-
if ((xmit_type & QLA_TGT_XMIT_DATA) && qlt_has_data(cmd)) {
if (qlt_pci_map_calc_cnt(prm) != 0)
return -EAGAIN;
@@ -1745,7 +1705,7 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,

if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
prm->residual = se_cmd->residual_count;
- ql_dbg(ql_dbg_tgt, vha, 0xe014,
+ ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x305c,
"Residual underflow: %d (tag %d, "
"op %x, bufflen %d, rq_result %x)\n", prm->residual,
cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0,
@@ -1753,7 +1713,7 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
prm->rq_result |= SS_RESIDUAL_UNDER;
} else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
prm->residual = se_cmd->residual_count;
- ql_dbg(ql_dbg_tgt, vha, 0xe015,
+ ql_dbg(ql_dbg_io, vha, 0x305d,
"Residual overflow: %d (tag %d, "
"op %x, bufflen %d, rq_result %x)\n", prm->residual,
cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0,
@@ -1776,10 +1736,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
}
}

- ql_dbg(ql_dbg_tgt, vha, 0xe016,
- "req_cnt=%d, full_req_cnt=%d, add_status_pkt=%d\n",
- prm->req_cnt, *full_req_cnt, prm->add_status_pkt);
-
return 0;
}

@@ -2356,8 +2312,9 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
struct ctio7_to_24xx *ctio =
(struct ctio7_to_24xx *)qlt_get_req_pkt(vha);

- ql_dbg(ql_dbg_tgt, vha, 0xe019,
- "Building additional status packet\n");
+ ql_dbg(ql_dbg_io, vha, 0x305e,
+ "Building additional status packet 0x%p.\n",
+ ctio);

/*
* T10Dif: ctio_crc2_to_fw overlay ontop of
@@ -2390,10 +2347,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,

cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */

- ql_dbg(ql_dbg_tgt, vha, 0xe01a,
- "Xmitting CTIO7 response pkt for 24xx: %p scsi_status: 0x%02x\n",
- pkt, scsi_status);
-
qla2x00_start_iocbs(vha, vha->req);
spin_unlock_irqrestore(&ha->hardware_lock, flags);

@@ -2428,11 +2381,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
return -EIO;

- ql_dbg(ql_dbg_tgt, vha, 0xe01b,
- "%s: CTIO_start: vha(%d) se_cmd %p ox_id %04x\n",
- __func__, (int)vha->vp_idx, &cmd->se_cmd,
- be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
-
/* Calculate number of entries and segments required */
if (qlt_pci_map_calc_cnt(&prm) != 0)
return -EAGAIN;
@@ -2861,11 +2809,9 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
CTIO_INTERMEDIATE_HANDLE_MARK);

if (handle != QLA_TGT_NULL_HANDLE) {
- if (unlikely(handle == QLA_TGT_SKIP_HANDLE)) {
- ql_dbg(ql_dbg_tgt, vha, 0xe01d, "%s",
- "SKIP_HANDLE CTIO\n");
+ if (unlikely(handle == QLA_TGT_SKIP_HANDLE))
return NULL;
- }
+
/* handle-1 is actually used */
if (unlikely(handle > DEFAULT_OUTSTANDING_COMMANDS)) {
ql_dbg(ql_dbg_tgt, vha, 0xe052,
@@ -2903,10 +2849,6 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
struct target_core_fabric_ops *tfo;
struct qla_tgt_cmd *cmd;

- ql_dbg(ql_dbg_tgt, vha, 0xe01e,
- "qla_target(%d): handle(ctio %p status %#x) <- %08x\n",
- vha->vp_idx, ctio, status, handle);
-
if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) {
/* That could happen only in case of an error/reset/abort */
if (status != CTIO_SUCCESS) {
@@ -3017,7 +2959,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
skip_term:

if (cmd->state == QLA_TGT_STATE_PROCESSED) {
- ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd);
+ ;
} else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
int rx_status = 0;

@@ -3028,10 +2970,6 @@ skip_term:
else
cmd->write_data_transferred = 1;

- ql_dbg(ql_dbg_tgt, vha, 0xe020,
- "Data received, context %x, rx_status %d\n",
- 0x0, rx_status);
-
ha->tgt.tgt_ops->handle_data(cmd);
return;
} else if (cmd->state == QLA_TGT_STATE_ABORTED) {
@@ -3126,11 +3064,6 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
&atio->u.isp24.fcp_cmnd.add_cdb[
atio->u.isp24.fcp_cmnd.add_cdb_len]));

- ql_dbg(ql_dbg_tgt, vha, 0xe022,
- "qla_target: START qla cmd: %p se_cmd %p lun: 0x%04x (tag %d) len(%d) ox_id %x\n",
- cmd, &cmd->se_cmd, cmd->unpacked_lun, cmd->tag, data_length,
- cmd->atio.u.isp24.fcp_hdr.ox_id);
-
ret = ha->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length,
fcp_task_attr, data_dir, bidi);
if (ret != 0)
@@ -3144,7 +3077,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
return;

out_term:
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf020, "Terminating work cmd %p", cmd);
+ ql_dbg(ql_dbg_io, vha, 0x3060, "Terminating work cmd %p", cmd);
/*
* cmd has not sent to target yet, so pass NULL as the second
* argument to qlt_send_term_exchange() and free the memory here.
@@ -3262,7 +3195,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
struct qla_tgt_cmd *cmd;

if (unlikely(tgt->tgt_stop)) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf021,
+ ql_dbg(ql_dbg_io, vha, 0x3061,
"New command while device %p is shutting down\n", tgt);
return -EFAULT;
}
@@ -3287,7 +3220,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,

cmd = qlt_get_tag(vha, sess, atio);
if (!cmd) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05e,
+ ql_dbg(ql_dbg_io, vha, 0x3062,
"qla_target(%d): Allocation of cmd failed\n", vha->vp_idx);
ha->tgt.tgt_ops->put_sess(sess);
return -ENOMEM;
@@ -4138,7 +4071,7 @@ static void qlt_send_busy(struct scsi_qla_host *vha,

pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
if (!pkt) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06e,
+ ql_dbg(ql_dbg_io, vha, 0x3063,
"qla_target(%d): %s failed: unable to allocate "
"request packet", vha->vp_idx, __func__);
return;
@@ -4185,14 +4118,10 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
int rc;

if (unlikely(tgt == NULL)) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf039,
+ ql_dbg(ql_dbg_io, vha, 0x3064,
"ATIO pkt, but no tgt (ha %p)", ha);
return;
}
- ql_dbg(ql_dbg_tgt, vha, 0xe02c,
- "qla_target(%d): ATIO pkt %p: type %02x count %02x",
- vha->vp_idx, atio, atio->u.raw.entry_type,
- atio->u.raw.entry_count);
/*
* In tgt_stop mode we also should allow all requests to pass.
* Otherwise, some commands can stuck.
@@ -4202,23 +4131,9 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,

switch (atio->u.raw.entry_type) {
case ATIO_TYPE7:
- ql_dbg(ql_dbg_tgt, vha, 0xe02d,
- "ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, cdb %x, add_cdb_len %x, data_length %04x, s_id %02x%02x%02x\n",
- vha->vp_idx, atio->u.isp24.fcp_cmnd.lun,
- atio->u.isp24.fcp_cmnd.rddata,
- atio->u.isp24.fcp_cmnd.wrdata,
- atio->u.isp24.fcp_cmnd.cdb[0],
- atio->u.isp24.fcp_cmnd.add_cdb_len,
- be32_to_cpu(get_unaligned((uint32_t *)
- &atio->u.isp24.fcp_cmnd.add_cdb[
- atio->u.isp24.fcp_cmnd.add_cdb_len])),
- atio->u.isp24.fcp_hdr.s_id[0],
- atio->u.isp24.fcp_hdr.s_id[1],
- atio->u.isp24.fcp_hdr.s_id[2]);
-
if (unlikely(atio->u.isp24.exchange_addr ==
ATIO_EXCHANGE_ADDRESS_UNKNOWN)) {
- ql_dbg(ql_dbg_tgt, vha, 0xe058,
+ ql_dbg(ql_dbg_io, vha, 0x3065,
"qla_target(%d): ATIO_TYPE7 "
"received with UNKNOWN exchange address, "
"sending QUEUE_FULL\n", vha->vp_idx);
@@ -4292,11 +4207,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
return;
}

- ql_dbg(ql_dbg_tgt, vha, 0xe02f,
- "qla_target(%d): response pkt %p: T %02x C %02x S %02x "
- "handle %#x\n", vha->vp_idx, pkt, pkt->entry_type,
- pkt->entry_count, pkt->entry_status, pkt->handle);
-
/*
* In tgt_stop mode we also should allow all requests to pass.
* Otherwise, some commands can stuck.
@@ -4309,9 +4219,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
case CTIO_TYPE7:
{
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
- ql_dbg(ql_dbg_tgt, vha, 0xe030,
- "CTIO[0x%x] 12/CTIO7 7A/CRC2: instance %d\n",
- entry->entry_type, vha->vp_idx);
qlt_do_ctio_completion(vha, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry);
@@ -4322,15 +4229,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
{
struct atio_from_isp *atio = (struct atio_from_isp *)pkt;
int rc;
- ql_dbg(ql_dbg_tgt, vha, 0xe031,
- "ACCEPT_TGT_IO instance %d status %04x "
- "lun %04x read/write %d data_length %04x "
- "target_id %02x rx_id %04x\n ", vha->vp_idx,
- le16_to_cpu(atio->u.isp2x.status),
- le16_to_cpu(atio->u.isp2x.lun),
- atio->u.isp2x.execution_codes,
- le32_to_cpu(atio->u.isp2x.data_length), GET_TARGET_ID(ha,
- atio), atio->u.isp2x.rx_id);
if (atio->u.isp2x.status !=
__constant_cpu_to_le16(ATIO_CDB_VALID)) {
ql_dbg(ql_dbg_tgt, vha, 0xe05e,
@@ -4339,10 +4237,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
le16_to_cpu(atio->u.isp2x.status));
break;
}
- ql_dbg(ql_dbg_tgt, vha, 0xe032,
- "FCP CDB: 0x%02x, sizeof(cdb): %lu",
- atio->u.isp2x.cdb[0], (unsigned long
- int)sizeof(atio->u.isp2x.cdb));

rc = qlt_handle_cmd_for_atio(vha, atio);
if (unlikely(rc != 0)) {
@@ -4375,8 +4269,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
case CONTINUE_TGT_IO_TYPE:
{
struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt;
- ql_dbg(ql_dbg_tgt, vha, 0xe033,
- "CONTINUE_TGT_IO: instance %d\n", vha->vp_idx);
qlt_do_ctio_completion(vha, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry);
@@ -4386,8 +4278,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
case CTIO_A64_TYPE:
{
struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt;
- ql_dbg(ql_dbg_tgt, vha, 0xe034, "CTIO_A64: instance %d\n",
- vha->vp_idx);
qlt_do_ctio_completion(vha, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry);
@@ -4491,11 +4381,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
int login_code;

- ql_dbg(ql_dbg_tgt, vha, 0xe039,
- "scsi(%ld): ha state %d init_done %d oper_mode %d topo %d\n",
- vha->host_no, atomic_read(&vha->loop_state), vha->flags.init_done,
- ha->operating_mode, ha->current_topology);
-
if (!ha->tgt.tgt_ops)
return;

@@ -4572,11 +4457,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
break;

default:
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf040,
- "qla_target(%d): Async event %#x occurred: "
- "ignore (m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx,
- code, le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
- le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
break;
}

@@ -4597,8 +4477,6 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
return NULL;
}

- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf041, "loop_id %d", loop_id);
-
fcport->loop_id = loop_id;

rc = qla2x00_get_port_database(vha, fcport, 0);
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:10:05 UTC
Permalink
Signed-off-by: Saurav Kashyap <***@qlogic.com>
Signed-off-by: Giridhar Malavali <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_def.h | 1 +
drivers/scsi/qla2xxx/qla_os.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c9fe4cf..6e3b4f5 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -266,6 +266,7 @@
#define REQUEST_ENTRY_CNT_2100 128 /* Number of request entries. */
#define REQUEST_ENTRY_CNT_2200 2048 /* Number of request entries. */
#define REQUEST_ENTRY_CNT_24XX 2048 /* Number of request entries. */
+#define REQUEST_ENTRY_CNT_83XX 8192 /* Number of request entries. */
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_MQ 128 /* Number of response entries.*/
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 437dc90..366ccf4 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2540,7 +2540,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->portnum = PCI_FUNC(ha->pdev->devfn);
ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
ha->mbx_count = MAILBOX_REGISTER_COUNT;
- req_length = REQUEST_ENTRY_CNT_24XX;
+ req_length = REQUEST_ENTRY_CNT_83XX;
rsp_length = RESPONSE_ENTRY_CNT_2300;
ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:09:57 UTC
Permalink
From: Himanshu Madhani <***@qlogic.com>

Signed-off-by: Himanshu Madhani <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_iocb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 6a6867d..c787847 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1901,7 +1901,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)

skip_cmd_array:
/* Check for room on request queue. */
- if (req->cnt < req_cnt) {
+ if (req->cnt < req_cnt + 2) {
if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
else if (IS_P3P_TYPE(ha))
@@ -1920,7 +1920,7 @@ skip_cmd_array:
req->cnt = req->length -
(req->ring_index - cnt);
}
- if (req->cnt < req_cnt)
+ if (req->cnt < req_cnt + 2)
goto queuing_error;

/* Prep packet */
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:09:55 UTC
Permalink
From: Himanshu Madhani <***@qlogic.com>

This patch is to fix regression added by commit id
51a07f84649d2be206c4c2ad9a612956db0c2f8c.

When allocating memory for new session original patch does
not assign vha to op->vha resulting into NULL pointer
access during qlt_create_sess_from_atio().

Cc: <***@vger.kernel.org>
Signed-off-by: Himanshu Madhani <***@qlogic.com>
Signed-off-by: Saurav Kashyap <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index e632e14..e44fcb5 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -3277,6 +3277,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
return -ENOMEM;

memcpy(&op->atio, atio, sizeof(*atio));
+ op->vha = vha;
INIT_WORK(&op->work, qlt_create_sess_from_atio);
queue_work(qla_tgt_wq, &op->work);
return 0;
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Saurav Kashyap
2014-09-25 08:10:00 UTC
Permalink
Signed-off-by: Saurav Kashyap <***@qlogic.com>
Signed-off-by: Giridhar Malavali <***@qlogic.com>
---
drivers/scsi/qla2xxx/qla_target.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 2d4003f..4989bf7 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1429,10 +1429,11 @@ static inline void qlt_unmap_sg(struct scsi_qla_host *vha,
static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
uint32_t req_cnt)
{
- uint32_t cnt;
+ uint32_t cnt, cnt_in;

if (vha->req->cnt < (req_cnt + 2)) {
cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);
+ cnt_in = (uint16_t)RD_REG_DWORD(vha->req->req_q_in);

if (vha->req->ring_index < cnt)
vha->req->cnt = cnt - vha->req->ring_index;
@@ -1443,10 +1444,9 @@ static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,

if (unlikely(vha->req->cnt < (req_cnt + 2))) {
ql_dbg(ql_dbg_io, vha, 0x305a,
- "qla_target(%d): There is no room in the "
- "request ring: vha->req->ring_index=%d, vha->req->cnt=%d, "
- "req_cnt=%d\n", vha->vp_idx, vha->req->ring_index,
- vha->req->cnt, req_cnt);
+ "qla_target(%d): There is no room in the request ring: vha->req->ring_index=%d, vha->req->cnt=%d, req_cnt=%d Req-out=%d Req-in=%d Req-Length=%d\n",
+ vha->vp_idx, vha->req->ring_index,
+ vha->req->cnt, req_cnt, cnt, cnt_in, vha->req->length);
return -EAGAIN;
}
vha->req->cnt -= req_cnt;
--
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...