git: e5615cd8094f - main - acpi_spmc(4): INVARIANTS: Do not panic on getting constraints failure

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Wed, 13 May 2026 12:39:51 UTC
The branch main has been updated by olce:

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

commit e5615cd8094f75a17572b3dae810f48ae8401d6c
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2026-05-04 19:10:25 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2026-05-13 12:38:22 +0000

    acpi_spmc(4): INVARIANTS: Do not panic on getting constraints failure
    
    Just continue without constraints checking in this case.
    
    To this end, remove the 'constraints_populated' field from 'struct
    acpi_spmc_softc' and any reference to it.
    
    However, we introduce another boolean, 'sc->get_constraints_succeeded',
    in order to check (under INVARIANTS) that acpi_spmc_get_constraints() is
    called only once on success.  Calling that function another time after
    a success would leak memory.  It would be easy to change that function
    to support multiple calls (e.g., by adding a call to
    acpi_spmc_free_constraints() near its start), however trying to retrieve
    the constraints again simply looks like wasted time as the same results
    are expected to be returned on each call.
    
    Reviewed by:    imp, obiwac
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D56812
---
 sys/dev/acpica/acpi_spmc.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/sys/dev/acpica/acpi_spmc.c b/sys/dev/acpica/acpi_spmc.c
index 33915b536667..9a4264d6785b 100644
--- a/sys/dev/acpica/acpi_spmc.c
+++ b/sys/dev/acpica/acpi_spmc.c
@@ -223,7 +223,9 @@ struct acpi_spmc_softc {
 	struct eventhandler_entry	*eh_suspend;
 	struct eventhandler_entry	*eh_resume;
 
-	bool				constraints_populated;
+#ifdef INVARIANTS
+	bool				get_constraints_succeeded;
+#endif
 	size_t				constraint_count;
 	struct acpi_spmc_constraint	*constraints;
 };
@@ -488,8 +490,6 @@ acpi_spmc_parse_constraints_intel(struct acpi_spmc_softc *sc, ACPI_OBJECT *objec
 	ACPI_OBJECT	*detail;
 	ACPI_OBJECT	*constraint_package;
 
-	KASSERT(!sc->constraints_populated, ("Constraints already populated"));
-
 	sc->constraint_count = object->Package.Count;
 	sc->constraints = malloc(sc->constraint_count * sizeof *sc->constraints,
 	    M_TEMP, M_WAITOK | M_ZERO);
@@ -536,7 +536,6 @@ acpi_spmc_parse_constraints_intel(struct acpi_spmc_softc *sc, ACPI_OBJECT *objec
 		    constraint_package->Package.Elements[2].Integer.Value;
 	}
 
-	sc->constraints_populated = true;
 	return (0);
 }
 
@@ -549,8 +548,6 @@ acpi_spmc_parse_constraints_amd(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
 	struct acpi_spmc_constraint *constraint;
 	ACPI_OBJECT	*name_obj;
 
-	KASSERT(!sc->constraints_populated, ("Constraints already populated"));
-
 	/*
 	 * First element in the package is unknown.
 	 * Second element is the number of device constraints.
@@ -596,7 +593,6 @@ acpi_spmc_parse_constraints_amd(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
 		    constraint_obj->Package.Elements[3].Integer.Value;
 	}
 
-	sc->constraints_populated = true;
 	return (0);
 }
 
@@ -613,8 +609,8 @@ acpi_spmc_get_constraints(device_t dev)
 	struct acpi_spmc_constraint *constraint;
 
 	sc = device_get_softc(dev);
-	if (sc->constraints_populated)
-		return (0);
+
+	MPASS(!sc->get_constraints_succeeded);
 
 	/* The Microsoft DSM doesn't have this function. */
 	is_amd = has_dsm(sc, DSM_AMD);
@@ -651,6 +647,10 @@ acpi_spmc_get_constraints(device_t dev)
 			constraint->handle = NULL;
 		}
 	}
+
+#ifdef INVARIANTS
+	sc->get_constraints_succeeded = true;
+#endif
 	return (0);
 }
 
@@ -661,7 +661,6 @@ acpi_spmc_check_constraints(struct acpi_spmc_softc *sc)
 	bool violation = false;
 #endif
 
-	KASSERT(sc->constraints_populated, ("Constraints not populated"));
 	/*
 	 * Avoid printing that constraints are respected when there are no
 	 * constraints at all.