Commit 4770e68d authored by Don Brace's avatar Don Brace Committed by Martin K. Petersen

scsi: hpsa: check for tag collision

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: default avatarJustin Lindley <justin.lindley@microsemi.com>
Reviewed-by: default avatarDavid Carroll <david.carroll@microsemi.com>
Reviewed-by: default avatarScott Teel <scott.teel@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 01192088
......@@ -5635,6 +5635,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.
......@@ -6041,7 +6043,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
......@@ -6049,13 +6050,19 @@ 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 (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;
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment