diff mbox series

platform/x86: p2sb: Defer P2SB device scan when P2SB device has func 0

Message ID 20240301134504.1887132-1-shinichiro.kawasaki@wdc.com
State New
Headers show
Series platform/x86: p2sb: Defer P2SB device scan when P2SB device has func 0 | expand

Commit Message

Shinichiro Kawasaki March 1, 2024, 1:45 p.m. UTC
The commit 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls
during PCI device probe") triggered repeated ACPI errors on ASUS
VivoBook D540NV-GQ065T [1]. It was confirmed that the P2SB device scan
and remove at the fs_initcall stage triggered the errors.

To avoid the error, defer the P2SB device scan on the concerned device.
The error was observed on the system with Pentium N4200 in Goldmont micro-
architecture, and on which P2SB has function 0. Then refer to the P2SB
function to decide whether to defer or not.

When the device scan is deferred, do the scan later when p2sb_bar() is
called for the first time. If this first scan is triggered by sysfs
pci bus rescan, deadlock happens. In most cases, the scan happens during
system boot process, then there is no chance of deadlock.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=218531 [1]
Fixes: 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 drivers/platform/x86/p2sb.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

Comments

Andy Shevchenko March 1, 2024, 5:39 p.m. UTC | #1
On Fri, Mar 01, 2024 at 10:45:04PM +0900, Shin'ichiro Kawasaki wrote:
> The commit 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls
> during PCI device probe") triggered repeated ACPI errors on ASUS
> VivoBook D540NV-GQ065T [1]. It was confirmed that the P2SB device scan
> and remove at the fs_initcall stage triggered the errors.
> 
> To avoid the error, defer the P2SB device scan on the concerned device.
> The error was observed on the system with Pentium N4200 in Goldmont micro-
> architecture, and on which P2SB has function 0. Then refer to the P2SB
> function to decide whether to defer or not.
> 
> When the device scan is deferred, do the scan later when p2sb_bar() is
> called for the first time. If this first scan is triggered by sysfs
> pci bus rescan, deadlock happens. In most cases, the scan happens during
> system boot process, then there is no chance of deadlock.

...

> +static bool p2sb_resource_cached(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < NR_P2SB_RES_CACHE; i++)
> +		if (p2sb_valid_resource(&p2sb_resources[i].res))
> +			return true;
> +
> +	return false;
> +}

We don't need this. It's enough to check the cache for P2SB device itself...

...

> +	/*
> +	 * On ASUS VivoBook D540NV-GQ065T which has Goldmont CPU family Pentium
> +	 * N4200, P2SB device scan including function 0 at fs_initcall step

fs_initcall()

> +	 * causes ACPI errors. To avoid the errors, defer P2SB device scan and
> +	 * cache when P2SB devices has function 0.
> +	 */

> +	if (!p2sb_resource_cached())
> +		p2sb_cache_resources(false);

Move this after we new devfn of the P2SB and modify to something like

	if (!p2sb_valid_resources(...p2sb_devfn...))
		...
diff mbox series

Patch

diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
index 6bd14d0132db..3fd23f6b0a91 100644
--- a/drivers/platform/x86/p2sb.c
+++ b/drivers/platform/x86/p2sb.c
@@ -62,6 +62,17 @@  static bool p2sb_valid_resource(struct resource *res)
 	return false;
 }
 
+static bool p2sb_resource_cached(void)
+{
+	int i;
+
+	for (i = 0; i < NR_P2SB_RES_CACHE; i++)
+		if (p2sb_valid_resource(&p2sb_resources[i].res))
+			return true;
+
+	return false;
+}
+
 /* Copy resource from the first BAR of the device in question */
 static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem)
 {
@@ -133,7 +144,7 @@  static struct pci_bus *p2sb_get_bus(struct pci_bus *bus)
 	return p2sb_bus;
 }
 
-static int p2sb_cache_resources(void)
+static int p2sb_cache_resources(bool from_fs_init)
 {
 	unsigned int devfn_p2sb;
 	u32 value = P2SBC_HIDE;
@@ -150,6 +161,15 @@  static int p2sb_cache_resources(void)
 	if (!bus)
 		return -ENODEV;
 
+	/*
+	 * On ASUS VivoBook D540NV-GQ065T which has Goldmont CPU family Pentium
+	 * N4200, P2SB device scan including function 0 at fs_initcall step
+	 * causes ACPI errors. To avoid the errors, defer P2SB device scan and
+	 * cache when P2SB devices has function 0.
+	 */
+	if (PCI_FUNC(devfn_p2sb) == 0 && from_fs_init)
+		return -EBUSY;
+
 	/*
 	 * When a device with same devfn exists and its device class is not
 	 * PCI_CLASS_MEMORY_OTHER for P2SB, do not touch it.
@@ -203,6 +223,9 @@  int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
 	struct p2sb_res_cache *cache;
 	int ret;
 
+	if (!p2sb_resource_cached())
+		p2sb_cache_resources(false);
+
 	bus = p2sb_get_bus(bus);
 	if (!bus)
 		return -ENODEV;
@@ -227,7 +250,7 @@  EXPORT_SYMBOL_GPL(p2sb_bar);
 
 static int __init p2sb_fs_init(void)
 {
-	p2sb_cache_resources();
+	p2sb_cache_resources(true);
 	return 0;
 }