Message ID | 5857066.DvuYhMxLoT@rjwysocki.net |
---|---|
State | New |
Headers | show |
Series | [v1] ACPI: OSL: Use usleep_range() in acpi_os_sleep() | expand |
On Thu, Dec 5, 2024 at 7:24 AM Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > > Add at least 50 us on top of the requested sleep time in case the > timer can be subject to coalescing, which is consistent with what's > done in user space in this context [2], but for sleeps longer than 5 ms > use 1% of the requested sleep time for this purpose. > > The rationale here is that longer sleeps don't need that much of a timer > precision as a rule and making the timer a more likely candidate for > coalescing in these cases is generally desirable. It starts at 5 ms so > that the delta between the requested sleep time and the effective > deadline is a contiuous function of the former. timerslack_ns defaults to 50,000 ns. So when a user invokes nanosleep(50ms), they get slacked out to 50.050 ms With this patch, if the AML BIOS programmer invokes Sleep(50ms), it gets slacked out to 50.500 ms -- a 10x longer slack period. I have not seen an explanation for why these cases should be treated differently. Len Brown, Intel Open Source Technology Center
Index: linux-pm/drivers/acpi/osl.c =================================================================== --- linux-pm.orig/drivers/acpi/osl.c +++ linux-pm/drivers/acpi/osl.c @@ -607,7 +607,27 @@ acpi_status acpi_os_remove_interrupt_han void acpi_os_sleep(u64 ms) { - msleep(ms); + u64 usec = ms * USEC_PER_MSEC, delta_us = 50; + + /* + * Use a hrtimer because the timer wheel timers are optimized for + * cancelation before they expire and this timer is not going to be + * canceled. + * + * Set the delta between the requested sleep time and the effective + * deadline to at least 50 us in case there is an opportunity for timer + * coalescing. + * + * Moreover, longer sleeps can be assumed to need somewhat less timer + * precision, so sacrifice some of it for making the timer a more likely + * candidate for coalescing by setting the delta to 1% of the sleep time + * if it is above 5 ms (this value is chosen so that the delta is a + * continuous function of the sleep time). + */ + if (ms > 5) + delta_us = (USEC_PER_MSEC / 100) * ms; + + usleep_range(usec, usec + delta_us); } void acpi_os_stall(u32 us)