From: "Danilo Krummrich" <dakr@kernel.org>
To: "FUJITA Tomonori" <fujita.tomonori@gmail.com>
Cc: <linux-kernel@vger.kernel.org>, <daniel.almeida@collabora.com>,
<rust-for-linux@vger.kernel.org>, <netdev@vger.kernel.org>,
<andrew@lunn.ch>, <hkallweit1@gmail.com>, <tmgross@umich.edu>,
<ojeda@kernel.org>, <alex.gaynor@gmail.com>, <gary@garyguo.net>,
<bjorn3_gh@protonmail.com>, <benno.lossin@proton.me>,
<a.hindborg@samsung.com>, <aliceryhl@google.com>,
<anna-maria@linutronix.de>, <frederic@kernel.org>,
<tglx@linutronix.de>, <arnd@arndb.de>, <jstultz@google.com>,
<sboyd@kernel.org>, <mingo@redhat.com>, <peterz@infradead.org>,
<juri.lelli@redhat.com>, <vincent.guittot@linaro.org>,
<dietmar.eggemann@arm.com>, <rostedt@goodmis.org>,
<bsegall@google.com>, <mgorman@suse.de>, <vschneid@redhat.com>,
<tgunders@redhat.com>, <me@kloenk.dev>,
<david.laight.linux@gmail.com>
Subject: Re: [PATCH v11 7/8] rust: Add read_poll_timeout functions
Date: Sat, 02 Aug 2025 13:06:04 +0200 [thread overview]
Message-ID: <DBRW63AMB4D8.2HXGYM6FZRX3Z@kernel.org> (raw)
In-Reply-To: <20250802.104249.1482605492526656971.fujita.tomonori@gmail.com>
On Sat Aug 2, 2025 at 3:42 AM CEST, FUJITA Tomonori wrote:
> On Mon, 28 Jul 2025 15:13:45 +0200
> "Danilo Krummrich" <dakr@kernel.org> wrote:
>> On Thu Feb 20, 2025 at 8:06 AM CET, FUJITA Tomonori wrote:
>>> +/// This process continues until either `cond` returns `true` or the timeout,
>>> +/// specified by `timeout_delta`, is reached. If `timeout_delta` is `None`,
>>> +/// polling continues indefinitely until `cond` evaluates to `true` or an error occurs.
>>> +///
>>> +/// # Examples
>>> +///
>>> +/// ```rust,ignore
>>
>> Why ignore? This should be possible to compile test.
>
> https://lore.kernel.org/rust-for-linux/CEF87294-8580-4C84-BEA3-EB72E63ED7DF@collabora.com/
I disagree with that. 'ignore' should only be used if we can't make it compile.
In this case we can make it compile, we just can't run it, since there's no real
HW underneath that we can read registers from.
An example that isn't compiled will eventually be forgotten to be updated when
things are changed.
>>> +/// fn wait_for_hardware(dev: &mut Device) -> Result<()> {
>>
>> I think the parameter here can just be `&Io<SIZE>`.
>>
>>> +/// // The `op` closure reads the value of a specific status register.
>>> +/// let op = || -> Result<u16> { dev.read_ready_register() };
>>> +///
>>> +/// // The `cond` closure takes a reference to the value returned by `op`
>>> +/// // and checks whether the hardware is ready.
>>> +/// let cond = |val: &u16| *val == HW_READY;
>>> +///
>>> +/// match read_poll_timeout(op, cond, Delta::from_millis(50), Some(Delta::from_secs(3))) {
>>> +/// Ok(_) => {
>>> +/// // The hardware is ready. The returned value of the `op`` closure isn't used.
>>> +/// Ok(())
>>> +/// }
>>> +/// Err(e) => Err(e),
>>> +/// }
>>> +/// }
>>> +/// ```
>>> +///
>>> +/// ```rust
>>> +/// use kernel::io::poll::read_poll_timeout;
>>> +/// use kernel::time::Delta;
>>> +/// use kernel::sync::{SpinLock, new_spinlock};
>>> +///
>>> +/// let lock = KBox::pin_init(new_spinlock!(()), kernel::alloc::flags::GFP_KERNEL)?;
>>> +/// let g = lock.lock();
>>> +/// read_poll_timeout(|| Ok(()), |()| true, Delta::from_micros(42), Some(Delta::from_micros(42)));
>>> +/// drop(g);
>>> +///
>>> +/// # Ok::<(), Error>(())
>>> +/// ```
>>> +#[track_caller]
>>> +pub fn read_poll_timeout<Op, Cond, T>(
>>> + mut op: Op,
>>> + mut cond: Cond,
>>> + sleep_delta: Delta,
>>> + timeout_delta: Option<Delta>,
>>> +) -> Result<T>
>>> +where
>>> + Op: FnMut() -> Result<T>,
>>> + Cond: FnMut(&T) -> bool,
>>> +{
>>> + let start = Instant::now();
>>> + let sleep = !sleep_delta.is_zero();
>>> +
>>> + if sleep {
>>> + might_sleep();
>>> + }
>>
>> I think a conditional might_sleep() is not great.
>>
>> I also think we can catch this at compile time, if we add two different variants
>> of read_poll_timeout() instead and be explicit about it. We could get Klint to
>> catch such issues for us at compile time.
>
> Your point is that functions which cannot be used in atomic context
> should be clearly separated into different ones. Then Klint might be
> able to detect such usage at compile time, right?
>
> How about dropping the conditional might_sleep() and making
> read_poll_timeout return an error with zero sleep_delta?
Yes, let's always call might_sleep(), the conditional is very error prone. We
want to see the warning splat whenever someone calls read_poll_timeout() from
atomic context.
Yes, with zero sleep_delta it could be called from atomic context technically,
but if drivers rely on this and wrap this into higher level helpers it's very
easy to miss a subtle case and end up with non-zero sleep_delta within an atomic
context for some rare condition that then is hard to debug.
As for making read_poll_timeout() return a error with zero sleep_delta, I don't
see a reason to do that. If a driver wraps read_poll_timeout() in its own
function that sometimes sleeps and sometimes does not, based on some condition,
but is never called from atomic context, that's fine.
> Drivers which need busy-loop (without even udelay) can
> call read_poll_timeout_atomic() with zero delay.
It's not the zero delay or zero sleep_delta that makes the difference it's
really the fact the one can be called from atomic context and one can't be.
next prev parent reply other threads:[~2025-08-02 11:06 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-20 7:06 [PATCH v11 0/8] rust: Add IO polling FUJITA Tomonori
2025-02-20 7:06 ` [PATCH v11 1/8] sched/core: Add __might_sleep_precision() FUJITA Tomonori
2025-02-24 1:40 ` FUJITA Tomonori
2025-02-20 7:06 ` [PATCH v11 2/8] rust: time: Add PartialEq/Eq/PartialOrd/Ord trait to Ktime FUJITA Tomonori
2025-03-22 8:51 ` Andreas Hindborg
2025-02-20 7:06 ` [PATCH v11 3/8] rust: time: Introduce Delta type FUJITA Tomonori
2025-03-22 8:50 ` Andreas Hindborg
2025-02-20 7:06 ` [PATCH v11 4/8] rust: time: Introduce Instant type FUJITA Tomonori
2025-03-22 13:58 ` Andreas Hindborg
2025-04-03 4:40 ` FUJITA Tomonori
2025-04-03 10:41 ` Andreas Hindborg
2025-04-03 12:23 ` FUJITA Tomonori
2025-02-20 7:06 ` [PATCH v11 5/8] rust: time: Add wrapper for fsleep() function FUJITA Tomonori
2025-03-21 22:05 ` Frederic Weisbecker
2025-03-22 1:24 ` FUJITA Tomonori
2025-03-22 14:15 ` Andreas Hindborg
2025-03-22 14:10 ` Andreas Hindborg
2025-02-20 7:06 ` [PATCH v11 6/8] MAINTAINERS: rust: Add new sections for DELAY/SLEEP and TIMEKEEPING API FUJITA Tomonori
2025-03-20 19:05 ` Boqun Feng
2025-03-21 19:18 ` Andreas Hindborg
2025-03-21 20:38 ` Thomas Gleixner
2025-03-21 21:00 ` Boqun Feng
2025-03-22 2:07 ` FUJITA Tomonori
2025-03-22 12:57 ` Boqun Feng
2025-03-22 22:40 ` Andreas Hindborg
2025-03-31 14:03 ` Boqun Feng
2025-03-31 19:43 ` Andreas Hindborg
2025-04-03 8:18 ` FUJITA Tomonori
2025-04-03 10:54 ` Andreas Hindborg
2025-04-03 12:57 ` FUJITA Tomonori
2025-04-04 16:40 ` Boqun Feng
2025-04-02 14:16 ` FUJITA Tomonori
2025-04-02 16:29 ` Boqun Feng
2025-04-02 23:03 ` FUJITA Tomonori
2025-04-03 0:51 ` Boqun Feng
2025-04-03 3:02 ` FUJITA Tomonori
2025-04-03 3:17 ` Boqun Feng
2025-02-20 7:06 ` [PATCH v11 7/8] rust: Add read_poll_timeout functions FUJITA Tomonori
2025-02-20 15:04 ` Fiona Behrens
2025-02-21 11:20 ` FUJITA Tomonori
2025-03-22 16:02 ` Andreas Hindborg
2025-08-11 1:53 ` FUJITA Tomonori
2025-08-11 9:42 ` Andreas Hindborg
2025-08-14 5:53 ` FUJITA Tomonori
2025-07-28 12:44 ` Daniel Almeida
2025-07-28 12:52 ` FUJITA Tomonori
2025-07-28 12:57 ` Danilo Krummrich
2025-07-28 13:08 ` FUJITA Tomonori
2025-07-28 13:15 ` Danilo Krummrich
2025-07-28 14:13 ` Daniel Almeida
2025-07-28 14:30 ` Danilo Krummrich
2025-07-28 13:13 ` Danilo Krummrich
2025-08-02 1:42 ` FUJITA Tomonori
2025-08-02 11:06 ` Danilo Krummrich [this message]
2025-08-05 13:37 ` FUJITA Tomonori
2025-08-05 13:48 ` Danilo Krummrich
2025-08-05 13:53 ` Andrew Lunn
2025-08-05 14:03 ` Danilo Krummrich
2025-08-05 14:01 ` Daniel Almeida
2025-08-05 14:19 ` Danilo Krummrich
2025-02-20 7:06 ` [PATCH v11 8/8] net: phy: qt2025: Wait until PHY becomes ready FUJITA Tomonori
2025-02-27 17:29 ` [PATCH v11 0/8] rust: Add IO polling Daniel Almeida
2025-02-27 23:05 ` FUJITA Tomonori
2025-03-20 19:04 ` Boqun Feng
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=DBRW63AMB4D8.2HXGYM6FZRX3Z@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@samsung.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=andrew@lunn.ch \
--cc=anna-maria@linutronix.de \
--cc=arnd@arndb.de \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=bsegall@google.com \
--cc=daniel.almeida@collabora.com \
--cc=david.laight.linux@gmail.com \
--cc=dietmar.eggemann@arm.com \
--cc=frederic@kernel.org \
--cc=fujita.tomonori@gmail.com \
--cc=gary@garyguo.net \
--cc=hkallweit1@gmail.com \
--cc=jstultz@google.com \
--cc=juri.lelli@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=me@kloenk.dev \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sboyd@kernel.org \
--cc=tglx@linutronix.de \
--cc=tgunders@redhat.com \
--cc=tmgross@umich.edu \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
/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).