Re: [RFC PATCH] timers: Optimize usleep_range()

From: John Stultz
Date: Mon May 23 2022 - 12:47:43 EST


On Sun, May 22, 2022 at 9:38 AM Christophe JAILLET
<christophe.jaillet@xxxxxxxxxx> wrote:
> diff --git a/include/linux/delay.h b/include/linux/delay.h
> index 039e7e0c7378..e84e7f9c1a47 100644
> --- a/include/linux/delay.h
> +++ b/include/linux/delay.h
> @@ -61,10 +61,23 @@ void msleep(unsigned int msecs);
> unsigned long msleep_interruptible(unsigned int msecs);
> void usleep_range_state(unsigned long min, unsigned long max,
> unsigned int state);
> +void __nsleep_range_delta_state(u64 min, u64 delta, unsigned int state);
>
> static inline void usleep_range(unsigned long min, unsigned long max)
> {
> - usleep_range_state(min, max, TASK_UNINTERRUPTIBLE);
> + /*
> + * Most of the time min and max are constant, so the time delta and the
> + * convertion to ns can be computed at compile time.
> + */
> + if (__builtin_constant_p(min) &&
> + __builtin_constant_p(max)) {
> + u64 delta = (u64)(max - min) * NSEC_PER_USEC;
> +
> + __nsleep_range_delta_state(min * NSEC_PER_USEC, delta,
> + TASK_UNINTERRUPTIBLE);
> + } else {
> + usleep_range_state(min, max, TASK_UNINTERRUPTIBLE);
> + }
> }

It seems the key optimization is just moving the multiplication to the
inlined header function, so rather than duplicating most of
usleep_range_state() in __nsleep_range_delta_state(), could you not
switch all uses of usleep_range_state() to use the
__nsleep_range_delta_state()? Then you don't need the
__buildint_constant_p() checks since the compiler can decide on its
own, no?


> +/**
> + * __nsleep_range_delta_state - Sleep for an approximate time in a given state
> + * @min: Minimum time in nsecs to sleep
> + * @delta: Maximum time in nsecs to sleep

I don't think that's the right value description here. Maybe this
should be the slack value?


thanks
-john