diff mbox series

[net-next,v1,1/2] rust: add delay abstraction

Message ID 20241001112512.4861-2-fujita.tomonori@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series add delay abstraction (sleep functions) | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 2 maintainers not CCed: walmeida@microsoft.com boqun.feng@gmail.com
netdev/build_clang success Errors and warnings before: 10 this patch: 10
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 44 this patch: 45
netdev/checkpatch warning WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
netdev/build_clang_rust fail Errors and warnings before: 14 this patch: 14
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

FUJITA Tomonori Oct. 1, 2024, 11:25 a.m. UTC
Add an abstraction for sleep functions in `include/linux/delay.h` for
dealing with hardware delays.

The kernel supports several `sleep` functions for handles various
lengths of delay. This adds fsleep helper function, internally calls
an appropriate sleep function.

This is used by QT2025 PHY driver to wait until a PHY becomes ready.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/bindings/bindings_helper.h |  1 +
 rust/helpers/delay.c            |  8 ++++++++
 rust/helpers/helpers.c          |  1 +
 rust/kernel/delay.rs            | 18 ++++++++++++++++++
 rust/kernel/lib.rs              |  1 +
 5 files changed, 29 insertions(+)
 create mode 100644 rust/helpers/delay.c
 create mode 100644 rust/kernel/delay.rs

Comments

Alice Ryhl Oct. 1, 2024, 11:33 a.m. UTC | #1
On Tue, Oct 1, 2024 at 1:27 PM FUJITA Tomonori
<fujita.tomonori@gmail.com> wrote:
>
> Add an abstraction for sleep functions in `include/linux/delay.h` for
> dealing with hardware delays.
>
> The kernel supports several `sleep` functions for handles various
> lengths of delay. This adds fsleep helper function, internally calls
> an appropriate sleep function.
>
> This is used by QT2025 PHY driver to wait until a PHY becomes ready.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
>  rust/bindings/bindings_helper.h |  1 +
>  rust/helpers/delay.c            |  8 ++++++++
>  rust/helpers/helpers.c          |  1 +
>  rust/kernel/delay.rs            | 18 ++++++++++++++++++
>  rust/kernel/lib.rs              |  1 +

There is already a rust/kernel/time.rs file that this can go in.

> +/// Sleeps for a given duration.
> +///
> +/// Equivalent to the kernel's [`fsleep`] function, internally calls `udelay`,
> +/// `usleep_range`, or `msleep`.
> +///
> +/// This function can only be used in a nonatomic context.
> +pub fn sleep(duration: Duration) {
> +    // SAFETY: FFI call.
> +    unsafe { bindings::fsleep(duration.as_micros() as c_ulong) }
> +}

We should probably call this `fsleep` to match the C side.

Alice
Andrew Lunn Oct. 1, 2024, 12:31 p.m. UTC | #2
On Tue, Oct 01, 2024 at 11:25:11AM +0000, FUJITA Tomonori wrote:
> Add an abstraction for sleep functions in `include/linux/delay.h` for
> dealing with hardware delays.
> 
> The kernel supports several `sleep` functions for handles various

s/for/which

