diff options
| author | Damien Le Moal <dlemoal@kernel.org> | 2026-02-20 12:09:12 +0900 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-03-13 17:20:49 +0100 |
| commit | 42ea6c476b2739c9acdf7120bd2d6ef9d0d78456 (patch) | |
| tree | 1f2edff707556e129562a6b6683d81177f25e82b | |
| parent | 08d9175578d6a8e9b81921898fbf01aa669cd2be (diff) | |
ata: libata-core: fix cancellation of a port deferred qc work
commit 55db009926634b20955bd8abbee921adbc8d2cb4 upstream.
cancel_work_sync() is a sleeping function so it cannot be called with
the spin lock of a port being held. Move the call to this function in
ata_port_detach() after EH completes, with the port lock released,
together with other work cancellation calls.
Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/ata/libata-core.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 42fbacd94a8a..237d8fd2a2cf 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6132,10 +6132,6 @@ static void ata_port_detach(struct ata_port *ap) } } - /* Make sure the deferred qc work finished. */ - cancel_work_sync(&ap->deferred_qc_work); - WARN_ON(ap->deferred_qc); - /* Tell EH to disable all devices */ ap->pflags |= ATA_PFLAG_UNLOADING; ata_port_schedule_eh(ap); @@ -6146,9 +6142,11 @@ static void ata_port_detach(struct ata_port *ap) /* wait till EH commits suicide */ ata_port_wait_eh(ap); - /* it better be dead now */ + /* It better be dead now and not have any remaining deferred qc. */ WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); + WARN_ON(ap->deferred_qc); + cancel_work_sync(&ap->deferred_qc_work); cancel_delayed_work_sync(&ap->hotplug_task); cancel_delayed_work_sync(&ap->scsi_rescan_task); |
