linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/8] snic: Added additional stats
@ 2016-03-17  7:51 Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts Narsimhulu Musini
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

Adding additional stats, and fixed logging messages.
- Added qdepth change stats
- Added separate isr stats for each type of interrupt
- Fixed race in updating active IOs
- Suppressed Link event message for DAS backend.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic_ctl.c     |  8 +++-----
 drivers/scsi/snic/snic_debugfs.c | 20 ++++++++++++++++----
 drivers/scsi/snic/snic_isr.c     |  6 +++---
 drivers/scsi/snic/snic_main.c    |  9 ++++++++-
 drivers/scsi/snic/snic_scsi.c    | 27 ++++++++++++++++++++-------
 drivers/scsi/snic/snic_stats.h   | 12 +++++++++---
 6 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/snic/snic_ctl.c b/drivers/scsi/snic/snic_ctl.c
index aebe753..229b199 100644
--- a/drivers/scsi/snic/snic_ctl.c
+++ b/drivers/scsi/snic/snic_ctl.c
@@ -39,17 +39,15 @@ snic_handle_link(struct work_struct *work)
 {
 	struct snic *snic = container_of(work, struct snic, link_work);
 
-	if (snic->config.xpt_type != SNIC_DAS) {
-		SNIC_HOST_INFO(snic->shost, "Link Event Received.\n");
-		SNIC_ASSERT_NOT_IMPL(1);
-
+	if (snic->config.xpt_type == SNIC_DAS)
 		return;
-	}
 
 	snic->link_status = svnic_dev_link_status(snic->vdev);
 	snic->link_down_cnt = svnic_dev_link_down_cnt(snic->vdev);
 	SNIC_HOST_INFO(snic->shost, "Link Event: Link %s.\n",
 		       ((snic->link_status) ? "Up" : "Down"));
+
+	SNIC_ASSERT_NOT_IMPL(1);
 }
 
 
diff --git a/drivers/scsi/snic/snic_debugfs.c b/drivers/scsi/snic/snic_debugfs.c
index 1686f01..d302803 100644
--- a/drivers/scsi/snic/snic_debugfs.c
+++ b/drivers/scsi/snic/snic_debugfs.c
@@ -264,12 +264,14 @@ snic_stats_show(struct seq_file *sfp, void *data)
 		   "Aborts Fail                 : %lld\n"
 		   "Aborts Driver Timeout       : %lld\n"
 		   "Abort FW Timeout            : %lld\n"
-		   "Abort IO NOT Found          : %lld\n",
+		   "Abort IO NOT Found          : %lld\n"
+		   "Abort Queuing Failed        : %lld\n",
 		   (u64) atomic64_read(&stats->abts.num),
 		   (u64) atomic64_read(&stats->abts.fail),
 		   (u64) atomic64_read(&stats->abts.drv_tmo),
 		   (u64) atomic64_read(&stats->abts.fw_tmo),
