commit ea1723092d356dc4d1266942aa132340677e7460 Author: Don Brace Date: Wed Mar 3 11:21:59 2021 -0600 hpsa: correct dev cmd outstanding for retried cmds Prevent incrementing device->commands_outstanding for retried commands. diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index f4d3747cfa0b..43c8f7e25eb5 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()]; @@ -5623,6 +5626,16 @@ static void hpsa_command_resubmit_worker(struct work_struct *work) return hpsa_cmd_free_and_done(c->h, c, cmd); } + /* + * SML retries come in through queue_command and therefore + * go through cmd_tagged_alloc. So a new command. + * + * Set a retry_pending flag for a driver initiated retry attempt + * on an existing command to indicate to not increment the + * device->commands_outstanding when submitted. + */ + c->retry_pending = 1; + if (c->cmd_type == CMD_IOACCEL2) { struct ctlr_info *h = c->h; struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex]; @@ -5646,6 +5659,7 @@ static void hpsa_command_resubmit_worker(struct work_struct *work) } } hpsa_cmd_partial_init(c->h, c->cmdindex, c); + if (hpsa_ciss_submit(c->h, c, cmd, dev)) { /* * If we get here, it means dma mapping failed. Try @@ -5708,6 +5722,10 @@ 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) && @@ -6107,6 +6125,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) @@ -6141,6 +6160,11 @@ static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h, } atomic_inc(&c->refcount); + /* + * This is a new command obtained from queue_command so + * there have not been any driver initiated retry attempts. + */ + c->retry_pending = 0; hpsa_cmd_partial_init(h, idx, c); return c; @@ -6210,6 +6234,11 @@ 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 = 0; return c; } diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index 46df2e3ff89b..e86af4e9eef0 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; + int retry_pending; struct hpsa_scsi_dev_t *device; atomic_t refcount; /* Must be last to avoid memset in hpsa_cmd_init() */ } __aligned(COMMANDLIST_ALIGNMENT);