linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bjorn Helgaas <helgaas@kernel.org>
To: Heiner Kallweit <hkallweit1@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Jonathan Corbet <corbet@lwn.net>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-doc@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Sajid Dalvi <sdalvi@google.com>
Subject: Re: [PATCH net-next 1/2] timer: add fsleep for flexible sleeping
Date: Thu, 5 Aug 2021 08:06:16 -0500	[thread overview]
Message-ID: <20210805130616.GA1684372@bjorn-Precision-5520> (raw)
In-Reply-To: <5e3c3f78-344c-ae03-b6ae-ea55e402c1e7@gmail.com>

[+cc Andrew, Sajid, -cc Realtek NIC, David, netdev]

On Fri, May 01, 2020 at 11:27:21PM +0200, Heiner Kallweit wrote:
> Sleeping for a certain amount of time requires use of different
> functions, depending on the time period.
> Documentation/timers/timers-howto.rst explains when to use which
> function, and also checkpatch checks for some potentially
> problematic cases.
> 
> So let's create a helper that automatically chooses the appropriate
> sleep function -> fsleep(), for flexible sleeping
> 
> If the delay is a constant, then the compiler should be able to ensure
> that the new helper doesn't create overhead. If the delay is not
> constant, then the new helper can save some code.
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
>  Documentation/timers/timers-howto.rst |  3 +++
>  include/linux/delay.h                 | 11 +++++++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/Documentation/timers/timers-howto.rst b/Documentation/timers/timers-howto.rst
> index 7e3167bec..afb0a43b8 100644
> --- a/Documentation/timers/timers-howto.rst
> +++ b/Documentation/timers/timers-howto.rst
> @@ -110,3 +110,6 @@ NON-ATOMIC CONTEXT:
>  			short, the difference is whether the sleep can be ended
>  			early by a signal. In general, just use msleep unless
>  			you know you have a need for the interruptible variant.
> +
> +	FLEXIBLE SLEEPING (any delay, uninterruptible)
> +		* Use fsleep
> diff --git a/include/linux/delay.h b/include/linux/delay.h
> index 8e6828094..cb1d508ca 100644
> --- a/include/linux/delay.h
> +++ b/include/linux/delay.h
> @@ -65,4 +65,15 @@ static inline void ssleep(unsigned int seconds)
>  	msleep(seconds * 1000);
>  }
>  
> +/* see Documentation/timers/timers-howto.rst for the thresholds */
> +static inline void fsleep(unsigned long usecs)
> +{
> +	if (usecs <= 10)
> +		udelay(usecs);
> +	else if (usecs <= 20000)
> +		usleep_range(usecs, 2 * usecs);
> +	else
> +		msleep(DIV_ROUND_UP(usecs, 1000));
> +}

This is nice; I really like it because it's simpler for callers to
use.

timers-howto.rst and checkpatch advise to "use usleep_range() for the
1-20ms range" [1].  That's a very common sleep range, and making it a
special case makes things harder than they should be.  Supposedly this
is explained by the thread at [2], but I'm not really buying it.  That
thread was mostly about what the function name should be and whether
it should be implemented with timers.

AFAICT the only real argument there against making msleep() behave as
advertised for <20ms durations was that buggy drivers might depend on
msleep(1) really sleeping for ~20ms.  That's a real concern to be
sure, and Andrew apparently tripped over it [3].

But it's also a bug if msleep(1) *always* sleeps for 10-20ms, or if
the actual sleep changes drastically based on the arch or HZ.

There's a large class of 1-20ms sleeps that do things like this:

  usleep_range(1000, 2000);
  msleep(1);
  msleep(5);

that are either accurate but clumsy or inaccurate and unnecessarily
slow.  We could use fsleep() for them, but it's a little clumsy to
write "fsleep(5 * 1000)" all the time.

If we had something like this:

  static inline void fmsleep(unsigned int msecs)
  {
    fsleep(msecs * 1000);
  }

it seems like the advice could be simpler:

  - Use fsleep() for usec-range sleeps.
  - Use fmsleep() for msec-range sleeps.
  - Use usleep_range() for special cases.


[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/timers/timers-howto.rst?id=v5.13#n76
[2] https://lore.kernel.org/r/15327.1186166232@lwn.net
[3] https://lore.kernel.org/r/20070809001640.ec2f3bfb.akpm@linux-foundation.org/

  reply	other threads:[~2021-08-05 13:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-01 21:26 [PATCH net-next 0/2] timer: add fsleep for flexible sleeping Heiner Kallweit
2020-05-01 21:27 ` [PATCH net-next 1/2] " Heiner Kallweit
2021-08-05 13:06   ` Bjorn Helgaas [this message]
2020-05-01 21:29 ` [PATCH net-next 2/2] r8169: use fsleep in polling functions Heiner Kallweit
2020-05-07  0:04 ` [PATCH net-next 0/2] timer: add fsleep for flexible sleeping David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210805130616.GA1684372@bjorn-Precision-5520 \
    --to=helgaas@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=corbet@lwn.net \
    --cc=hkallweit1@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sdalvi@google.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).