]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
PCI/ERR: Update device error_state already after reset
authorLukas Wunner <lukas@wunner.de>
Wed, 13 Aug 2025 05:11:04 +0000 (07:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:34:11 +0000 (15:34 -0500)
[ Upstream commit 45bc82563d5505327d97963bc54d3709939fa8f8 ]

After a Fatal Error has been reported by a device and has been recovered
through a Secondary Bus Reset, AER updates the device's error_state to
pci_channel_io_normal before invoking its driver's ->resume() callback.

By contrast, EEH updates the error_state earlier, namely after resetting
the device and before invoking its driver's ->slot_reset() callback.
Commit c58dc575f3c8 ("powerpc/pseries: Set error_state to
pci_channel_io_normal in eeh_report_reset()") explains in great detail
that the earlier invocation is necessitated by various drivers checking
accessibility of the device with pci_channel_offline() and avoiding
accesses if it returns true.  It returns true for any other error_state
than pci_channel_io_normal.

The device should be accessible already after reset, hence the reasoning
is that it's safe to update the error_state immediately afterwards.

This deviation between AER and EEH seems problematic because drivers
behave differently depending on which error recovery mechanism the
platform uses.  Three drivers have gone so far as to update the
error_state themselves, presumably to work around AER's behavior.

For consistency, amend AER to update the error_state at the same recovery
steps as EEH.  Drop the now unnecessary workaround from the three drivers.

Keep updating the error_state before ->resume() in case ->error_detected()
or ->mmio_enabled() return PCI_ERS_RESULT_RECOVERED, which causes
->slot_reset() to be skipped.  There are drivers doing this even for Fatal
Errors, e.g. mhi_pci_error_detected().

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/4517af6359ffb9d66152b827a5d2833459144e3f.1755008151.git.lukas@wunner.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/pci/pcie/err.c
drivers/scsi/qla2xxx/qla_os.c

index d7cdea8f604d08f6c6ca2b60d724c99e72ca4587..91e7b38143ead1e0dc559bb49f34e34e73bab6bb 100644 (file)
@@ -4215,7 +4215,6 @@ static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
        struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
        int err = 0;
 
-       pdev->error_state = pci_channel_io_normal;
        err = pci_enable_device(pdev);
        if (err)
                goto disconnect;
index b3588a1ebc25f466576f593f6178778730987f32..5e170400c61b96ae497d53f1718af738bd173d9e 100644 (file)
@@ -3767,8 +3767,6 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
        struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
        struct net_device *netdev = adapter->netdev;
 
-       pdev->error_state = pci_channel_io_normal;
-
        err = pci_enable_device(pdev);
        if (err)
                return err;
index 628d192de90b27af33ae75770148a0d649cc5f51..e277f3735fe65cff1b812d9aa18adaa16f46d70a 100644 (file)
@@ -141,7 +141,8 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
 
        device_lock(&dev->dev);
        pdrv = dev->driver;
-       if (!pdrv || !pdrv->err_handler || !pdrv->err_handler->slot_reset)
+       if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
+           !pdrv || !pdrv->err_handler || !pdrv->err_handler->slot_reset)
                goto out;
 
        err_handler = pdrv->err_handler;
index 31535beaaa161c315895546ea1b7124ef0ae1220..81c76678f25a822c5b6f1e32058f40346d9905ea 100644 (file)
@@ -7895,11 +7895,6 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev)
               "Slot Reset.\n");
 
        ha->pci_error_state = QLA_PCI_SLOT_RESET;
-       /* Workaround: qla2xxx driver which access hardware earlier
-        * needs error state to be pci_channel_io_online.
-        * Otherwise mailbox command timesout.
-        */
-       pdev->error_state = pci_channel_io_normal;
 
        pci_restore_state(pdev);