linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] hpsa: correct dev cmds outstanding for retried cmds
@ 2021-02-15 22:26 Don Brace
  2021-02-23  3:44 ` Martin K. Petersen
  2021-02-26  2:22 ` Martin K. Petersen
  0 siblings, 2 replies; 3+ messages in thread
From: Don Brace @ 2021-02-15 22:26 UTC (permalink / raw)
  To: Kevin.Barnett, scott.teel, Justin.Lindley, scott.benesh,
	gerry.morong, mahesh.rajashekhara, hch, jejb, joseph.szczypek,
	POSWALD
  Cc: linux-scsi

Prevent incrementing device->commands_outstanding for
ioaccel command retries that are driver initiated.
If the command goes through the retry path,
the device->commands_outstanding counter has already
accounted for the number of commands outstanding to the device.
Only commands going through function hpsa_cmd_resolve_events
decrement this counter.
 * ioaccel commands go to either HBA disks or to logical volumes
   comprised of SSDs.

The extra increment is causing device resets to hang.
 * Resets wait for all device outstanding commands to complete
   before returning.

Replace unused field abort_pending with retry_pending.

This is a maintenance driver so these changes have the
least impact/risk.

Tested-by: Joe Szczypek <jszczype@redhat.com>

Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Don Brace <don.brace@microchip.com>
---
 drivers/scsi/hpsa.c     |   51 +++++++++++++++++++++++++++++++++++++++++------
 drivers/scsi/hpsa_cmd.h |    2 +-
 2 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 337d3aa91945..38369766511c 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1151,7 +1151,10 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
 {
 	dial_down_lockup_detection_during_fw_flash(h, c);
 	atomic_inc(&h->commands_outstanding);
-	if (c->device)
+	/*
+	 * Check to see if the command is being retried.
+	 */
+	if (c->device && !c->retry_pending)
 		atomic_inc(&c->device->commands_outstanding);
 
 	reply_queue = h->reply_map[raw_smp_processor_id()];
@@ -5567,7 +5570,8 @@ static inline void hpsa_cmd_partial_init(struct ctlr_info *h, int index,
 }
 
 static int hpsa_ioaccel_submit(struct ctlr_info *h,
-		struct CommandList *c, struct scsi_cmnd *cmd)
+		struct CommandList *c, struct scsi_cmnd *cmd,
+		bool retry)
 {
 	struct hpsa_scsi_dev_t *dev = cmd->device->hostdata;
 	int rc = IO_ACCEL_INELIGIBLE;
@@ -5584,18 +5588,22 @@ static int hpsa_ioaccel_submit(struct ctlr_info *h,
 	cmd->host_scribble = (unsigned char *) c;
 
 	if (dev->offload_enabled) {
-		hpsa_cmd_init(h, c->cmdindex, c);
+		hpsa_cmd_init(h, c->cmdindex, c); /* Zeroes out all fields */
 		c->cmd_type = CMD_SCSI;
 		c->scsi_cmd = cmd;
 		c->device = dev;
+		if (retry) /* Resubmit but do not increment device->commands_outstanding. */
+			c->retry_pending = true;
 		rc = hpsa_scsi_ioaccel_raid_map(h, c);
 		if (rc < 0)     /* scsi_dma_map failed. */
 			rc = SCSI_MLQUEUE_HOST_BUSY;
 	} else if (dev->hba_ioaccel_enabled) {
-		hpsa_cmd_init(h, c->cmdindex, c);
+		hpsa_cmd_init(h, c->cmdindex, c); /* Zeroes out all fields */
 		c->cmd_type = CMD_SCSI;
 		c->scsi_cmd = cmd;
 		c->device = dev;
+		if (retry) /* Resubmit but do not increment device->commands_outstanding. */
+			c->retry_pending = true;
 		rc = hpsa_scsi_ioaccel_direct_map(h, c);
 		if (rc < 0)     /* scsi_dma_map failed. */
 			rc = SCSI_MLQUEUE_HOST_BUSY;
@@ -5628,7 +5636,8 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
 
 		if (c2->error_data.serv_response ==
 				IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL) {
-			rc = hpsa_ioaccel_submit(h, c, cmd);
+			/* Resubmit with the retry_pending flag set. */
+			rc = hpsa_ioaccel_submit(h, c, cmd, true);
 			if (rc == 0)
 				return;
 			if (rc == SCSI_MLQUEUE_HOST_BUSY) {
@@ -5644,6 +5653,15 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
 		}
 	}
 	hpsa_cmd_partial_init(c->h, c->cmdindex, c);
+	/*
+	 * Here we have not come in though queue_command, so we
+	 * can set the retry_pending flag to true for a driver initiated
+	 * retry attempt (I.E. not a SML retry).
+	 * I.E. We are submitting a driver initiated retry.
+	 * Note: hpsa_ciss_submit does not zero out the command fields like
+	 *       ioaccel submit does.
+	 */
+	c->retry_pending = true;
 	if (hpsa_ciss_submit(c->h, c, cmd, dev)) {
 		/*
 		 * If we get here, it means dma mapping failed. Try
@@ -5706,11 +5724,16 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
 	/*
 	 * Call alternate submit routine for I/O accelerated commands.
 	 * Retries always go down the normal I/O path.
+	 * Note: If cmd->retries is non-zero, then this is a SML
+	 *       initiated retry and not a driver initiated retry.
+	 *       This command has been obtained from cmd_tagged_alloc
+	 *       and is therefore a brand-new command.
 	 */
 	if (likely(cmd->retries == 0 &&
 			!blk_rq_is_passthrough(cmd->request) &&
 			h->acciopath_status)) {
-		rc = hpsa_ioaccel_submit(h, c, cmd);
+		/* Submit with the retry_pending flag unset. */
+		rc = hpsa_ioaccel_submit(h, c, cmd, false);
 		if (rc == 0)
 			return 0;
 		if (rc == SCSI_MLQUEUE_HOST_BUSY) {
@@ -6105,6 +6128,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
  * at init, and managed by cmd_tagged_alloc() and cmd_tagged_free() using the
  * block request tag as an index into a table of entries.  cmd_tagged_free() is
  * the complement, although cmd_free() may be called instead.
+ * This function is only called for new requests from queue_command.
  */
 static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h,
 					    struct scsi_cmnd *scmd)
@@ -6139,8 +6163,14 @@ static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h,
 	}
 
 	atomic_inc(&c->refcount);
-
 	hpsa_cmd_partial_init(h, idx, c);
+
+	/*
+	 * This is a new command obtained from queue_command so
+	 * there have not been any driver initiated retry attempts.
+	 */
+	c->retry_pending = false;
+
 	return c;
 }
 
@@ -6208,6 +6238,13 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
 	}
 	hpsa_cmd_partial_init(h, i, c);
 	c->device = NULL;
+
+	/*
+	 * cmd_alloc is for "internal" commands and they are never
+	 * retried.
+	 */
+	c->retry_pending = false;
+
 	return c;
 }
 
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 46df2e3ff89b..d126bb877250 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -448,7 +448,7 @@ struct CommandList {
 	 */
 	struct hpsa_scsi_dev_t *phys_disk;
 
-	int abort_pending;
+	bool retry_pending;
 	struct hpsa_scsi_dev_t *device;
 	atomic_t refcount; /* Must be last to avoid memset in hpsa_cmd_init() */
 } __aligned(COMMANDLIST_ALIGNMENT);


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

* Re: [PATCH] hpsa: correct dev cmds outstanding for retried cmds
  2021-02-15 22:26 [PATCH] hpsa: correct dev cmds outstanding for retried cmds Don Brace
@ 2021-02-23  3:44 ` Martin K. Petersen
  2021-02-26  2:22 ` Martin K. Petersen
  1 sibling, 0 replies; 3+ messages in thread
From: Martin K. Petersen @ 2021-02-23  3:44 UTC (permalink / raw)
  To: Don Brace
  Cc: Kevin.Barnett, scott.teel, Justin.Lindley, scott.benesh,
	gerry.morong, mahesh.rajashekhara, hch, jejb, joseph.szczypek,
	POSWALD, linux-scsi


Don,

> Prevent incrementing device->commands_outstanding for ioaccel command
> retries that are driver initiated.

Applied to 5.12/scsi-staging, thanks!

-- 
Martin K. Petersen	Oracle Linux Engineering

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

* Re: [PATCH] hpsa: correct dev cmds outstanding for retried cmds
  2021-02-15 22:26 [PATCH] hpsa: correct dev cmds outstanding for retried cmds Don Brace
  2021-02-23  3:44 ` Martin K. Petersen
@ 2021-02-26  2:22 ` Martin K. Petersen
  1 sibling, 0 replies; 3+ messages in thread
From: Martin K. Petersen @ 2021-02-26  2:22 UTC (permalink / raw)
  To: Justin.Lindley, Kevin.Barnett, scott.teel, scott.benesh,
	Don Brace, joseph.szczypek, hch, jejb, POSWALD,
	mahesh.rajashekhara, gerry.morong
  Cc: Martin K . Petersen, linux-scsi

On Mon, 15 Feb 2021 16:26:57 -0600, Don Brace wrote:

> Prevent incrementing device->commands_outstanding for
> ioaccel command retries that are driver initiated.
> If the command goes through the retry path,
> the device->commands_outstanding counter has already
> accounted for the number of commands outstanding to the device.
> Only commands going through function hpsa_cmd_resolve_events
> decrement this counter.
>  * ioaccel commands go to either HBA disks or to logical volumes
>    comprised of SSDs.
> 
> [...]

Applied to 5.12/scsi-queue, thanks!

[1/1] hpsa: correct dev cmds outstanding for retried cmds
      https://git.kernel.org/mkp/scsi/c/f749d8b7a989

-- 
Martin K. Petersen	Oracle Linux Engineering

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

end of thread, other threads:[~2021-02-26  2:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-15 22:26 [PATCH] hpsa: correct dev cmds outstanding for retried cmds Don Brace
2021-02-23  3:44 ` Martin K. Petersen
2021-02-26  2:22 ` Martin K. Petersen

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).