> lengths of delay. This adds fsleep helper function, internally calls
> an appropriate sleep function.
> 
> This is used by QT2025 PHY driver to wait until a PHY becomes ready.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
>  rust/bindings/bindings_helper.h |  1 +
>  rust/helpers/delay.c            |  8 ++++++++
>  rust/helpers/helpers.c          |  1 +
>  rust/kernel/delay.rs            | 18 ++++++++++++++++++
>  rust/kernel/lib.rs              |  1 +
>  5 files changed, 29 insertions(+)
>  create mode 100644 rust/helpers/delay.c
>  create mode 100644 rust/kernel/delay.rs
> 
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> index ae82e9c941af..29a2f59294ba 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -10,6 +10,7 @@
>  #include <linux/blk-mq.h>
>  #include <linux/blk_types.h>
>  #include <linux/blkdev.h>
> +#include <linux/delay.h>
>  #include <linux/errname.h>
>  #include <linux/ethtool.h>
>  #include <linux/firmware.h>
> diff --git a/rust/helpers/delay.c b/rust/helpers/delay.c
> new file mode 100644
> index 000000000000..7ae64ad8141d
> --- /dev/null
> +++ b/rust/helpers/delay.c
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/delay.h>
> +
> +void rust_helper_fsleep(unsigned long usecs)
> +{
> +	fsleep(usecs);
> +}
> diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> index 30f40149f3a9..279ea662ee3b 100644
> --- a/rust/helpers/helpers.c
> +++ b/rust/helpers/helpers.c
> @@ -12,6 +12,7 @@
>  #include "build_assert.c"
>  #include "build_bug.c"
>  #include "err.c"
> +#include "delay.c"
>  #include "kunit.c"
>  #include "mutex.c"
>  #include "page.c"
> diff --git a/rust/kernel/delay.rs b/rust/kernel/delay.rs
> new file mode 100644
> index 000000000000..79f51a9608b5
> --- /dev/null
> +++ b/rust/kernel/delay.rs
> @@ -0,0 +1,18 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Delay and sleep routines.
> +//!
> +//! C headers: [`include/linux/delay.h`](srctree/include/linux/delay.h).
> +
> +use core::{ffi::c_ulong, time::Duration};
> +
> +/// Sleeps for a given duration.
> +///
> +/// Equivalent to the kernel's [`fsleep`] function, internally calls `udelay`,
> +/// `usleep_range`, or `msleep`.

Is it possible to cross reference
Documentation/timers/timers-howto.rst ?  fsleep() points to it, so it
would e good if the Rust version also did.

I would also document the units for the parameter. Is it picoseconds
or centuries?

	Andrew
Miguel Ojeda Oct. 1, 2024, 3:08 p.m. UTC | #3
On Tue, Oct 1, 2024 at 2:31 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> Is it possible to cross reference
> Documentation/timers/timers-howto.rst ?  fsleep() points to it, so it
> would e good if the Rust version also did.

We currently use links like:

    //! Reference: <https://docs.kernel.org/core-api/rbtree.html>

Cheers,
Miguel
FUJITA Tomonori Oct. 2, 2024, 11:34 a.m. UTC | #4
On Tue, 1 Oct 2024 14:31:39 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

> On Tue, Oct 01, 2024 at 11:25:11AM +0000, FUJITA Tomonori wrote:
>> Add an abstraction for sleep functions in `include/linux/delay.h` for
>> dealing with hardware delays.
>> 
>> The kernel supports several `sleep` functions for handles various
> 
> s/for/which

Oops, thanks.

>> +/// Sleeps for a given duration.
>> +///
>> +/// Equivalent to the kernel's [`fsleep`] function, internally calls `udelay`,
>> +/// `usleep_range`, or `msleep`.
> 
> Is it possible to cross reference
> Documentation/timers/timers-howto.rst ?  fsleep() points to it, so it
> would e good if the Rust version also did.
> 
> I would also document the units for the parameter. Is it picoseconds
> or centuries?

Rust's Duration is created from seconds and nanoseconds.
Andrew Lunn Oct. 2, 2024, 12:18 p.m. UTC | #5
> > I would also document the units for the parameter. Is it picoseconds
> > or centuries?
> 
> Rust's Duration is created from seconds and nanoseconds.

How well know is that? And is there a rust-for-linux wide preference
to use Duration for time? Are we going to get into a situation that
some abstractions use Duration, others seconds, some milliseconds,
etc, just like C code?

Anyway, i would still document the parameter is a Duration, since it
is different to how C fsleep() works.

	Andrew
Miguel Ojeda Oct. 2, 2024, 12:35 p.m. UTC | #6
On Wed, Oct 2, 2024 at 2:19 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> How well know is that? And is there a rust-for-linux wide preference
> to use Duration for time? Are we going to get into a situation that
> some abstractions use Duration, others seconds, some milliseconds,
> etc, just like C code?

We have `Ktime` that wraps `ktime_t`.

However, note that something like `Ktime` or `Duration` are types, not
a typedef, i.e. it is not an integer where you may confuse the unit.

So, for instance, the implementation here calls `as_micros()` to get
the actual integer. And whoever constructs e.g. a `Duration` has
several constructors to do so, not just the one that takes seconds and
nanoseconds, e.g. there is also `from_millis()`.