-		   (u64) atomic64_read(&stats->abts.io_not_found));
+		   (u64) atomic64_read(&stats->abts.io_not_found),
+		   (u64) atomic64_read(&stats->abts.q_fail));
 
 	/* Dump Reset Stats */
 	seq_printf(sfp,
@@ -316,7 +318,9 @@ snic_stats_show(struct seq_file *sfp, void *data)
 	seq_printf(sfp,
 		   "Last ISR Time               : %llu (%8lu.%8lu)\n"
 		   "Last Ack Time               : %llu (%8lu.%8lu)\n"
-		   "ISRs                        : %llu\n"
+		   "Ack ISRs                    : %llu\n"
+		   "IO Cmpl ISRs                : %llu\n"
+		   "Err Notify ISRs             : %llu\n"
 		   "Max CQ Entries              : %lld\n"
 		   "Data Count Mismatch         : %lld\n"
 		   "IOs w/ Timeout Status       : %lld\n"
@@ -324,12 +328,17 @@ snic_stats_show(struct seq_file *sfp, void *data)
 		   "IOs w/ SGL Invalid Stat     : %lld\n"
 		   "WQ Desc Alloc Fail          : %lld\n"
 		   "Queue Full                  : %lld\n"
+		   "Queue Ramp Up               : %lld\n"
+		   "Queue Ramp Down             : %lld\n"
+		   "Queue Last Queue Depth      : %lld\n"
 		   "Target Not Ready            : %lld\n",
 		   (u64) stats->misc.last_isr_time,
 		   last_isr_tms.tv_sec, last_isr_tms.tv_nsec,
 		   (u64)stats->misc.last_ack_time,
 		   last_ack_tms.tv_sec, last_ack_tms.tv_nsec,
-		   (u64) atomic64_read(&stats->misc.isr_cnt),
+		   (u64) atomic64_read(&stats->misc.ack_isr_cnt),
+		   (u64) atomic64_read(&stats->misc.cmpl_isr_cnt),
+		   (u64) atomic64_read(&stats->misc.errnotify_isr_cnt),
 		   (u64) atomic64_read(&stats->misc.max_cq_ents),
 		   (u64) atomic64_read(&stats->misc.data_cnt_mismat),
 		   (u64) atomic64_read(&stats->misc.io_tmo),
@@ -337,6 +346,9 @@ snic_stats_show(struct seq_file *sfp, void *data)
 		   (u64) atomic64_read(&stats->misc.sgl_inval),
 		   (u64) atomic64_read(&stats->misc.wq_alloc_fail),
 		   (u64) atomic64_read(&stats->misc.qfull),
+		   (u64) atomic64_read(&stats->misc.qsz_rampup),
+		   (u64) atomic64_read(&stats->misc.qsz_rampdown),
+		   (u64) atomic64_read(&stats->misc.last_qsz),
 		   (u64) atomic64_read(&stats->misc.tgt_not_rdy));
 
 	return 0;
diff --git a/drivers/scsi/snic/snic_isr.c b/drivers/scsi/snic/snic_isr.c
index a85fae2..f552003 100644
--- a/drivers/scsi/snic/snic_isr.c
+++ b/drivers/scsi/snic/snic_isr.c
@@ -38,7 +38,7 @@ snic_isr_msix_wq(int irq, void *data)
 	unsigned long wq_work_done = 0;
 
 	snic->s_stats.misc.last_isr_time = jiffies;
-	atomic64_inc(&snic->s_stats.misc.isr_cnt);
+	atomic64_inc(&snic->s_stats.misc.ack_isr_cnt);
 
 	wq_work_done = snic_wq_cmpl_handler(snic, -1);
 	svnic_intr_return_credits(&snic->intr[SNIC_MSIX_WQ],
@@ -56,7 +56,7 @@ snic_isr_msix_io_cmpl(int irq, void *data)
 	unsigned long iocmpl_work_done = 0;
 
 	snic->s_stats.misc.last_isr_time = jiffies;
-	atomic64_inc(&snic->s_stats.misc.isr_cnt);
+	atomic64_inc(&snic->s_stats.misc.cmpl_isr_cnt);
 
 	iocmpl_work_done = snic_fwcq_cmpl_handler(snic, -1);
 	svnic_intr_return_credits(&snic->intr[SNIC_MSIX_IO_CMPL],
@@ -73,7 +73,7 @@ snic_isr_msix_err_notify(int irq, void *data)
 	struct snic *snic = data;
 
 	snic->s_stats.misc.last_isr_time = jiffies;
-	atomic64_inc(&snic->s_stats.misc.isr_cnt);
+	atomic64_inc(&snic->s_stats.misc.errnotify_isr_cnt);
 
 	svnic_intr_return_all_credits(&snic->intr[SNIC_MSIX_ERR_NOTIFY]);
 	snic_log_q_error(snic);
diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
index 2b3c253..37ec507 100644
--- a/drivers/scsi/snic/snic_main.c
+++ b/drivers/scsi/snic/snic_main.c
@@ -98,11 +98,18 @@ snic_slave_configure(struct scsi_device *sdev)
 static int
 snic_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
+	struct snic *snic = shost_priv(sdev->host);
 	int qsz = 0;
 
 	qsz = min_t(u32, qdepth, SNIC_MAX_QUEUE_DEPTH);
+	if (qsz < sdev->queue_depth)
+		atomic64_inc(&snic->s_stats.misc.qsz_rampdown);
+	else if (qsz > sdev->queue_depth)
+		atomic64_inc(&snic->s_stats.misc.qsz_rampup);
+
+	atomic64_set(&snic->s_stats.misc.last_qsz, sdev->queue_depth);
+
 	scsi_change_queue_depth(sdev, qsz);
-	SNIC_INFO("QDepth Changed to %d\n", sdev->queue_depth);
 
 	return sdev->queue_depth;
 }
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 2c7b4c3..e423eaa 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -221,11 +221,15 @@ snic_queue_icmnd_req(struct snic *snic,
 			pa, /* sense buffer pa */
 			SCSI_SENSE_BUFFERSIZE);
 
+	atomic64_inc(&snic->s_stats.io.active);
 	ret = snic_queue_wq_desc(snic, rqi->req, rqi->req_len);
-	if (ret)
+	if (ret) {
+		atomic64_dec(&snic->s_stats.io.active);
 		SNIC_HOST_ERR(snic->shost,
 			      "QIcmnd: Queuing Icmnd Failed. ret = %d\n",
 			      ret);
+	} else
+		snic_stats_update_active_ios(&snic->s_stats);
 
 	return ret;
 } /* end of snic_queue_icmnd_req */
@@ -361,8 +365,7 @@ snic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
 	if (ret) {
 		SNIC_HOST_ERR(shost, "Failed to Q, Scsi Req w/ err %d.\n", ret);
 		ret = SCSI_MLQUEUE_HOST_BUSY;
-	} else
-		snic_stats_update_active_ios(&snic->s_stats);
+	}
 
 	atomic_dec(&snic->ios_inflight);
 
