Skip to content

Commit f749d8b

Browse files
Don Bracemartinkpetersen
authored andcommitted
scsi: hpsa: Correct dev cmds outstanding for retried cmds
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. Link: https://lore.kernel.org/r/161342801747.29388.13045495968308188518.stgit@brunhilda Tested-by: Joe Szczypek <[email protected]> Reviewed-by: Scott Benesh <[email protected]> Reviewed-by: Scott Teel <[email protected]> Reviewed-by: Tomas Henzl <[email protected]> Signed-off-by: Don Brace <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent aaf15f8 commit f749d8b

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

drivers/scsi/hpsa.c

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,7 +1151,10 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
11511151
{
11521152
dial_down_lockup_detection_during_fw_flash(h, c);
11531153
atomic_inc(&h->commands_outstanding);
1154-
if (c->device)
1154+
/*
1155+
* Check to see if the command is being retried.
1156+
*/
1157+
if (c->device && !c->retry_pending)
11551158
atomic_inc(&c->device->commands_outstanding);
11561159

11571160
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,
55675570
}
55685571

55695572
static int hpsa_ioaccel_submit(struct ctlr_info *h,
5570-
struct CommandList *c, struct scsi_cmnd *cmd)
5573+
struct CommandList *c, struct scsi_cmnd *cmd,
5574+
bool retry)
55715575
{
55725576
struct hpsa_scsi_dev_t *dev = cmd->device->hostdata;
55735577
int rc = IO_ACCEL_INELIGIBLE;
@@ -5584,18 +5588,22 @@ static int hpsa_ioaccel_submit(struct ctlr_info *h,
55845588
cmd->host_scribble = (unsigned char *) c;
55855589

55865590
if (dev->offload_enabled) {
5587-
hpsa_cmd_init(h, c->cmdindex, c);
5591+
hpsa_cmd_init(h, c->cmdindex, c); /* Zeroes out all fields */
55885592
c->cmd_type = CMD_SCSI;
55895593
c->scsi_cmd = cmd;
55905594
c->device = dev;
5595+
if (retry) /* Resubmit but do not increment device->commands_outstanding. */
5596+
c->retry_pending = true;
55915597
rc = hpsa_scsi_ioaccel_raid_map(h, c);
55925598
if (rc < 0) /* scsi_dma_map failed. */
55935599
rc = SCSI_MLQUEUE_HOST_BUSY;
55945600
} else if (dev->hba_ioaccel_enabled) {
5595-
hpsa_cmd_init(h, c->cmdindex, c);
5601+
hpsa_cmd_init(h, c->cmdindex, c); /* Zeroes out all fields */
55965602
c->cmd_type = CMD_SCSI;
55975603
c->scsi_cmd = cmd;
55985604
c->device = dev;
5605+
if (retry) /* Resubmit but do not increment device->commands_outstanding. */
5606+
c->retry_pending = true;
55995607
rc = hpsa_scsi_ioaccel_direct_map(h, c);
56005608
if (rc < 0) /* scsi_dma_map failed. */
56015609
rc = SCSI_MLQUEUE_HOST_BUSY;
@@ -5628,7 +5636,8 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
56285636

56295637
if (c2->error_data.serv_response ==
56305638
IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL) {
5631-
rc = hpsa_ioaccel_submit(h, c, cmd);
5639+
/* Resubmit with the retry_pending flag set. */
5640+
rc = hpsa_ioaccel_submit(h, c, cmd, true);
56325641
if (rc == 0)
56335642
return;
56345643
if (rc == SCSI_MLQUEUE_HOST_BUSY) {
@@ -5644,6 +5653,15 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
56445653
}
56455654
}
56465655
hpsa_cmd_partial_init(c->h, c->cmdindex, c);
5656+
/*
5657+
* Here we have not come in though queue_command, so we
5658+
* can set the retry_pending flag to true for a driver initiated
5659+
* retry attempt (I.E. not a SML retry).
5660+
* I.E. We are submitting a driver initiated retry.
5661+
* Note: hpsa_ciss_submit does not zero out the command fields like
5662+
* ioaccel submit does.
5663+
*/
5664+
c->retry_pending = true;
56475665
if (hpsa_ciss_submit(c->h, c, cmd, dev)) {
56485666
/*
56495667
* 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)
57065724
/*
57075725
* Call alternate submit routine for I/O accelerated commands.
57085726
* Retries always go down the normal I/O path.
5727+
* Note: If cmd->retries is non-zero, then this is a SML
5728+
* initiated retry and not a driver initiated retry.
5729+
* This command has been obtained from cmd_tagged_alloc
5730+
* and is therefore a brand-new command.
57095731
*/
57105732
if (likely(cmd->retries == 0 &&
57115733
!blk_rq_is_passthrough(cmd->request) &&
57125734
h->acciopath_status)) {
5713-
rc = hpsa_ioaccel_submit(h, c, cmd);
5735+
/* Submit with the retry_pending flag unset. */
5736+
rc = hpsa_ioaccel_submit(h, c, cmd, false);
57145737
if (rc == 0)
57155738
return 0;
57165739
if (rc == SCSI_MLQUEUE_HOST_BUSY) {
@@ -6105,6 +6128,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
61056128
* at init, and managed by cmd_tagged_alloc() and cmd_tagged_free() using the
61066129
* block request tag as an index into a table of entries. cmd_tagged_free() is
61076130
* the complement, although cmd_free() may be called instead.
6131+
* This function is only called for new requests from queue_command.
61086132
*/
61096133
static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h,
61106134
struct scsi_cmnd *scmd)
@@ -6139,8 +6163,14 @@ static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h,
61396163
}
61406164

61416165
atomic_inc(&c->refcount);
6142-
61436166
hpsa_cmd_partial_init(h, idx, c);
6167+
6168+
/*
6169+
* This is a new command obtained from queue_command so
6170+
* there have not been any driver initiated retry attempts.
6171+
*/
6172+
c->retry_pending = false;
6173+
61446174
return c;
61456175
}
61466176

@@ -6208,6 +6238,13 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
62086238
}
62096239
hpsa_cmd_partial_init(h, i, c);
62106240
c->device = NULL;
6241+
6242+
/*
6243+
* cmd_alloc is for "internal" commands and they are never
6244+
* retried.
6245+
*/
6246+
c->retry_pending = false;
6247+
62116248
return c;
62126249
}
62136250

drivers/scsi/hpsa_cmd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ struct CommandList {
448448
*/
449449
struct hpsa_scsi_dev_t *phys_disk;
450450

451-
int abort_pending;
451+
bool retry_pending;
452452
struct hpsa_scsi_dev_t *device;
453453
atomic_t refcount; /* Must be last to avoid memset in hpsa_cmd_init() */
454454
} __aligned(COMMANDLIST_ALIGNMENT);

0 commit comments

Comments
 (0)