Perhaps we may end up needing different abstractions depending on what
we need (Cc'ing Thomas), but we will almost certainly want to still
use types like this, rather than plain integers or typedefs where
units can be confused.

> Anyway, i would still document the parameter is a Duration, since it
> is different to how C fsleep() works.

That is in the signature itself -- so taking into account what I
mentioned above, does it make sense that seeing the type in the
signature would be enough?

Cheers,
Miguel
Alice Ryhl Oct. 2, 2024, 12:37 p.m. UTC | #7
On Wed, Oct 2, 2024 at 2:19 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > > I would also document the units for the parameter. Is it picoseconds
> > > or centuries?
> >
> > Rust's Duration is created from seconds and nanoseconds.
>
> How well know is that? And is there a rust-for-linux wide preference
> to use Duration for time? Are we going to get into a situation that
> some abstractions use Duration, others seconds, some milliseconds,
> etc, just like C code?
>
> Anyway, i would still document the parameter is a Duration, since it
> is different to how C fsleep() works.

I'm not necessarily convinced we want to use the Rust Duration type.
Similar questions came up when I added the Ktime type. The Rust
Duration type is rather large.

Alice
Andrew Lunn Oct. 2, 2024, 12:51 p.m. UTC | #8
On Wed, Oct 02, 2024 at 02:35:57PM +0200, Miguel Ojeda wrote:
> On Wed, Oct 2, 2024 at 2:19 PM Andrew Lunn <andrew@lunn.ch> wrote:
> >
> > How well know is that? And is there a rust-for-linux wide preference
> > to use Duration for time? Are we going to get into a situation that
> > some abstractions use Duration, others seconds, some milliseconds,
> > etc, just like C code?
> 
> We have `Ktime` that wraps `ktime_t`.
> 
> However, note that something like `Ktime` or `Duration` are types, not
> a typedef, i.e. it is not an integer where you may confuse the unit.
> 
> So, for instance, the implementation here calls `as_micros()` to get
> the actual integer. And whoever constructs e.g. a `Duration` has
> several constructors to do so, not just the one that takes seconds and
> nanoseconds, e.g. there is also `from_millis()`.
> 
> Perhaps we may end up needing different abstractions depending on what
> we need (Cc'ing Thomas), but we will almost certainly want to still
> use types like this, rather than plain integers or typedefs where
> units can be confused.
> 
> > Anyway, i would still document the parameter is a Duration, since it
> > is different to how C fsleep() works.
> 
> That is in the signature itself -- so taking into account what I
> mentioned above, does it make sense that seeing the type in the
> signature would be enough?

Which is better, the Rust type system catching the error, or not
making the error in the first place because you read the documentation
and it pointed you in the right direction?

Maybe this is my background as a C programmer, with its sloppy type
system, but i prefer to have this very clear, maybe redundantly
stating it in words in addition to the signature.

	Andrew
Miguel Ojeda Oct. 2, 2024, 1:21 p.m. UTC | #9
On Wed, Oct 2, 2024 at 2:51 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> Which is better, the Rust type system catching the error, or not
> making the error in the first place because you read the documentation
> and it pointed you in the right direction?

The former, because we don't want to duplicate documentation of every
type in every function that uses a type. It does not scale, and it
would be worse for the reader of the docs as soon as you become
familiar with a given type.

Of course, there may be exceptions, but just using a type normally
should not require explaining the type itself in every function.

Also note that in e.g. the rendered docs you can jump to another type
with a single click on top of the name. In some editors, you may be
able to e.g. hover it perhaps.

> Maybe this is my background as a C programmer, with its sloppy type
> system, but i prefer to have this very clear, maybe redundantly
> stating it in words in addition to the signature.

The second part of my message was about the signature point you made,
i.e. not about the units. So I am not sure if you are asking here to
re-state the types of parameters in every function's docs -- what do
you gain from that in common cases?

We also don't repeat every parameter in a bullet list inside the
documentation to explain each parameter, unless a parameter needs it
for a particular reason. In general, the stronger/stricter your
types/signatures are, and the better documented your types are, the
less "extra notes" in every function you need.

For instance, if you see `int` in a signature, then you very likely
need documentation to understand how the argument works because `int`
is way too general (e.g. it is likely it admits cases you are not
supposed to use). However, if you see `Duration`, then you already
know the answer to the units question.

Thus, in a way, we are factoring out documentation to a single place,
thus making them simpler/easier/lighter -- so you can see it as a way
to scale writing docs! :)

That is also why carrying as much information in the signature also
helps with docs, and not just with having the compiler catch mistakes
for us.

I hope this gives some context on why we are approaching it like this.

Cheers,
Miguel
FUJITA Tomonori Oct. 2, 2024, 1:58 p.m. UTC | #10
On Wed, 2 Oct 2024 14:37:55 +0200
Alice Ryhl <aliceryhl@google.com> wrote:

> On Wed, Oct 2, 2024 at 2:19 PM Andrew Lunn <andrew@lunn.ch> wrote:
>>
>> > > I would also document the units for the parameter. Is it picoseconds
>> > > or centuries?
>> >
>> > Rust's Duration is created from seconds and nanoseconds.
>>
>> How well know is that? And is there a rust-for-linux wide preference
>> to use Duration for time? Are we going to get into a situation that
>> some abstractions use Duration, others seconds, some milliseconds,
>> etc, just like C code?
>>
>> Anyway, i would still document the parameter is a Duration, since it
>> is different to how C fsleep() works.
> 
> I'm not necessarily convinced we want to use the Rust Duration type.
> Similar questions came up when I added the Ktime type. The Rust
> Duration type is rather large.

core::mem::size_of::<core::time::Duration>() says 16 bytes.

You prefer to add a simpler Duration structure to kernel/time.rs?
Something like:

struct Duration {
    nanos: u64,
}

u64 in nanoseconds is enough for delay in the kernel, I think.


btw, core::time::Duration::new() could panic if a driver does
something stupid; for example,

let d = core::time::Duration::new(u64::MAX, 1_000_000_000);

Is this acceptable?
Alice Ryhl Oct. 2, 2024, 2:27 p.m. UTC | #11
On Wed, Oct 2, 2024 at 3:58 PM FUJITA Tomonori
<fujita.tomonori@gmail.com> wrote:
>
> On Wed, 2 Oct 2024 14:37:55 +0200
> Alice Ryhl <aliceryhl@google.com> wrote:
>
> > On Wed, Oct 2, 2024 at 2:19 PM Andrew Lunn <andrew@lunn.ch> wrote:
> >>
> >> > > I would also document the units for the parameter. Is it picoseconds
> >> > > or centuries?
> >> >
> >> > Rust's Duration is created from seconds and nanoseconds.
> >>
> >> How well know is that? And is there a rust-for-linux wide preference
> >> to use Duration for time? Are we going to get into a situation that
> >> some abstractions use Duration, others seconds, some milliseconds,
> >> etc, just like C code?
> >>
> >> Anyway, i would still document the parameter is a Duration, since it
> >> is different to how C fsleep() works.
> >
> > I'm not necessarily convinced we want to use the Rust Duration type.
> > Similar questions came up when I added the Ktime type. The Rust
> > Duration type is rather large.
>
> core::mem::size_of::<core::time::Duration>() says 16 bytes.
>
> You prefer to add a simpler Duration structure to kernel/time.rs?
> Something like:
>
> struct Duration {
>     nanos: u64,
> }
>
> u64 in nanoseconds is enough for delay in the kernel, I think.

That type already exists. It's called kernel::time::Ktime.

Alice
FUJITA Tomonori Oct. 2, 2024, 2:40 p.m. UTC | #12
On Wed, 2 Oct 2024 16:27:17 +0200
Alice Ryhl <aliceryhl@google.com> wrote:

>> You prefer to add a simpler Duration structure to kernel/time.rs?
>> Something like:
>>
>> struct Duration {
>>     nanos: u64,
>> }
>>
>> u64 in nanoseconds is enough for delay in the kernel, I think.
> 
> That type already exists. It's called kernel::time::Ktime.

Sure. Some code use ktime_t to represent duration so using Ktime for
the delay functions makes sense. I'll add some methods to Ktime and
use it.

Thanks!
Miguel Ojeda Oct. 2, 2024, 2:52 p.m. UTC | #13
On Wed, Oct 2, 2024 at 4:40 PM FUJITA Tomonori
<fujita.tomonori@gmail.com> wrote:
>
> Sure. Some code use ktime_t to represent duration so using Ktime for
> the delay functions makes sense. I'll add some methods to Ktime and
> use it.

We really should still use different types to represent points and
deltas, even if internally they happen to end up using/being the
"same" thing.

If we start mixing those two up, then it will be harder to unravel later.

I think Thomas also wanted to have two types, please see this thread:
https://lore.kernel.org/rust-for-linux/87h6vfnh0f.ffs@tglx/ (we also
discussed clocks).

