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);
 

Reply via email to