Skip to content

Commit

Permalink
libata: fix eh locking
Browse files Browse the repository at this point in the history
The SCSI host eh_cmd_q should be protected by the host lock (not the
port lock).  This probably doesn't matter that much at the moment,
since we try to serialise the add and eh pieces, but it might matter
in future for more convenient error handling.  Plus this switches
libata to the standard eh pattern where you lock, remove from the cmd
queue to a local list and unlock and then operate on the local list.

Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
James Bottomley authored and Jeff Garzik committed Mar 2, 2011
1 parent a29b5da commit c34aeeb
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,9 +589,14 @@ void ata_scsi_error(struct Scsi_Host *host)
struct ata_port *ap = ata_shost_to_port(host);
int i;
unsigned long flags;
LIST_HEAD(eh_work_q);

DPRINTK("ENTER\n");

spin_lock_irqsave(host->host_lock, flags);
list_splice_init(&host->eh_cmd_q, &eh_work_q);
spin_unlock_irqrestore(host->host_lock, flags);

/* make sure sff pio task is not running */
ata_sff_flush_pio_task(ap);

Expand Down Expand Up @@ -627,7 +632,7 @@ void ata_scsi_error(struct Scsi_Host *host)
if (ap->ops->lost_interrupt)
ap->ops->lost_interrupt(ap);

list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
list_for_each_entry_safe(scmd, tmp, &eh_work_q, eh_entry) {
struct ata_queued_cmd *qc;

for (i = 0; i < ATA_MAX_QUEUE; i++) {
Expand Down Expand Up @@ -762,7 +767,7 @@ void ata_scsi_error(struct Scsi_Host *host)
}

/* finish or retry handled scmd's and clean up */
WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
WARN_ON(host->host_failed || !list_empty(&eh_work_q));

scsi_eh_flush_done_q(&ap->eh_done_q);

Expand Down

0 comments on commit c34aeeb

Please sign in to comment.