Skip to content

Commit

Permalink
[SCSI] qla2xxx: fix bad locking during eh_abort
Browse files Browse the repository at this point in the history
Correct incorrect locking order in qla2xxx_eh_abort() handler which
would case a hang during certain code-paths.

With extra pieces to fix the irq state in the locks.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Andrew Vasquez authored and James Bottomley committed Jun 3, 2005
1 parent cdbbde1 commit 18e144d
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
int ret, i;
unsigned int id, lun;
unsigned long serial;
unsigned long flags;

if (!CMD_SP(cmd))
return FAILED;
Expand All @@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)

/* Check active list for command command. */
spin_unlock_irq(ha->host->host_lock);
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
sp = ha->outstanding_cmds[i];

Expand All @@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
sp->state));
DEBUG3(qla2x00_print_scsi_cmd(cmd);)

spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (qla2x00_abort_command(ha, sp)) {
DEBUG2(printk("%s(%ld): abort_command "
"mbx failed.\n", __func__, ha->host_no));
Expand All @@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
"mbx success.\n", __func__, ha->host_no));
ret = SUCCESS;
}
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);

break;
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);

/* Wait for the command to be returned. */
if (ret == SUCCESS) {
spin_unlock(&ha->hardware_lock);
if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
qla_printk(KERN_ERR, ha,
"scsi(%ld:%d:%d): Abort handler timed out -- %lx "
"%x.\n", ha->host_no, id, lun, serial, ret);
}
spin_lock(&ha->hardware_lock);
}
spin_lock_irq(ha->host->host_lock);

Expand Down Expand Up @@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
int status;
srb_t *sp;
struct scsi_cmnd *cmd;
unsigned long flags;

status = 0;

Expand All @@ -596,19 +597,19 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
* array
*/
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
sp = ha->outstanding_cmds[cnt];
if (sp) {
cmd = sp->cmd;
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (cmd->device->id == t) {
if (!qla2x00_eh_wait_on_command(ha, cmd)) {
status = 1;
break;
}
}
} else {
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
}
return (status);
Expand Down Expand Up @@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
int status;
srb_t *sp;
struct scsi_cmnd *cmd;
unsigned long flags;

status = 1;

Expand All @@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
* array
*/
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
spin_lock(&ha->hardware_lock);
spin_lock_irqsave(&ha->hardware_lock, flags);
sp = ha->outstanding_cmds[cnt];
if (sp) {
cmd = sp->cmd;
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
status = qla2x00_eh_wait_on_command(ha, cmd);
if (status == 0)
break;
}
else {
spin_unlock(&ha->hardware_lock);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
}
return (status);
Expand Down

0 comments on commit 18e144d

Please sign in to comment.