Cheers,
Miguel
Thomas Gleixner Oct. 2, 2024, 7:40 p.m. UTC | #14
On Wed, Oct 02 2024 at 16:52, Miguel Ojeda wrote:
> On Wed, Oct 2, 2024 at 4:40 PM FUJITA Tomonori
> <fujita.tomonori@gmail.com> wrote:
>>
>> Sure. Some code use ktime_t to represent duration so using Ktime for
>> the delay functions makes sense. I'll add some methods to Ktime and
>> use it.
>
> We really should still use different types to represent points and
> deltas, even if internally they happen to end up using/being the
> "same" thing.
>
> If we start mixing those two up, then it will be harder to unravel later.
>
> I think Thomas also wanted to have two types, please see this thread:
> https://lore.kernel.org/rust-for-linux/87h6vfnh0f.ffs@tglx/ (we also
> discussed clocks).

Correct. They are distinct.

Btw, why is this sent to netdev and not to LKML? delay is generic code
and has nothing to do with networking.

Thanks,

        tglx
Thomas Gleixner Oct. 2, 2024, 8:04 p.m. UTC | #15
On Wed, Oct 02 2024 at 15:21, Miguel Ojeda wrote:
> On Wed, Oct 2, 2024 at 2:51 PM Andrew Lunn <andrew@lunn.ch> wrote:
>> Maybe this is my background as a C programmer, with its sloppy type
>> system, but i prefer to have this very clear, maybe redundantly
>> stating it in words in addition to the signature.
>
> The second part of my message was about the signature point you made,
> i.e. not about the units. So I am not sure if you are asking here to
> re-state the types of parameters in every function's docs -- what do
> you gain from that in common cases?
>
> We also don't repeat every parameter in a bullet list inside the
> documentation to explain each parameter, unless a parameter needs it
> for a particular reason. In general, the stronger/stricter your
> types/signatures are, and the better documented your types are, the
> less "extra notes" in every function you need.
>
> For instance, if you see `int` in a signature, then you very likely
> need documentation to understand how the argument works because `int`
> is way too general (e.g. it is likely it admits cases you are not
> supposed to use). However, if you see `Duration`, then you already
> know the answer to the units question.
>
> Thus, in a way, we are factoring out documentation to a single place,
> thus making them simpler/easier/lighter -- so you can see it as a way
> to scale writing docs! :)
>
> That is also why carrying as much information in the signature also
> helps with docs, and not just with having the compiler catch mistakes
> for us.