@@ -1001,10 +1004,11 @@ snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
 	unsigned long flags, gflags;
 	int ret = 0;
 
+	snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
 	SNIC_HOST_INFO(snic->shost,
-		       "reset_cmpl:HBA Reset Completion received.\n");
+		       "reset_cmpl:Tag %d ctx %lx cmpl status %s HBA Reset Completion received.\n",
+		       cmnd_id, ctx, snic_io_status_to_str(hdr_stat));
 
-	snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
 	SNIC_SCSI_DBG(snic->shost,
 		      "reset_cmpl: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x, ctx = %lx\n",
 		      typ, hdr_stat, cmnd_id, hid, ctx);
@@ -1012,6 +1016,9 @@ snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
 	/* spl case, host reset issued through ioctl */
 	if (cmnd_id == SCSI_NO_TAG) {
 		rqi = (struct snic_req_info *) ctx;
+		SNIC_HOST_INFO(snic->shost,
+			       "reset_cmpl:Tag %d ctx %lx cmpl stat %s\n",
+			       cmnd_id, ctx, snic_io_status_to_str(hdr_stat));
 		sc = rqi->sc;
 
 		goto ioctl_hba_rst;
@@ -1038,6 +1045,10 @@ ioctl_hba_rst:
 		return ret;
 	}
 
+	SNIC_HOST_INFO(snic->shost,
+		       "reset_cmpl: sc %p rqi %p Tag %d flags 0x%llx\n",
+		       sc, rqi, cmnd_id, CMD_FLAGS(sc));
+
 	io_lock = snic_io_lock_hash(snic, sc);
 	spin_lock_irqsave(io_lock, flags);
 
@@ -1554,6 +1565,7 @@ snic_send_abort_and_wait(struct snic *snic, struct scsi_cmnd *sc)
 	/* Now Queue the abort command to firmware */
 	ret = snic_queue_abort_req(snic, rqi, sc, tmf);
 	if (ret) {
+		atomic64_inc(&snic->s_stats.abts.q_fail);
 		SNIC_HOST_ERR(snic->shost,
 			      "send_abt_cmd: IO w/ Tag 0x%x fail w/ err %d flags 0x%llx\n",
 			      tag, ret, CMD_FLAGS(sc));
@@ -2459,8 +2471,9 @@ snic_scsi_cleanup(struct snic *snic, int ex_tag)
 cleanup:
 		sc->result = DID_TRANSPORT_DISRUPTED << 16;
 		SNIC_HOST_INFO(snic->shost,
-			       "sc_clean: DID_TRANSPORT_DISRUPTED for sc %p. rqi %p duration %llu msecs\n",
-			       sc, rqi, (jiffies - st_time));
+			       "sc_clean: DID_TRANSPORT_DISRUPTED for sc %p, Tag %d flags 0x%llx rqi %p duration %u msecs\n",
+			       sc, sc->request->tag, CMD_FLAGS(sc), rqi,
+			       jiffies_to_msecs(jiffies - st_time));
 
 		/* Update IO stats */
 		snic_stats_update_io_cmpl(&snic->s_stats);
