2021-04-30 23:28:26

by Shanker Donthineni

[permalink] [raw]
Subject: [PATCH v5 1/2] PCI: Add support for a function level reset based on _RST method

The _RST is a standard method specified in the ACPI specification. It
provides a function level reset when it is described in the acpi_device
context associated with PCI-device.

Implement a new reset function pci_dev_acpi_reset() for probing RST
method and execute if it is defined in the firmware. The ACPI binding
information is available only after calling device_add(), so move
pci_init_reset_methods() to end of the pci_device_add().

The default priority of the acpi reset is set to below device-specific
and above hardware resets.

Signed-off-by: Shanker Donthineni <[email protected]>
---
changes since v4:
- change acpi reset method name from 'acpi_reset' to 'acpi'
changes since v3:
- rebase patch on top of https://lore.kernel.org/linux-pci/[email protected]/
changes since v2:
- fix typo in the commit text

drivers/pci/pci.c | 30 ++++++++++++++++++++++++++++++
drivers/pci/probe.c | 2 +-
include/linux/pci.h | 2 +-
3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 664cf2d358d6..d39dba590583 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5076,6 +5076,35 @@ static void pci_dev_restore(struct pci_dev *dev)
err_handler->reset_done(dev);
}

+/**
+ * pci_dev_acpi_reset - do a function level reset using _RST method
+ * @dev: device to reset
+ * @probe: check if _RST method is included in the acpi_device context.
+ */
+static int pci_dev_acpi_reset(struct pci_dev *dev, int probe)
+{
+#ifdef CONFIG_ACPI
+ acpi_handle handle = ACPI_HANDLE(&dev->dev);
+
+ /* Return -ENOTTY if _RST method is not included in the dev context */
+ if (!handle || !acpi_has_method(handle, "_RST"))
+ return -ENOTTY;
+
+ /* Return 0 for probe phase indicating that we can reset this device */
+ if (probe)
+ return 0;
+
+ /* Invoke _RST() method to perform a function level reset */
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_RST", NULL, NULL))) {
+ pci_warn(dev, "Failed to reset the device\n");
+ return -EINVAL;
+ }
+ return 0;
+#else
+ return -ENOTTY;
+#endif
+}
+
/*
* The ordering for functions in pci_reset_fn_methods
* is required for reset_methods byte array defined
@@ -5083,6 +5112,7 @@ static void pci_dev_restore(struct pci_dev *dev)
*/
const struct pci_reset_fn_method pci_reset_fn_methods[] = {
{ .reset_fn = &pci_dev_specific_reset, .name = "device_specific" },
+ { .reset_fn = &pci_dev_acpi_reset, .name = "acpi" },
{ .reset_fn = &pcie_reset_flr, .name = "flr" },
{ .reset_fn = &pci_af_flr, .name = "af_flr" },
{ .reset_fn = &pci_pm_reset, .name = "pm" },
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4764e031a44b..d4becd6ffb52 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2403,7 +2403,6 @@ static void pci_init_capabilities(struct pci_dev *dev)
pci_rcec_init(dev); /* Root Complex Event Collector */

pcie_report_downtraining(dev);
- pci_init_reset_methods(dev);
}

/*
@@ -2494,6 +2493,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
dev->match_driver = false;
ret = device_add(&dev->dev);
WARN_ON(ret < 0);
+ pci_init_reset_methods(dev);
}

struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9f8347799634..b4a5d2146542 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -49,7 +49,7 @@
PCI_STATUS_SIG_TARGET_ABORT | \
PCI_STATUS_PARITY)

-#define PCI_RESET_FN_METHODS 5
+#define PCI_RESET_FN_METHODS 6

/*
* The PCI interface treats multi-function devices as independent
--
2.17.1


2021-04-30 23:29:24

by Shanker Donthineni

[permalink] [raw]
Subject: [PATCH v5 2/2] PCI: Enable NO_BUS_RESET quirk for Nvidia GPUs

On select platforms, some Nvidia GPU devices do not work with SBR.
Triggering SBR would leave the device inoperable for the current
system boot. It requires a system hard-reboot to get the GPU device
back to normal operating condition post-SBR. For the affected
devices, enable NO_BUS_RESET quirk to fix the issue.

This issue will be fixed in the next generation of hardware.

Signed-off-by: Shanker Donthineni <[email protected]>
---
Changes since v4:
- Move reset quirk next to the existing no_bus reset quirks
Changes since v1:
- Split patch into 2, code for handling _RST and SBR specific quirk
- The RST based reset is called as a first-class mechanism in the reset code path

drivers/pci/quirks.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 8f47d139c381..ceec67342365 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3558,6 +3558,18 @@ static void quirk_no_bus_reset(struct pci_dev *dev)
dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET;
}

+/*
+ * Some Nvidia GPU devices do not work with bus reset, SBR needs to be
+ * prevented for those affected devices.
+ */
+static void quirk_nvidia_no_bus_reset(struct pci_dev *dev)
+{
+ if ((dev->device & 0xffc0) == 0x2340)
+ quirk_no_bus_reset(dev);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+ quirk_nvidia_no_bus_reset);
+
/*
* Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset.
* The device will throw a Link Down error on AER-capable systems and
--
2.17.1

2021-05-03 02:27:10

by Sinan Kaya

[permalink] [raw]
Subject: Re: [PATCH v5 1/2] PCI: Add support for a function level reset based on _RST method

On 4/30/2021 7:26 PM, Shanker Donthineni wrote:
> The _RST is a standard method specified in the ACPI specification. It
> provides a function level reset when it is described in the acpi_device
> context associated with PCI-device.
>
> Implement a new reset function pci_dev_acpi_reset() for probing RST
> method and execute if it is defined in the firmware. The ACPI binding
> information is available only after calling device_add(), so move
> pci_init_reset_methods() to end of the pci_device_add().
>
> The default priority of the acpi reset is set to below device-specific
> and above hardware resets.
>
> Signed-off-by: Shanker Donthineni <[email protected]>

Reviewed-by: Sinan Kaya <[email protected]>

2021-05-03 02:29:04

by Sinan Kaya

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] PCI: Enable NO_BUS_RESET quirk for Nvidia GPUs

On 4/30/2021 7:26 PM, Shanker Donthineni wrote:
> On select platforms, some Nvidia GPU devices do not work with SBR.
> Triggering SBR would leave the device inoperable for the current
> system boot. It requires a system hard-reboot to get the GPU device
> back to normal operating condition post-SBR. For the affected
> devices, enable NO_BUS_RESET quirk to fix the issue.
>
> This issue will be fixed in the next generation of hardware.
>
> Signed-off-by: Shanker Donthineni <[email protected]>

Reviewed-by: Sinan Kaya <[email protected]>