I completely agree.

'delay(Duration d)' does not need explanation for @d unless there is a
restriction for the valid range of @d. @d is explained in the
documentation of Duration.

That's not any different in C, when the function argument is a pointer
to a complex struct. Nobody would even think about explaining the struct
members in the documentation of the function which has that struct
pointer argument. No, you need to go to the struct declaration to figure
it out.

Redundant documentation is actually bad, because any changes to the type
will inevitably lead to stale documentation at the usage site. The
kernel is full of this.

I havent's seen the actual patches as they were sent to netdev for
whatever reason. There is a larger rework of delay.h going on:

  https://lore.kernel.org/all/20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de/

V3 will be coming early next week. So please look at V2 if you have any
constraints vs. the rust implementation.

Thanks,

        tglx
FUJITA Tomonori Oct. 3, 2024, 1:24 a.m. UTC | #16
On Wed, 02 Oct 2024 21:40:45 +0200
Thomas Gleixner <tglx@linutronix.de> wrote:

> On Wed, Oct 02 2024 at 16:52, Miguel Ojeda wrote:
>> On Wed, Oct 2, 2024 at 4:40 PM FUJITA Tomonori
>> <fujita.tomonori@gmail.com> wrote:
>>>
>>> Sure. Some code use ktime_t to represent duration so using Ktime for
>>> the delay functions makes sense. I'll add some methods to Ktime and
>>> use it.
>>
>> We really should still use different types to represent points and
>> deltas, even if internally they happen to end up using/being the
>> "same" thing.
>>
>> If we start mixing those two up, then it will be harder to unravel later.
>>
>> I think Thomas also wanted to have two types, please see this thread:
>> https://lore.kernel.org/rust-for-linux/87h6vfnh0f.ffs@tglx/ (we also
>> discussed clocks).
> 
> Correct. They are distinct.