diff --git a/drivers/scsi/snic/snic_stats.h b/drivers/scsi/snic/snic_stats.h
index 11e6148..fd1066b 100644
--- a/drivers/scsi/snic/snic_stats.h
+++ b/drivers/scsi/snic/snic_stats.h
@@ -42,6 +42,7 @@ struct snic_abort_stats {
 	atomic64_t drv_tmo;	/* Abort Driver Timeouts */
 	atomic64_t fw_tmo;	/* Abort Firmware Timeouts */
 	atomic64_t io_not_found;/* Abort IO Not Found */
+	atomic64_t q_fail;	/* Abort Queuing Failed */
 };
 
 struct snic_reset_stats {
@@ -69,7 +70,9 @@ struct snic_fw_stats {
 struct snic_misc_stats {
 	u64	last_isr_time;
 	u64	last_ack_time;
-	atomic64_t isr_cnt;
+	atomic64_t ack_isr_cnt;
+	atomic64_t cmpl_isr_cnt;
+	atomic64_t errnotify_isr_cnt;
 	atomic64_t max_cq_ents;		/* Max CQ Entries */
 	atomic64_t data_cnt_mismat;	/* Data Count Mismatch */
 	atomic64_t io_tmo;
@@ -81,6 +84,9 @@ struct snic_misc_stats {
 	atomic64_t no_icmnd_itmf_cmpls;
 	atomic64_t io_under_run;
 	atomic64_t qfull;
+	atomic64_t qsz_rampup;
+	atomic64_t qsz_rampdown;
+	atomic64_t last_qsz;
 	atomic64_t tgt_not_rdy;
 };
 
@@ -101,9 +107,9 @@ static inline void
 snic_stats_update_active_ios(struct snic_stats *s_stats)
 {
 	struct snic_io_stats *io = &s_stats->io;
-	u32 nr_active_ios;
+	int nr_active_ios;
 
-	nr_active_ios = atomic64_inc_return(&io->active);
+	nr_active_ios = atomic64_read(&io->active);
 	if (atomic64_read(&io->max_active) < nr_active_ios)
 		atomic64_set(&io->max_active, nr_active_ios);
 
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  2016-04-05  2:05   ` Martin K. Petersen
  2016-03-17  7:51 ` [PATCH 3/8] snic: Handling control path queue issues Narsimhulu Musini
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

- LUN goes offline, if there are atleast two scsi command timeouts
  Completing the IO with scsi_done() fixes the issue.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic_scsi.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index e423eaa..5a709eb 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -1465,11 +1465,19 @@ snic_abort_finish(struct snic *snic, struct scsi_cmnd *sc)
 	case SNIC_STAT_IO_SUCCESS:
 	case SNIC_STAT_IO_NOT_FOUND:
 		ret = SUCCESS;
+		/*
+		 * If abort path doesn't call scsi_done(),
+		 * the # IO timeouts == 2, will cause the LUN offline.
+		 * Call scsi_done to complete the IO.
+		 */
+		sc->result = (DID_ERROR << 16);
+		sc->scsi_done(sc);
 		break;
 
 	default:
 		/* Firmware completed abort with error */
 		ret = FAILED;
+		rqi = NULL;
 		break;
 	}
 
@@ -1842,6 +1850,9 @@ snic_dr_clean_single_req(struct snic *snic,
 
 	snic_release_req_buf(snic, rqi, sc);
 
+	sc->result = (DID_ERROR << 16);
+	sc->scsi_done(sc);
+
 	ret = 0;
 
 	return ret;
@@ -2396,6 +2407,13 @@ snic_cmpl_pending_tmreq(struct snic *snic, struct scsi_cmnd *sc)
 		      "Completing Pending TM Req sc %p, state %s flags 0x%llx\n",
 		      sc, snic_io_status_to_str(CMD_STATE(sc)), CMD_FLAGS(sc));
 
+	/*
+	 * CASE : FW didn't post itmf completion due to PCIe Errors.
+	 * Marking the abort status as Success to call scsi completion
+	 * in snic_abort_finish()
+	 */
+	CMD_ABTS_STATUS(sc) = SNIC_STAT_IO_SUCCESS;
+
 	rqi = (struct snic_req_info *) CMD_SP(sc);
 	if (!rqi)
 		return;
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/8] snic: Handling control path queue issues
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 4/8] snic: target cleanup in driver unload path Narsimhulu Musini
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

Fix handles control path queue issues such as queue full, and
sudden removal of hardware.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/vnic_dev.c | 44 ++++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/snic/vnic_dev.c b/drivers/scsi/snic/vnic_dev.c
index e0b5549..dad5fc6 100644
--- a/drivers/scsi/snic/vnic_dev.c
+++ b/drivers/scsi/snic/vnic_dev.c
@@ -263,12 +263,20 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	int wait)
 {
 	struct devcmd2_controller *dc2c = vdev->devcmd2;
-	struct devcmd2_result *result = dc2c->result + dc2c->next_result;
+	struct devcmd2_result *result = NULL;
 	unsigned int i;
 	int delay;
 	int err;
 	u32 posted;
+	u32 fetch_idx;
 	u32 new_posted;
+	u8 color;
+
+	fetch_idx = ioread32(&dc2c->wq_ctrl->fetch_index);
+	if (fetch_idx == 0xFFFFFFFF) { /* check for hardware gone  */
+		/* Hardware surprise removal: return error */
+		return -ENODEV;
+	}
 
 	posted = ioread32(&dc2c->wq_ctrl->posted_index);
 
@@ -278,6 +286,13 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	}
 
 	new_posted = (posted + 1) % DEVCMD2_RING_SIZE;
+	if (new_posted == fetch_idx) {
+		pr_err("%s: wq is full while issuing devcmd2 command %d, fetch index: %u, posted index: %u\n",
+			pci_name(vdev->pdev), _CMD_N(cmd), fetch_idx, posted);
+
+		return -EBUSY;
+	}
+
 	dc2c->cmd_ring[posted].cmd = cmd;
 	dc2c->cmd_ring[posted].flags = 0;
 
@@ -299,14 +314,22 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT)
 		return 0;
 
