Hi, I was looking at fixing powerdown on the x260 Skylake machine and ran into the EC XXX comment from acpi_powerdown().
I think that grabbing the global lock before doing the AML calls is a good start. What we are missing now is incrementing the global_lock_count variable from the ACPI thread so that calls to acpi_glk_leave() take into account our hold of the lock. Should we make that a global variable and protect increments and decrements from acpi_glk_{enter,leave}? This way we could also increment it from acpi_powerdown() and that would put an end to this issue. Paul Index: acpi.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.313 diff -u -p -u -p -r1.313 acpi.c --- acpi.c 28 Jul 2016 21:57:56 -0000 1.313 +++ acpi.c 3 Aug 2016 10:12:15 -0000 @@ -2497,27 +2497,31 @@ fail_tts: return (error); } -/* XXX - * We are going to do AML execution but are not in the acpi thread. - * We do not know if the acpi thread is sleeping on acpiec in some - * intermediate context. Wish us luck. - */ void acpi_powerdown(void) { int state = ACPI_STATE_S5, s; struct acpi_softc *sc = acpi_softc; + int st = 0; if (acpi_enabled == 0) return; + /* + * We are going to do AML execution but are not in the acpi thread. + * Grab the global lock to make sure that the acpi thread is not + * sleeping on acpiec in some intermediate context. + */ + while (!st) + st = acpi_acquire_glk(&sc->sc_facs->global_lock); + s = splhigh(); disable_intr(); cold = 1; /* 1st powerdown AML step: _PTS(tostate) */ aml_node_setval(sc, sc->sc_pts, state); - + acpi_disable_allgpes(sc); acpi_enable_wakegpes(sc, state);