From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Christian Schrefl <chrisi.schrefl@gmail.com>
Cc: FUJITA Tomonori <fujita.tomonori@gmail.com>,
a.hindborg@kernel.org, rust-for-linux@vger.kernel.org,
gary@garyguo.net, aliceryhl@google.com, me@kloenk.dev,
daniel.almeida@collabora.com, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, andrew@lunn.ch, hkallweit1@gmail.com,
tmgross@umich.edu, ojeda@kernel.org, alex.gaynor@gmail.com,
bjorn3_gh@protonmail.com, benno.lossin@proton.me,
a.hindborg@samsung.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,
david.laight.linux@gmail.com, boqun.feng@gmail.com,
pbonzini@redhat.com, jfalempe@redhat.com,
linus.walleij@linaro.org
Subject: Re: [PATCH v15 5/6] rust: time: Add wrapper for fsleep() function
Date: Tue, 29 Apr 2025 15:31:47 +0100 [thread overview]
Message-ID: <aBDi06bQibCIB4En@shell.armlinux.org.uk> (raw)
In-Reply-To: <03ccb65b-a5f8-4afc-84f5-e46f1caf96b0@gmail.com>
On Tue, Apr 29, 2025 at 04:16:01PM +0200, Christian Schrefl wrote:
> On 29.04.25 3:17 PM, FUJITA Tomonori wrote:
> > On Mon, 28 Apr 2025 20:16:47 +0200
> > Andreas Hindborg <a.hindborg@kernel.org> wrote:
> >
> >> Hi Tomonori,
> >>
> >> "FUJITA Tomonori" <fujita.tomonori@gmail.com> writes:
> >>
> >>> Add a wrapper for fsleep(), flexible sleep functions in
> >>> include/linux/delay.h which typically deals with hardware delays.
> >>>
> >>> The kernel supports several sleep functions to handle various lengths
> >>> of delay. This adds fsleep(), automatically chooses the best sleep
> >>> method based on a duration.
> >>>
> >>> sleep functions including fsleep() belongs to TIMERS, not
> >>> TIMEKEEPING. They are maintained separately. rust/kernel/time.rs is an
> >>> abstraction for TIMEKEEPING. To make Rust abstractions match the C
> >>> side, add rust/kernel/time/delay.rs for this wrapper.
> >>>
> >>> fsleep() can only be used in a nonatomic context. This requirement is
> >>> not checked by these abstractions, but it is intended that klint [1]
> >>> or a similar tool will be used to check it in the future.
> >>
> >> I get an error when building this patch for arm32:
> >>
> >> + kernel-make -j 96 O=/home/aeh/src/linux-rust/test-build-arm-1.78.0 vmlinux modules
> >> ld.lld: error: undefined symbol: __aeabi_uldivmod
> >> >>> referenced by kernel.df165ca450b1fd1-cgu.0
> >> >>> rust/kernel.o:(kernel::time::delay::fsleep) in archive vmlinux.a
> >> >>> did you mean: __aeabi_uidivmod
> >> >>> defined in: vmlinux.a(arch/arm/lib/lib1funcs.o)
> >>
> >> Looks like a division function of some sort is not defined. Can you
> >> reproduce?
> >
> > Ah, 64-bit integer division on 32-bit architectures.
> >
> > I think that the DRM QR driver has the same problem:
> >
> > https://lore.kernel.org/rust-for-linux/CANiq72ke45eOwckMhWHvmwxc03dxr4rnxxKvx+HvWdBLopZfrQ@mail.gmail.com/
> >
> > It appears that there is still no consensus on how to resolve it. CC
> > the participants in the above thread.
>
> From what I remember from the thread is that generally 64 bit divisions
> should be avoided (like the solution for DRM).
>
> > I think that we can drop this patch and better to focus on Instant and
> > Delta types in this merge window.
> >
> > With the patch below, this issue could be resolved like the C side,
> > but I'm not sure whether we can reach a consensus quickly.
>
> I think adding rust bindings for this is fine (and most likely needed),
> for cases where it is required.
>
> >
> > diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> > index 48143cdd26b3..c44d45960eb1 100644
> > --- a/rust/helpers/helpers.c
> > +++ b/rust/helpers/helpers.c
> > @@ -19,6 +19,7 @@
> > #include "io.c"
> > #include "jump_label.c"
> > #include "kunit.c"
> > +#include "math64.c"
> > #include "mutex.c"
> > #include "page.c"
> > #include "platform.c"
> > diff --git a/rust/helpers/math64.c b/rust/helpers/math64.c
> > new file mode 100644
> > index 000000000000..f94708cf8fcb
> > --- /dev/null
> > +++ b/rust/helpers/math64.c
> > @@ -0,0 +1,8 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/math64.h>
> > +
> > +s64 rust_helper_div64_s64(s64 dividend, s64 divisor)
> > +{
> > + return div64_s64(dividend, divisor);
> > +}
> > diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> > index de07aadd1ff5..d272e0b0b05d 100644
> > --- a/rust/kernel/lib.rs
> > +++ b/rust/kernel/lib.rs
> > @@ -60,6 +60,7 @@
> > #[cfg(CONFIG_KUNIT)]
> > pub mod kunit;
> > pub mod list;
> > +pub mod math64;
> > pub mod miscdevice;
> > #[cfg(CONFIG_NET)]
> > pub mod net;
> > diff --git a/rust/kernel/math64.rs b/rust/kernel/math64.rs
> > new file mode 100644
> > index 000000000000..523e47911859
> > --- /dev/null
> > +++ b/rust/kernel/math64.rs
> > @@ -0,0 +1,12 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +//! 64-bit integer arithmetic helpers.
> > +//!
> > +//! C header: [`include/linux/math64.h`](srctree/include/linux/math64.h)
> > +
> > +/// Divide a signed 64-bit integer by another signed 64-bit integer.
> > +#[inline]
> > +pub fn div64_s64(dividend: i64, divisor: i64) -> i64 {
> > + // SAFETY: Calling `div64_s64()` is safe as long as `divisor` is non-zero.
> The safety comment is not valid, nowhere is it guaranteed divisor is non-zero.
>
> There's three solutions I can think of:
> * Mark this function as `unsafe` and give the responsibility of checking
> this to the caller,
> * return a `Result` with a division by zero error type or
> * change the type of divisor to `NonZeroI64` [0].
>
> Probably the best way is to use `NonZeroI64` since that way
> it's statically guaranteed.
>
> In that case it would also make sense to change `NSEC_PER_USEC` to be `NonZeroI64`.
>
>
> Link: https://doc.rust-lang.org/nightly/core/num/type.NonZeroI64.html [0]
> > + unsafe { bindings::div64_s64(dividend, divisor) }
>
> Is `s64` just a typedef for `int64_t` and if so this true for every
> architecture? (I don't know the C side very well).
>
> If not there might need to be some kind of conversion to make sure
> they are passed correctly.
>
> > +}
> > diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
> > index 863385905029..7b5255893929 100644
> > --- a/rust/kernel/time.rs
> > +++ b/rust/kernel/time.rs
> > @@ -24,6 +24,8 @@
> > //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
> > //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
> >
> > +use crate::math64;
> > +
> > pub mod delay;
> > pub mod hrtimer;
> >
> > @@ -229,13 +231,16 @@ pub const fn as_nanos(self) -> i64 {
> > /// Return the smallest number of microseconds greater than or equal
> > /// to the value in the [`Delta`].
> > #[inline]
> > - pub const fn as_micros_ceil(self) -> i64 {
> > - self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC
> > + pub fn as_micros_ceil(self) -> i64 {
> > + math64::div64_s64(
> It would make sense to change `NSEC_PER_USEC` to be `NonZeroI64`.
>
> > + self.as_nanos().saturating_add(NSEC_PER_USEC - 1),
> > + NSEC_PER_USEC,
> > + )
> > }
> >
> > /// Return the number of milliseconds in the [`Delta`].
> > #[inline]
> > - pub const fn as_millis(self) -> i64 {
> > - self.as_nanos() / NSEC_PER_MSEC
> > + pub fn as_millis(self) -> i64 {
> > + math64::div64_s64(self.as_nanos(), NSEC_PER_MSEC)
There is no way this should ever be an expensive 64-bit by 64-bit
division. Think about value of the divisor here - there's 1000us
in 1ms, and 1000ns in 1us, so this has the value of 1000000,
which is 20 bits.
So for a 32-bit architecture, trying to do a 64-bit by 64-bit
division is expensive, and 32-bit architectures don't implement
this as a general rule because of this - most times you do not
have a 64-bit divisor, but something much smaller, making a
64-bit by 32-bit division more suitable. That is a lot faster on
32-bit architectures.
So, I think more thought is needed to be put into this by Rust
folk, rather than blindly forcing everything to be 64-bit by
64-bit even when the divisor is 20-bit.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
next prev parent reply other threads:[~2025-04-29 14:32 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-23 19:28 [PATCH v15 0/6] rust: Add IO polling FUJITA Tomonori
2025-04-23 19:28 ` [PATCH v15 1/6] rust: hrtimer: Add Ktime temporarily FUJITA Tomonori
2025-04-23 19:28 ` [PATCH v15 2/6] rust: time: Add PartialEq/Eq/PartialOrd/Ord trait to Ktime FUJITA Tomonori
2025-04-23 19:28 ` [PATCH v15 3/6] rust: time: Introduce Delta type FUJITA Tomonori
2025-04-23 19:28 ` [PATCH v15 4/6] rust: time: Introduce Instant type FUJITA Tomonori
2025-04-23 19:28 ` [PATCH v15 5/6] rust: time: Add wrapper for fsleep() function FUJITA Tomonori
2025-04-28 18:16 ` Andreas Hindborg
2025-04-29 13:17 ` FUJITA Tomonori
2025-04-29 14:16 ` Christian Schrefl
2025-04-29 14:31 ` Russell King (Oracle) [this message]
2025-04-29 14:35 ` Miguel Ojeda
2025-04-30 13:51 ` FUJITA Tomonori
2025-04-30 14:50 ` Boqun Feng
2025-04-30 16:43 ` Christian Schrefl
2025-04-29 15:51 ` Arnd Bergmann
2025-04-29 16:03 ` Boqun Feng
2025-04-29 16:11 ` Arnd Bergmann
2025-04-29 17:15 ` Boqun Feng
2025-04-29 18:33 ` Arnd Bergmann
2025-04-29 19:14 ` Boqun Feng
2025-04-29 19:27 ` Boqun Feng
2025-04-23 19:28 ` [PATCH v15 6/6] MAINTAINERS: rust: Add a new section for all of the time stuff FUJITA Tomonori
2025-04-30 10:40 ` [PATCH v15 0/6] rust: Add IO polling Andreas Hindborg
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=aBDi06bQibCIB4En@shell.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=a.hindborg@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=boqun.feng@gmail.com \
--cc=bsegall@google.com \
--cc=chrisi.schrefl@gmail.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=jfalempe@redhat.com \
--cc=jstultz@google.com \
--cc=juri.lelli@redhat.com \
--cc=linus.walleij@linaro.org \
--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=pbonzini@redhat.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.