+	result = dc2c->result + dc2c->next_result;
+	color = dc2c->color;
+
+	/*
+	 * Increment next_result, after posting the devcmd, irrespective of
+	 * devcmd result, and it should be done only once.
+	 */
+	dc2c->next_result++;
+	if (dc2c->next_result == dc2c->result_size) {
+		dc2c->next_result = 0;
+		dc2c->color = dc2c->color ? 0 : 1;
+	}
+
 	for (delay = 0; delay < wait; delay++) {
 		udelay(100);
-		if (result->color == dc2c->color) {
-			dc2c->next_result++;
-			if (dc2c->next_result == dc2c->result_size) {
-				dc2c->next_result = 0;
-				dc2c->color = dc2c->color ? 0 : 1;
-			}
+		if (result->color == color) {
 			if (result->error) {
 				err = (int) result->error;
 				if (err != ERR_ECMDUNKNOWN ||
@@ -317,13 +340,6 @@ static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 				return err;
 			}
 			if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
-				/*
-				 * Adding the rmb() prevents the compiler
-				 * and/or CPU from reordering the reads which
-				 * would potentially result in reading stale
-				 * values.
-				 */
-				rmb();
 				for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
 					vdev->args[i] = result->results[i];
 			}
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/8] snic: target cleanup in driver unload path
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 3/8] snic: Handling control path queue issues Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 5/8] snic: Fix for missing interrupts Narsimhulu Musini
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

Fix deletes the snic targets synchronously prior to deletion of host.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic_disc.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c
index 5f63217..c46960c 100644
--- a/drivers/scsi/snic/snic_disc.c
+++ b/drivers/scsi/snic/snic_disc.c
@@ -480,10 +480,21 @@ int
 snic_disc_start(struct snic *snic)
 {
 	struct snic_disc *disc = &snic->disc;
+	unsigned long flags;
 	int ret = 0;
 
 	SNIC_SCSI_DBG(snic->shost, "Discovery Start.\n");
 
+	spin_lock_irqsave(&snic->snic_lock, flags);
+	if (snic->in_remove) {
+		spin_unlock_irqrestore(&snic->snic_lock, flags);
+		SNIC_ERR("snic driver removal in progress ...\n");
+		ret = 0;
+
+		return ret;
+	}
+	spin_unlock_irqrestore(&snic->snic_lock, flags);
+
 	mutex_lock(&disc->mutex);
 	if (disc->state == SNIC_DISC_PENDING) {
 		disc->req_cnt++;
@@ -533,6 +544,8 @@ snic_tgt_del_all(struct snic *snic)
 	struct list_head *cur, *nxt;
 	unsigned long flags;
 
+	scsi_flush_work(snic->shost);
+
 	mutex_lock(&snic->disc.mutex);
 	spin_lock_irqsave(snic->shost->host_lock, flags);
 
@@ -545,7 +558,7 @@ snic_tgt_del_all(struct snic *snic)
 		tgt = NULL;
 	}
 	spin_unlock_irqrestore(snic->shost->host_lock, flags);
-
-	scsi_flush_work(snic->shost);
 	mutex_unlock(&snic->disc.mutex);
+
+	flush_workqueue(snic_glob->event_q);
 } /* end of snic_tgt_del_all */
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/8] snic: Fix for missing interrupts
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
                   ` (2 preceding siblings ...)
  2016-03-17  7:51 ` [PATCH 4/8] snic: target cleanup in driver unload path Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 6/8] snic: Fixing race in the hba reset and IO/TM completion Narsimhulu Musini
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

- On posting an IO to the firmware, adapter generates an interrupt.
  Due to hardware issues, some times the adapter fails to generate
  the interrupt. This behavior skips updating transmit queue-
  counters, which inturn causes the queue full condition. The fix
  addresses the queue full condition.

- The fix also reserves a slot in transmit queue for hba reset.
  when queue full is observed during IO, there will always be room
  to post hba reset command.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic_fwint.h |  4 ++-
 drivers/scsi/snic/snic_io.c    | 62 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/snic/snic_fwint.h b/drivers/scsi/snic/snic_fwint.h
index 2cfaf2d..c5f9e19 100644
--- a/drivers/scsi/snic/snic_fwint.h
+++ b/drivers/scsi/snic/snic_fwint.h
@@ -414,7 +414,7 @@ enum snic_ev_type {
 /* Payload 88 bytes = 128 - 24 - 16 */
 #define SNIC_HOST_REQ_PAYLOAD	((int)(SNIC_HOST_REQ_LEN -		\
 					sizeof(struct snic_io_hdr) -	\
-					(2 * sizeof(u64))))
+					(2 * sizeof(u64)) - sizeof(ulong)))
 
 /*
  * snic_host_req: host -> firmware request
@@ -448,6 +448,8 @@ struct snic_host_req {
 		/* hba reset */
 		struct snic_hba_reset		reset;
 	} u;
+
+	ulong req_pa;
 }; /* end of snic_host_req structure */
 
 
