Short version:

Please test if this patch breaks suspend or hibernate on your
machine.  Reply with the results of your test and your dmesg.

Both are still working on my Lenovo Thinkpad X1 Carbon Gen 6.

Long version:

This patch converts the remaining tick sleeps in dev/acpi to
nanosecond sleeps.

In acpiec_wait() we have a tsleep(9) for up to 1 tick.  There is no
discernable unit in this code and no timeout so as with all the other
1 tick sleeps I think tsleep_nsec(9) for 1ms will work fine.  It may
oversleep 1ms but because there is no timeout it doesn't really
matter.

In acpi_event_wait() we have a timeout in milliseconds.  Currently we
sleep for up to 1 tick and deduct time from the timeout when the sleep
returns EWOULDBLOCK.  Of note here is that this code is broken on
kernels where hz > 1000: we will never time out.

I have changed the code to rwsleep_nsec(9) for at least 1ms.  The
timeout is in milliseconds so this seems logical to me.

The caveat is that on default HZ=100 kernels we will oversleep and it
will take much longer for us to time out in this loop.  We can fix
this by measuring the sleep and deducting the elapsed time from the
total timeout.  Or, if it doesn't really matter, we can just oversleep
and not worry about it.

Preferences?

Assuming we get no bad tests back, OK?

Index: acpiec.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpiec.c,v
retrieving revision 1.62
diff -u -p -r1.62 acpiec.c
--- acpiec.c    26 Aug 2020 03:29:06 -0000      1.62
+++ acpiec.c    20 Dec 2020 22:19:14 -0000
@@ -105,8 +105,10 @@ acpiec_wait(struct acpiec_softc *sc, uin
                        sc->sc_gotsci = 1;
                if (cold || (stat & EC_STAT_BURST))
                        delay(1);
-               else
-                       tsleep(&acpiecnowait, PWAIT, "acpiec", 1);
+               else {
+                       tsleep_nsec(&acpiecnowait, PWAIT, "acpiec",
+                           MSEC_TO_NSEC(1));
+               }
        }
 
        dnprintf(40, "%s: EC wait_ns, stat: %b\n", DEVNAME(sc), (int)stat,
Index: dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.257
diff -u -p -r1.257 dsdt.c
--- dsdt.c      17 Dec 2020 17:57:19 -0000      1.257
+++ dsdt.c      20 Dec 2020 22:19:15 -0000
@@ -2907,10 +2907,10 @@ acpi_event_wait(struct aml_scope *scope,
                if (acpi_dotask(acpi_softc))
                    continue;
                if (!cold) {
-                       if (rwsleep(evt, &acpi_softc->sc_lck, PWAIT,
-                           "acpievt", 1) == EWOULDBLOCK) {
+                       if (rwsleep_nsec(evt, &acpi_softc->sc_lck, PWAIT,
+                           "acpievt", MSEC_TO_NSEC(1)) == EWOULDBLOCK) {
                                if (timeout < AML_NO_TIMEOUT)
-                                       timeout -= (1000 / hz);
+                                       timeout--;
                        }
                } else {
                        delay(1000);

Reply via email to