Understood. I'll add a new type, time::Delta. Any alternative name
suggestions?

> Btw, why is this sent to netdev and not to LKML? delay is generic code
> and has nothing to do with networking.

Rust abstractions are typically merged with their users. I'm trying to
push the delay abstractions with a fix for QT2025 PHY driver
(drivers/net/phy/qt2025.rs), which uses delay.

Sorry, I'll send v2 to timers maintainers too.
Miguel Ojeda Oct. 3, 2024, 10:50 a.m. UTC | #17
On Thu, Oct 3, 2024 at 3:24 AM FUJITA Tomonori
<fujita.tomonori@gmail.com> wrote:
>
> Rust abstractions are typically merged with their users. I'm trying to
> push the delay abstractions with a fix for QT2025 PHY driver
> (drivers/net/phy/qt2025.rs), which uses delay.

To clarify, in case it helps: users indeed drive the need for
abstractions (i.e. we don't merge abstractions without an expected
user), and it can happen that they go together in the same patch
series for convenience, that is true.

However, I don't think I would say "typically", since most
abstractions went in on their own so far, and each patch still needs
to Cc the relevant maintainers/lists and the respective maintainers
should say they are OK moving it through another tree.

In other words, the "default" is that the abstractions go through
their tree, i.e. delay wouldn't go through netdev, unless the
maintainers are OK with that (e.g. perhaps because it is simpler in a
given case).

I have some more notes at
https://rust-for-linux.com/contributing#the-rust-subsystem.

Of course, in most cases to review abstractions it helps seeing the
expected user, so sometimes it may help to show the users in the same
patch series, and sometimes it may make more sense to just add a link
to Lore to the user, or to a branch; and sometimes examples in the
commit message or in the abstractions' docs themselves are enough.

Cheers,
Miguel
Andrew Lunn Oct. 3, 2024, 12:33 p.m. UTC | #18
On Thu, Oct 03, 2024 at 12:50:51PM +0200, Miguel Ojeda wrote:
> On Thu, Oct 3, 2024 at 3:24 AM FUJITA Tomonori
> <fujita.tomonori@gmail.com> wrote:
> >
> > Rust abstractions are typically merged with their users. I'm trying to
> > push the delay abstractions with a fix for QT2025 PHY driver
> > (drivers/net/phy/qt2025.rs), which uses delay.
> 
> To clarify, in case it helps: users indeed drive the need for
> abstractions (i.e. we don't merge abstractions without an expected
> user), and it can happen that they go together in the same patch
> series for convenience, that is true.
> 
> However, I don't think I would say "typically", since most
> abstractions went in on their own so far

Looking at the kernel as a whole, i would say that is actually
atypical. Rust is being somewhat special here. But it also seems to be
agreed on that this is O.K.

> In other words, the "default" is that the abstractions go through
> their tree, i.e. delay wouldn't go through netdev, unless the
> maintainers are OK with that (e.g. perhaps because it is simpler in a
> given case).

In this case, the fdelay() binding should be simple enough that i
think we can use the normal mechanism of merging it via netdev, so
long as the other subsystem Maintainer gives an Acked-by: But we can
also pull a stable branch into netdev if we need to.