diff --git a/drivers/scsi/snic/snic_io.c b/drivers/scsi/snic/snic_io.c
index 993db7d..8e69548 100644
--- a/drivers/scsi/snic/snic_io.c
+++ b/drivers/scsi/snic/snic_io.c
@@ -48,7 +48,7 @@ snic_wq_cmpl_frame_send(struct vnic_wq *wq,
 	SNIC_TRC(snic->shost->host_no, 0, 0,
 		 ((ulong)(buf->os_buf) - sizeof(struct snic_req_info)), 0, 0,
 		 0);
-	pci_unmap_single(snic->pdev, buf->dma_addr, buf->len, PCI_DMA_TODEVICE);
+
 	buf->os_buf = NULL;
 }
 
@@ -137,13 +137,36 @@ snic_select_wq(struct snic *snic)
 	return 0;
 }
 
+static int
+snic_wqdesc_avail(struct snic *snic, int q_num, int req_type)
+{
+	int nr_wqdesc = snic->config.wq_enet_desc_count;
+
+	if (q_num > 0) {
+		/*
+		 * Multi Queue case, additional care is required.
+		 * Per WQ active requests need to be maintained.
+		 */
+		SNIC_HOST_INFO(snic->shost, "desc_avail: Multi Queue case.\n");
+		SNIC_BUG_ON(q_num > 0);
+
+		return -1;
+	}
+
+	nr_wqdesc -= atomic64_read(&snic->s_stats.fw.actv_reqs);
+
+	return ((req_type == SNIC_REQ_HBA_RESET) ? nr_wqdesc : nr_wqdesc - 1);
+}
+
 int
 snic_queue_wq_desc(struct snic *snic, void *os_buf, u16 len)
 {
 	dma_addr_t pa = 0;
 	unsigned long flags;
 	struct snic_fw_stats *fwstats = &snic->s_stats.fw;
+	struct snic_host_req *req = (struct snic_host_req *) os_buf;
 	long act_reqs;
+	long desc_avail = 0;
 	int q_num = 0;
 
 	snic_print_desc(__func__, os_buf, len);
@@ -156,11 +179,15 @@ snic_queue_wq_desc(struct snic *snic, void *os_buf, u16 len)
 		return -ENOMEM;
 	}
 
+	req->req_pa = (ulong)pa;
+
 	q_num = snic_select_wq(snic);
 
 	spin_lock_irqsave(&snic->wq_lock[q_num], flags);
-	if (!svnic_wq_desc_avail(snic->wq)) {
+	desc_avail = snic_wqdesc_avail(snic, q_num, req->hdr.type);
+	if (desc_avail <= 0) {
 		pci_unmap_single(snic->pdev, pa, len, PCI_DMA_TODEVICE);
+		req->req_pa = 0;
 		spin_unlock_irqrestore(&snic->wq_lock[q_num], flags);
 		atomic64_inc(&snic->s_stats.misc.wq_alloc_fail);
 		SNIC_DBG("host = %d, WQ is Full\n", snic->shost->host_no);
@@ -169,10 +196,13 @@ snic_queue_wq_desc(struct snic *snic, void *os_buf, u16 len)
 	}
 
 	snic_queue_wq_eth_desc(&snic->wq[q_num], os_buf, pa, len, 0, 0, 1);
+	/*
+	 * Update stats
+	 * note: when multi queue enabled, fw actv_reqs should be per queue.
+	 */
+	act_reqs = atomic64_inc_return(&fwstats->actv_reqs);
 	spin_unlock_irqrestore(&snic->wq_lock[q_num], flags);
 
-	/* Update stats */
-	act_reqs = atomic64_inc_return(&fwstats->actv_reqs);
 	if (act_reqs > atomic64_read(&fwstats->max_actv_reqs))
 		atomic64_set(&fwstats->max_actv_reqs, act_reqs);
 
@@ -318,11 +348,31 @@ snic_req_free(struct snic *snic, struct snic_req_info *rqi)
 		      "Req_free:rqi %p:ioreq %p:abt %p:dr %p\n",
 		      rqi, rqi->req, rqi->abort_req, rqi->dr_req);
 
