Skip to content

Commit aa0ae1c

Browse files
bvanasschefloatious
authored andcommitted
ata: libata: Fix ata_exec_internal()
Some but not all ata_exec_internal() calls happen from the context of the ATA error handler. Commit c0c362b ("libata: implement cross-port EH exclusion") added ata_eh_release() and ata_eh_acquire() calls in ata_exec_internal(). Calling these functions is necessary if the caller holds the eh_mutex but is not allowed if the caller doesn't hold that mutex. Fix this by only calling ata_eh_release() and ata_eh_acquire() if the caller holds the eh_mutex. An example of an indirect caller of ata_exec_internal() that does not hold the eh_mutex is ata_host_register(). Fixes: c0c362b ("libata: implement cross-port EH exclusion") Signed-off-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org>
1 parent fa0f667 commit aa0ae1c

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

drivers/ata/libata-core.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,7 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
15401540
{
15411541
struct ata_link *link = dev->link;
15421542
struct ata_port *ap = link->ap;
1543+
const bool owns_eh_mutex = ap->host->eh_owner == current;
15431544
u8 command = tf->command;
15441545
struct ata_queued_cmd *qc;
15451546
struct scatterlist sgl;
@@ -1617,11 +1618,25 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
16171618
}
16181619
}
16191620

1620-
ata_eh_release(ap);
1621+
if (owns_eh_mutex) {
1622+
/*
1623+
* To prevent that the compiler complains about the
1624+
* ata_eh_release() call below.
1625+
*/
1626+
__acquire(&ap->host->eh_mutex);
1627+
ata_eh_release(ap);
1628+
}
16211629

16221630
rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
16231631

1624-
ata_eh_acquire(ap);
1632+
if (owns_eh_mutex) {
1633+
ata_eh_acquire(ap);
1634+
/*
1635+
* To prevent that the compiler complains about the above
1636+
* ata_eh_acquire() call.
1637+
*/
1638+
__release(&ap->host->eh_mutex);
1639+
}
16251640

16261641
ata_sff_flush_pio_task(ap);
16271642

0 commit comments

Comments
 (0)