A Rust equivalent of iopoll.h is going to be a bit more interesting.

./scripts/get_maintainer.pl -f include/linux/iopoll.h 
linux-kernel@vger.kernel.org (open list)

i.e. it does not have a Maintainer!

Looking at the Acked-by:s i would keep Arnd Bergmann <arnd@arndb.de>
in the loop.

	Andrew
FUJITA Tomonori Oct. 4, 2024, 12:08 p.m. UTC | #19
On Tue, 1 Oct 2024 14:31:39 +0200
Andrew Lunn <andrew@lunn.ch> wrote:

>> +/// Sleeps for a given duration.
>> +///
>> +/// Equivalent to the kernel's [`fsleep`] function, internally calls `udelay`,
>> +/// `usleep_range`, or `msleep`.
> 
> Is it possible to cross reference
> Documentation/timers/timers-howto.rst ?  fsleep() points to it, so it
> would e good if the Rust version also did.

Looks like the pointer to Documentation/timers/timers-howto.rst in
fsleep will be removed soon.

https://lore.kernel.org/all/20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de/
Andrew Lunn Oct. 4, 2024, 2:08 p.m. UTC | #20
On Fri, Oct 04, 2024 at 09:08:19PM +0900, FUJITA Tomonori wrote:
> On Tue, 1 Oct 2024 14:31:39 +0200
> Andrew Lunn <andrew@lunn.ch> wrote:
> 
> >> +/// Sleeps for a given duration.
> >> +///
> >> +/// Equivalent to the kernel's [`fsleep`] function, internally calls `udelay`,
> >> +/// `usleep_range`, or `msleep`.
> > 
> > Is it possible to cross reference
> > Documentation/timers/timers-howto.rst ?  fsleep() points to it, so it
> > would e good if the Rust version also did.
> 
> Looks like the pointer to Documentation/timers/timers-howto.rst in
> fsleep will be removed soon.
> 
> https://lore.kernel.org/all/20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de/

It would be more accurate to say it gets replaced with a new document:

Documentation/timers/delay_sleep_functions.rst

So please reference that.

	Andrew
diff mbox series

Patch

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index ae82e9c941af..29a2f59294ba 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -10,6 +10,7 @@ 
 #include <linux/blk-mq.h>
 #include <linux/blk_types.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <linux/errname.h>
 #include <linux/ethtool.h>
 #include <linux/firmware.h>
diff --git a/rust/helpers/delay.c b/rust/helpers/delay.c
new file mode 100644
index 000000000000..7ae64ad8141d
--- /dev/null
+++ b/rust/helpers/delay.c
@@ -0,0 +1,8 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/delay.h>
+
+void rust_helper_fsleep(unsigned long usecs)
+{
+	fsleep(usecs);
+}
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 30f40149f3a9..279ea662ee3b 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -12,6 +12,7 @@ 
 #include "build_assert.c"
 #include "build_bug.c"
 #include "err.c"
+#include "delay.c"
 #include "kunit.c"
 #include "mutex.c"
 #include "page.c"
diff --git a/rust/kernel/delay.rs b/rust/kernel/delay.rs
new file mode 100644
index 000000000000..79f51a9608b5
--- /dev/null
+++ b/rust/kernel/delay.rs
@@ -0,0 +1,18 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+//! Delay and sleep routines.
+//!
+//! C headers: [`include/linux/delay.h`](srctree/include/linux/delay.h).
+
+use core::{ffi::c_ulong, time::Duration};
+
+/// Sleeps for a given duration.
+///
+/// Equivalent to the kernel's [`fsleep`] function, internally calls `udelay`,
+/// `usleep_range`, or `msleep`.
+///
+/// This function can only be used in a nonatomic context.
+pub fn sleep(duration: Duration) {
+    // SAFETY: FFI call.
+    unsafe { bindings::fsleep(duration.as_micros() as c_ulong) }
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 22a3bfa5a9e9..c08cb5509c82 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -30,6 +30,7 @@ 
 #[cfg(CONFIG_BLOCK)]
 pub mod block;
 mod build_assert;
+pub mod delay;
 pub mod device;
 pub mod error;
 #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]