-	if (rqi->abort_req)
+	if (rqi->abort_req) {
+		if (rqi->abort_req->req_pa)
+			pci_unmap_single(snic->pdev,
+					 rqi->abort_req->req_pa,
+					 sizeof(struct snic_host_req),
+					 PCI_DMA_TODEVICE);
+
 		mempool_free(rqi->abort_req, snic->req_pool[SNIC_REQ_TM_CACHE]);
+	}
+
+	if (rqi->dr_req) {
+		if (rqi->dr_req->req_pa)
+			pci_unmap_single(snic->pdev,
+					 rqi->dr_req->req_pa,
+					 sizeof(struct snic_host_req),
+					 PCI_DMA_TODEVICE);
 
-	if (rqi->dr_req)
 		mempool_free(rqi->dr_req, snic->req_pool[SNIC_REQ_TM_CACHE]);
+	}
+
+	if (rqi->req->req_pa)
+		pci_unmap_single(snic->pdev,
+				 rqi->req->req_pa,
+				 rqi->req_len,
+				 PCI_DMA_TODEVICE);
 
 	mempool_free(rqi, snic->req_pool[rqi->rq_pool_type]);
 }
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/8] snic: Fixing race in the hba reset and IO/TM completion
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
                   ` (3 preceding siblings ...)
  2016-03-17  7:51 ` [PATCH 5/8] snic: Fix for missing interrupts Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 7/8] snic: add scsi host after determining max IOs Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 8/8] snic: updating driver version Narsimhulu Musini
  6 siblings, 0 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

While HBA reset is in progress, if IO/TM completion is received for the
same IO then IO/TM completion path releases the driver private resources
associated with IO. This fix prevents releasing the resources in
IO and TM completion path if HBA reset is in progress.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic.h      |  5 ++++-
 drivers/scsi/snic/snic_scsi.c | 11 +++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h
index d7f5ba6..8ed778d 100644
--- a/drivers/scsi/snic/snic.h
+++ b/drivers/scsi/snic/snic.h
@@ -95,6 +95,8 @@
 #define SNIC_DEV_RST_NOTSUP		BIT(25)
 #define SNIC_SCSI_CLEANUP		BIT(26)
 #define SNIC_HOST_RESET_ISSUED		BIT(27)
+#define SNIC_HOST_RESET_CMD_TERM	\
+	(SNIC_DEV_RST_NOTSUP | SNIC_SCSI_CLEANUP | SNIC_HOST_RESET_ISSUED)
 
 #define SNIC_ABTS_TIMEOUT		30000		/* msec */
 #define SNIC_LUN_RESET_TIMEOUT		30000		/* msec */
@@ -216,9 +218,10 @@ enum snic_msix_intr_index {
 	SNIC_MSIX_INTR_MAX,
 };
 
+#define SNIC_INTRHDLR_NAMSZ	(2 * IFNAMSIZ)
 struct snic_msix_entry {
 	int requested;
-	char devname[IFNAMSIZ];
+	char devname[SNIC_INTRHDLR_NAMSZ];
 	irqreturn_t (*isr)(int, void *);
 	void *devid;
 };
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 5a709eb..abada16 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -601,6 +601,12 @@ snic_icmnd_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
 		      sc->device->lun, sc, sc->cmnd[0], snic_cmd_tag(sc),
 		      CMD_FLAGS(sc), rqi);
 
