]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
pds_core: cancel pending PCI reset work on AER recovery
authorNikhil P. Rao <nikhil.rao@amd.com>
Mon, 27 Jul 2026 17:00:30 +0000 (17:00 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 30 Jul 2026 23:44:26 +0000 (16:44 -0700)
pdsc_check_pci_health() queues pci_reset_work when it sees a broken PCI
connection, and nothing cancels it. When the PCI core starts AER
recovery, pdsc_pci_error_detected() runs pdsc_reset_prepare() and
recovers the device, but a pci_reset_work queued just before is left
pending. If it runs after recovery released the device lock, it resets a
device the driver now considers healthy, bouncing the link for no reason.

Cancel pci_reset_work in pdsc_pci_error_detected() after
pdsc_reset_prepare(), which has already stopped the health thread so it
cannot requeue the work. cancel_work_sync() is safe under the device
lock here because pdsc_pci_reset_thread() uses pci_try_reset_function(),
which returns instead of blocking on the lock. Only PFs initialize
pci_reset_work, so guard the cancel with !is_virtfn.

Fixes: 81665adf25d2 ("pds_core: Fix pdsc_check_pci_health function to use work thread")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260714180223.1642792-2-nikhil.rao%40amd.com?part=1
Signed-off-by: Nikhil P. Rao <nikhil.rao@amd.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20260727170030.361116-1-nikhil.rao@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amd/pds_core/main.c

index 71a1d4b001c22728c8975421e99684e37e2b0608..9a2c64198d03bb44c6c4f593169b48f1114051cd 100644 (file)
@@ -561,7 +561,11 @@ static pci_ers_result_t pdsc_pci_error_detected(struct pci_dev *pdev,
                                                pci_channel_state_t error)
 {
        if (error == pci_channel_io_frozen) {
+               struct pdsc *pdsc = pci_get_drvdata(pdev);
+
                pdsc_reset_prepare(pdev);
+               if (!pdev->is_virtfn)
+                       cancel_work_sync(&pdsc->pci_reset_work);
                return PCI_ERS_RESULT_NEED_RESET;
        }