- correct rare multipath issue where a device is deleted with an outstanding cmd which results in a tag collision. . The cmd eventually completes. If a collision is detected wait until the command slot is cleared. Reviewed-by: Justin Lindley <justin.lindley@xxxxxxxxxxxxx> Reviewed-by: David Carroll <david.carroll@xxxxxxxxxxxxx> Reviewed-by: Scott Teel <scott.teel@xxxxxxxxxxxxx> Signed-off-by: Don Brace <don.brace@xxxxxxxxxxxxx> --- drivers/scsi/hpsa.c | 21 ++++++++++++++------- drivers/scsi/hpsa.h | 1 + 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ade0d505a32c..a315d108fdcb 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -5620,6 +5620,8 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd) return 0; } c = cmd_tagged_alloc(h, cmd); + if (c == NULL) + return SCSI_MLQUEUE_DEVICE_BUSY; /* * Call alternate submit routine for I/O accelerated commands. @@ -6026,7 +6028,6 @@ static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h, BUG(); } - atomic_inc(&c->refcount); if (unlikely(!hpsa_is_cmd_idle(c))) { /* * We expect that the SCSI layer will hand us a unique tag @@ -6034,14 +6035,20 @@ static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h, * two requests...because if the selected command isn't idle * then someone is going to be very disappointed. */ - dev_err(&h->pdev->dev, - "tag collision (tag=%d) in cmd_tagged_alloc().\n", - idx); - if (c->scsi_cmd != NULL) - scsi_print_command(c->scsi_cmd); - scsi_print_command(scmd); + if (idx != h->last_collision_tag) { /* Print once per tag */ + dev_warn(&h->pdev->dev, + "%s: tag collision (tag=%d)\n", __func__, idx); + if (c->scsi_cmd != NULL) + scsi_print_command(c->scsi_cmd); + if (scmd) + scsi_print_command(scmd); + h->last_collision_tag = idx; + } + return NULL; } + atomic_inc(&c->refcount); + hpsa_cmd_partial_init(h, idx, c); return c; } diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 7aa7378f70dd..75210de71917 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -174,6 +174,7 @@ struct ctlr_info { struct CfgTable __iomem *cfgtable; int interrupts_enabled; int max_commands; + int last_collision_tag; /* tags are global */ atomic_t commands_outstanding; # define PERF_MODE_INT 0 # define DOORBELL_INT 1