+	if (CMD_FLAGS(sc) & SNIC_HOST_RESET_CMD_TERM) {
+		spin_unlock_irqrestore(io_lock, flags);
+
+		return;
+	}
+
 	SNIC_BUG_ON(rqi != (struct snic_req_info *)ctx);
 	WARN_ON_ONCE(req);
 	if (!rqi) {
@@ -782,6 +788,11 @@ snic_process_itmf_cmpl(struct snic *snic,
 
 	io_lock = snic_io_lock_hash(snic, sc);
 	spin_lock_irqsave(io_lock, flags);
+	if (CMD_FLAGS(sc) & SNIC_HOST_RESET_CMD_TERM) {
+		spin_unlock_irqrestore(io_lock, flags);
+
+		return ret;
+	}
 	rqi = (struct snic_req_info *) CMD_SP(sc);
 	WARN_ON_ONCE(!rqi);
 
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/8] snic: add scsi host after determining max IOs.
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
                   ` (4 preceding siblings ...)
  2016-03-17  7:51 ` [PATCH 6/8] snic: Fixing race in the hba reset and IO/TM completion Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  2016-03-17  7:51 ` [PATCH 8/8] snic: updating driver version Narsimhulu Musini
  6 siblings, 0 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

scsi host is added after negotiating the max number of IOs with Firmware.

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic_main.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
index 37ec507..396b32d 100644
--- a/drivers/scsi/snic/snic_main.c
+++ b/drivers/scsi/snic/snic_main.c
@@ -631,19 +631,6 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_free_tmreq_pool;
 	}
 
-	/*
-	 * Initialization done with PCI system, hardware, firmware.
-	 * Add shost to SCSI
-	 */
-	ret = snic_add_host(shost, pdev);
-	if (ret) {
-		SNIC_HOST_ERR(shost,
-			      "Adding scsi host Failed ... exiting. %d\n",
-			      ret);
-
-		goto err_notify_unset;
-	}
-
 	spin_lock_irqsave(&snic_glob->snic_list_lock, flags);
 	list_add_tail(&snic->list, &snic_glob->snic_list);
 	spin_unlock_irqrestore(&snic_glob->snic_list_lock, flags);
@@ -676,8 +663,6 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	for (i = 0; i < snic->intr_count; i++)
 		svnic_intr_unmask(&snic->intr[i]);
 
-	snic_set_state(snic, SNIC_ONLINE);
-
 	/* Get snic params */
 	ret = snic_get_conf(snic);
 	if (ret) {
@@ -688,6 +673,21 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_get_conf;
 	}
 
+	/*
+	 * Initialization done with PCI system, hardware, firmware.
+	 * Add shost to SCSI
+	 */
+	ret = snic_add_host(shost, pdev);
+	if (ret) {
+		SNIC_HOST_ERR(shost,
+			      "Adding scsi host Failed ... exiting. %d\n",
+			      ret);
+
+		goto err_get_conf;
+	}
+
+	snic_set_state(snic, SNIC_ONLINE);
+
 	ret = snic_disc_start(snic);
 	if (ret) {
 		SNIC_HOST_ERR(shost, "snic_probe:Discovery Failed w err = %d\n",
@@ -712,6 +712,8 @@ err_req_intr:
 	svnic_dev_disable(snic->vdev);
 
 err_vdev_enable:
+	svnic_dev_notify_unset(snic->vdev);
+
 	for (i = 0; i < snic->wq_count; i++) {
 		int rc = 0;
 
@@ -725,9 +727,6 @@ err_vdev_enable:
 	}
 	snic_del_host(snic->shost);
 
-err_notify_unset:
-	svnic_dev_notify_unset(snic->vdev);
-
 err_free_tmreq_pool:
 	mempool_destroy(snic->req_pool[SNIC_REQ_TM_CACHE]);
 
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 8/8] snic: updating driver version
  2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
                   ` (5 preceding siblings ...)
  2016-03-17  7:51 ` [PATCH 7/8] snic: add scsi host after determining max IOs Narsimhulu Musini
@ 2016-03-17  7:51 ` Narsimhulu Musini
  6 siblings, 0 replies; 9+ messages in thread
From: Narsimhulu Musini @ 2016-03-17  7:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi, hare; +Cc: Narsimhulu Musini, Sesidhar Baddela

updated driver version to 0.0.1.26

Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
---
 drivers/scsi/snic/snic.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h
index 8ed778d..31cb20b 100644
--- a/drivers/scsi/snic/snic.h
+++ b/drivers/scsi/snic/snic.h
@@ -41,7 +41,7 @@
 
 #define SNIC_DRV_NAME		"snic"
 #define SNIC_DRV_DESCRIPTION	"Cisco SCSI NIC Driver"
-#define SNIC_DRV_VERSION	"0.0.1.18"
+#define SNIC_DRV_VERSION	"0.0.1.26"
 #define PFX			SNIC_DRV_NAME ":"
 #define DFX			SNIC_DRV_NAME "%d: "
 
-- 
1.8.5.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts
  2016-03-17  7:51 ` [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts Narsimhulu Musini
@ 2016-04-05  2:05   ` Martin K. Petersen
  0 siblings, 0 replies; 9+ messages in thread
From: Martin K. Petersen @ 2016-04-05  2:05 UTC (permalink / raw)
  To: Narsimhulu Musini; +Cc: James.Bottomley, linux-scsi, hare, Sesidhar Baddela

>>>>> "Narsimhulu" == Narsimhulu Musini <nmusini@cisco.com> writes:

Narsimhulu> - LUN goes offline, if there are atleast two scsi command
Narsimhulu> timeouts Completing the IO with scsi_done() fixes the issue.

Narsimhulu> Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Narsimhulu> Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com> ---
Narsimhulu> drivers/scsi/snic/snic_scsi.c | 18 ++++++++++++++++++ 1 file
Narsimhulu> changed, 18 insertions(+)

Applied patches 1-8 to to 4.7/scsi-queue.

Thanks!

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-04-05  2:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-17  7:51 [PATCH 1/8] snic: Added additional stats Narsimhulu Musini
2016-03-17  7:51 ` [PATCH 2/8] snic: LUN goes offline due to scsi cmd timeouts Narsimhulu Musini
2016-04-05  2:05   ` Martin K. Petersen
2016-03-17  7:51 ` [PATCH 3/8] snic: Handling control path queue issues Narsimhulu Musini
2016-03-17  7:51 ` [PATCH 4/8] snic: target cleanup in driver unload path Narsimhulu Musini
2016-03-17  7:51 ` [PATCH 5/8] snic: Fix for missing interrupts Narsimhulu Musini
2016-03-17  7:51 ` [PATCH 6/8] snic: Fixing race in the hba reset and IO/TM completion Narsimhulu Musini
2016-03-17  7:51 ` [PATCH 7/8] snic: add scsi host after determining max IOs Narsimhulu Musini
2016-03-17  7:51 ` [PATCH 8/8] snic: updating driver version Narsimhulu Musini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).