]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ata: libata-core: fix cancellation of a port deferred qc work
authorDamien Le Moal <dlemoal@kernel.org>
Fri, 20 Feb 2026 03:09:12 +0000 (12:09 +0900)
committerDamien Le Moal <dlemoal@kernel.org>
Tue, 24 Feb 2026 00:38:55 +0000 (09:38 +0900)
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>
drivers/ata/libata-core.c

index 11909417f0178547149012edbf97e6a4382bd895..ccbf320524da7972b3533bbf9c22faf6da6f9a7b 100644 (file)
@@ -6269,10 +6269,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);
@@ -6283,9 +6279,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);