[PATCH 7.1 042/271] pds_core: cancel pending PCI reset work on AER recovery

Greg Kroah-Hartman <[email protected]>
Newsgroups dev.linux.lists.patches,org.kernel.vger.stable
Message-ID <[email protected]>
7.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nikhil P. Rao <[email protected]>

[ Upstream commit 57d635329d799b79096155cdf47ee0013d6780d1 ]

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 <[email protected]>
Closes: https://sashiko.dev/#/patchset/20260714180223.1642792-2-nikhil.rao%40amd.com?part=1
Signed-off-by: Nikhil P. Rao <[email protected]>
Reviewed-by: Jacob Keller <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
 drivers/net/ethernet/amd/pds_core/main.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c
index 71a1d4b001c22..9a2c64198d03b 100644
--- a/drivers/net/ethernet/amd/pds_core/main.c
+++ b/drivers/net/ethernet/amd/pds_core/main.c
@@ -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;
 	}
 
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.