git: c76878c656e9 - stable/14 - acpi: Defer reserving resources for ACPI devices

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 23 Feb 2024 05:20:42 UTC
The branch stable/14 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=c76878c656e91aa595c2c81e86ac5adb59a15c98

commit c76878c656e91aa595c2c81e86ac5adb59a15c98
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-02-22 18:43:43 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-02-23 00:48:35 +0000

    acpi: Defer reserving resources for ACPI devices
    
    The goal of reserving firmware-assigned resources is to ensure that
    "wildcard" resource allocation requests will not claim an address
    range that is actually in use even if no attached driver is actively
    using that range.  However, the current approach can break in some
    cases.
    
    In particular, ACPI can enumerate devices behind PCI bridges that
    don't show up in a normal PCI scan, but those device_t objects can end
    up as direct children of acpi0.  Reserving resources for those devices
    directly from acpi0 ends up conflicting with later attempts to reserve
    the PCI bridge windows.
    
    As a workaround, defer reserving unclaimed resources until after the
    initial probe and attach scan.  Eventually this pass of reserving
    unclaimed resources can be moved earlier, but it requires changes to
    other drivers in the tree to permit enumerating devices and reserving
    firmware-assigned resources in a depth-first traversal before
    attaching devices whose drivers request wildcard allocations.
    
    PR:             272507
    Reported by:    Justin Tocci <justin@tocci.org>
    Reported by:    john@feith.com, many others
    Tested by:      Oleg Sidorkin <osidorkin@gmail.com>, dch
    
    (cherry picked from commit f2fcb68074a51a8b399dc80d4c03fbe98a0ab92c)
---
 sys/dev/acpica/acpi.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 7d1fc10afb9e..61df797c7393 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -1367,8 +1367,17 @@ acpi_sysres_alloc(device_t dev)
 }
 
 /*
- * Reserve declared resources for devices found during attach once system
- * resources have been allocated.
+ * Reserve declared resources for active devices found during the
+ * namespace scan once the boot-time attach of devices has completed.
+ *
+ * Ideally reserving firmware-assigned resources would work in a
+ * depth-first traversal of the device namespace, but this is
+ * complicated.  In particular, not all resources are enumerated by
+ * ACPI (e.g. PCI bridges and devices enumerate their resources via
+ * other means).  Some systems also enumerate devices via ACPI behind
+ * PCI bridges but without a matching a PCI device_t enumerated via
+ * PCI bus scanning, the device_t's end up as direct children of
+ * acpi0.  Doing this scan late is not ideal, but works for now.
  */
 static void
 acpi_reserve_resources(device_t dev)
@@ -2256,9 +2265,6 @@ acpi_probe_children(device_t bus)
     /* Pre-allocate resources for our rman from any sysresource devices. */
     acpi_sysres_alloc(bus);
 
-    /* Reserve resources already allocated to children. */
-    acpi_reserve_resources(bus);
-
     /* Create any static children by calling device identify methods. */
     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "device identify routines\n"));
     bus_generic_probe(bus);
@@ -2267,6 +2273,12 @@ acpi_probe_children(device_t bus)
     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "acpi bus_generic_attach\n"));
     bus_generic_attach(bus);
 
+    /*
+     * Reserve resources allocated to children but not yet allocated
+     * by a driver.
+     */
+    acpi_reserve_resources(bus);
+
     /* Attach wake sysctls. */
     acpi_wake_sysctl_walk(bus);