All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Add support for print exactly once
@ 2025-11-17  0:24 FUJITA Tomonori
  2025-11-17  0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2025-11-17  0:24 UTC (permalink / raw)
  To: alex.gaynor, ojeda, a.hindborg, aliceryhl, boqun.feng
  Cc: bjorn3_gh, dakr, gary, lossin, rust-for-linux, tmgross

This adds the Rust equivalent of the C's DO_ONCE_LITE and pr_*_once
macros.

A proposal for this feature was made in the past [1], but it didn't
reach consensus on the implementation and wasn't merged.

Unlike the previous proposal, this implements the C's DO_ONCE_LITE
mechanism using a single atomic variable. While it would be possible
to implement the feature entirely as a Rust macro, the functionality
that can be implemented as regular functions has been extracted and
implemented as the OnceLite struct for better code readability.

To make it clear that this feature is intended solely for
print-related functionality (just like in C), the implementation is
placed in print.rs. If an equivalent of std::sync::Once is needed in
the future, it should be based on SetOnce rather than OnceLite. Unlike
std::sync::Once and SetOnce, OnceLite only manages two states:
incomplete and complete.

The do_once_lite macro places the OnceLite object in the .data..once
section, which may be zeroed by memset at any time. While this means
tear reads might happen, OnceLite only manages two states (zero and
non-zero), so no actual problem occurs in practice.

OnceLite currently uses Atomic<i32>, but may be changed to use
Atomic<i8> [2] when it becomes available.

[1] https://lore.kernel.org/rust-for-linux/20241126-pr_once_macros-v4-0-410b8ca9643e@tuta.io/
[2] https://lore.kernel.org/rust-for-linux/20251115050305.3872412-1-fujita.tomonori@gmail.com/

v3:
- add relaxed load before expensive xchg
- move OnceLite to print.rs
v2: https://lore.kernel.org/rust-for-linux/20251112131619.3585510-1-fujita.tomonori@gmail.com/
- improve do_once_lite micro syntax
- move once_lite.rs to kernel/sync/
- add comments (including ORDERING)
- fix rustdoc errors
- use vertical layout for imports
v1: https://lore.kernel.org/rust-for-linux/20251105054731.3194118-1-fujita.tomonori@gmail.com/


FUJITA Tomonori (2):
  rust: Add support for calling a function exactly once
  rust: Add pr_*_once macros

 rust/kernel/print.rs | 153 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)


base-commit: 3b83f5d5e78ac5cddd811a5e431af73959864390
-- 
2.43.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3 1/2] rust: Add support for calling a function exactly once
  2025-11-17  0:24 [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
@ 2025-11-17  0:24 ` FUJITA Tomonori
  2025-12-18 11:38   ` Alice Ryhl
  2025-12-23 12:18   ` Gary Guo
  2025-11-17  0:24 ` [PATCH v3 2/2] rust: Add pr_*_once macros FUJITA Tomonori
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2025-11-17  0:24 UTC (permalink / raw)
  To: alex.gaynor, ojeda, a.hindborg, aliceryhl, boqun.feng
  Cc: bjorn3_gh, dakr, gary, lossin, rust-for-linux, tmgross

Add the Rust equivalent of the kernel's `DO_ONCE_LITE` macro. While it
would be possible to implement the feature entirely as a Rust macro,
the functionality that can be implemented as regular functions has
been extracted and implemented as the `OnceLite` struct for better
code maintainability.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/print.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
index 2d743d78d220..af32054be5a2 100644
--- a/rust/kernel/print.rs
+++ b/rust/kernel/print.rs
@@ -11,6 +11,11 @@
     fmt,
     prelude::*,
     str::RawFormatter,
+    sync::atomic::{
+        Atomic,
+        AtomicType,
+        Relaxed, //
+    },
 };
 
 // Called from `vsprintf` with format specifier `%pA`.
@@ -423,3 +428,81 @@ macro_rules! pr_cont (
         $crate::print_macro!($crate::print::format_strings::CONT, true, $($arg)*)
     )
 );
+
+/// A lightweight `call_once` primitive.
+///
+/// This structure provides the Rust equivalent of the kernel's `DO_ONCE_LITE` macro.
+/// While it would be possible to implement the feature entirely as a Rust macro,
+/// the functionality that can be implemented as regular functions has been
+/// extracted and implemented as the `OnceLite` struct for better code maintainability.
+pub struct OnceLite(Atomic<State>);
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+#[repr(i32)]
+enum State {
+    Incomplete = 0,
+    Complete = 1,
+}
+
+// SAFETY: `State` and `i32` has the same size and alignment, and it's round-trip
+// transmutable to `i32`.
+unsafe impl AtomicType for State {
+    type Repr = i32;
+}
+
+impl OnceLite {
+    /// Creates a new [`OnceLite`] in the incomplete state.
+    #[inline(always)]
+    #[allow(clippy::new_without_default)]
+    pub const fn new() -> Self {
+        OnceLite(Atomic::new(State::Incomplete))
+    }
+
+    /// Calls the provided function exactly once.
+    ///
+    /// There is no other synchronization between two `call_once()`s
+    /// except that only one will execute `f`, in other words, callers
+    /// should not use a failed `call_once()` as a proof that another
+    /// `call_once()` has already finished and the effect is observable
+    /// to this thread.
+    pub fn call_once<F>(&self, f: F) -> bool
+    where
+        F: FnOnce(),
+    {
+        // Avoid expensive cmpxchg if already completed.
+        // ORDERING: `Relaxed` is used here since no synchronization is required.
+        let old = self.0.load(Relaxed);
+        if old == State::Complete {
+            return false;
+        }
+
+        // ORDERING: `Relaxed` is used here since no synchronization is required.
+        let old = self.0.xchg(State::Complete, Relaxed);
+        if old == State::Complete {
+            return false;
+        }
+
+        f();
+        true
+    }
+}
+
+/// Run the given function exactly once.
+///
+/// This is equivalent to the kernel's `DO_ONCE_LITE` macro.
+///
+/// # Examples
+///
+/// ```
+/// kernel::do_once_lite! {
+///     kernel::pr_info!("This will be printed only once\n");
+/// };
+/// ```
+#[macro_export]
+macro_rules! do_once_lite {
+    { $($e:tt)* } => {{
+        #[link_section = ".data..once"]
+        static ONCE: $crate::print::OnceLite = $crate::print::OnceLite::new();
+        ONCE.call_once(|| { $($e)* });
+    }};
+}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 2/2] rust: Add pr_*_once macros
  2025-11-17  0:24 [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
  2025-11-17  0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
@ 2025-11-17  0:24 ` FUJITA Tomonori
  2025-12-23 12:06   ` Gary Guo
  2025-12-18 11:18 ` [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
  2026-01-30  4:51 ` Miguel Ojeda
  3 siblings, 1 reply; 13+ messages in thread
From: FUJITA Tomonori @ 2025-11-17  0:24 UTC (permalink / raw)
  To: alex.gaynor, ojeda, a.hindborg, aliceryhl, boqun.feng
  Cc: bjorn3_gh, dakr, gary, lossin, rust-for-linux, tmgross

Add Rust version of pr_[emerg|alert|crit|err|warn|notic|info]_once
macros, which print a message only once.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/print.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
index af32054be5a2..6fd84389a858 100644
--- a/rust/kernel/print.rs
+++ b/rust/kernel/print.rs
@@ -506,3 +506,73 @@ macro_rules! do_once_lite {
         ONCE.call_once(|| { $($e)* });
     }};
 }
+
+/// Prints an emergency-level message (level 0) only once.
+///
+/// Equivalent to the kernel's `pr_emerg_once` macro.
+#[macro_export]
+macro_rules! pr_emerg_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_emerg!($($arg)*) }
+    )
+);
+
+/// Prints an alert-level message (level 1) only once.
+///
+/// Equivalent to the kernel's `pr_alert_once` macro.
+#[macro_export]
+macro_rules! pr_alert_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_alert!($($arg)*) }
+    )
+);
+
+/// Prints a critical-level message (level 2) only once.
+///
+/// Equivalent to the kernel's `pr_crit_once` macro.
+#[macro_export]
+macro_rules! pr_crit_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_crit!($($arg)*) }
+    )
+);
+
+/// Prints an error-level message (level 3) only once.
+///
+/// Equivalent to the kernel's `pr_err_once` macro.
+#[macro_export]
+macro_rules! pr_err_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_err!($($arg)*) }
+    )
+);
+
+/// Prints a warning-level message (level 4) only once.
+///
+/// Equivalent to the kernel's `pr_warn_once` macro.
+#[macro_export]
+macro_rules! pr_warn_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_warn!($($arg)*) }
+    )
+);
+
+/// Prints a notice-level message (level 5) only once.
+///
+/// Equivalent to the kernel's `pr_notice_once` macro.
+#[macro_export]
+macro_rules! pr_notice_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_notice!($($arg)*) }
+    )
+);
+
+/// Prints an info-level message (level 6) only once.
+///
+/// Equivalent to the kernel's `pr_info_once` macro.
+#[macro_export]
+macro_rules! pr_info_once (
+    ($($arg:tt)*) => (
+        $crate::do_once_lite! { $crate::pr_info!($($arg)*) }
+    )
+);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 0/2] Add support for print exactly once
  2025-11-17  0:24 [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
  2025-11-17  0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
  2025-11-17  0:24 ` [PATCH v3 2/2] rust: Add pr_*_once macros FUJITA Tomonori
@ 2025-12-18 11:18 ` FUJITA Tomonori
  2026-01-30  4:51 ` Miguel Ojeda
  3 siblings, 0 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2025-12-18 11:18 UTC (permalink / raw)
  To: a.hindborg, aliceryhl, boqun.feng, ojeda
  Cc: bjorn3_gh, dakr, gary, lossin, rust-for-linux, tmgross

On Mon, 17 Nov 2025 09:24:50 +0900
FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:

> This adds the Rust equivalent of the C's DO_ONCE_LITE and pr_*_once
> macros.
> 
> A proposal for this feature was made in the past [1], but it didn't
> reach consensus on the implementation and wasn't merged.
> 
> Unlike the previous proposal, this implements the C's DO_ONCE_LITE
> mechanism using a single atomic variable. While it would be possible
> to implement the feature entirely as a Rust macro, the functionality
> that can be implemented as regular functions has been extracted and
> implemented as the OnceLite struct for better code readability.
> 
> To make it clear that this feature is intended solely for
> print-related functionality (just like in C), the implementation is
> placed in print.rs. If an equivalent of std::sync::Once is needed in
> the future, it should be based on SetOnce rather than OnceLite. Unlike
> std::sync::Once and SetOnce, OnceLite only manages two states:
> incomplete and complete.
> 
> The do_once_lite macro places the OnceLite object in the .data..once
> section, which may be zeroed by memset at any time. While this means
> tear reads might happen, OnceLite only manages two states (zero and
> non-zero), so no actual problem occurs in practice.
> 
> OnceLite currently uses Atomic<i32>, but may be changed to use
> Atomic<i8> [2] when it becomes available.
> 
> [1] https://lore.kernel.org/rust-for-linux/20241126-pr_once_macros-v4-0-410b8ca9643e@tuta.io/
> [2] https://lore.kernel.org/rust-for-linux/20251115050305.3872412-1-fujita.tomonori@gmail.com/
> 
> v3:
> - add relaxed load before expensive xchg
> - move OnceLite to print.rs
> v2: https://lore.kernel.org/rust-for-linux/20251112131619.3585510-1-fujita.tomonori@gmail.com/
> - improve do_once_lite micro syntax
> - move once_lite.rs to kernel/sync/
> - add comments (including ORDERING)
> - fix rustdoc errors
> - use vertical layout for imports
> v1: https://lore.kernel.org/rust-for-linux/20251105054731.3194118-1-fujita.tomonori@gmail.com/
> 
> 
> FUJITA Tomonori (2):
>   rust: Add support for calling a function exactly once
>   rust: Add pr_*_once macros
> 
>  rust/kernel/print.rs | 153 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 153 insertions(+)

Any feedback on this?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/2] rust: Add support for calling a function exactly once
  2025-11-17  0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
@ 2025-12-18 11:38   ` Alice Ryhl
  2025-12-23  6:49     ` FUJITA Tomonori
  2025-12-23 12:18   ` Gary Guo
  1 sibling, 1 reply; 13+ messages in thread
From: Alice Ryhl @ 2025-12-18 11:38 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: alex.gaynor, ojeda, a.hindborg, boqun.feng, bjorn3_gh, dakr, gary,
	lossin, rust-for-linux, tmgross

On Mon, Nov 17, 2025 at 09:24:51AM +0900, FUJITA Tomonori wrote:
> Add the Rust equivalent of the kernel's `DO_ONCE_LITE` macro. While it
> would be possible to implement the feature entirely as a Rust macro,
> the functionality that can be implemented as regular functions has
> been extracted and implemented as the `OnceLite` struct for better
> code maintainability.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>

Reviewed-by: Alice Ryhl <aliceryhl@google.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/2] rust: Add support for calling a function exactly once
  2025-12-18 11:38   ` Alice Ryhl
@ 2025-12-23  6:49     ` FUJITA Tomonori
  0 siblings, 0 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2025-12-23  6:49 UTC (permalink / raw)
  To: aliceryhl, ojeda
  Cc: fujita.tomonori, alex.gaynor, a.hindborg, boqun.feng, bjorn3_gh,
	dakr, gary, lossin, rust-for-linux, tmgross

On Thu, 18 Dec 2025 11:38:04 +0000
Alice Ryhl <aliceryhl@google.com> wrote:

> On Mon, Nov 17, 2025 at 09:24:51AM +0900, FUJITA Tomonori wrote:
>> Add the Rust equivalent of the kernel's `DO_ONCE_LITE` macro. While it
>> would be possible to implement the feature entirely as a Rust macro,
>> the functionality that can be implemented as regular functions has
>> been extracted and implemented as the `OnceLite` struct for better
>> code maintainability.
>> 
>> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> 
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>

Thanks a lot!

Miguel, would it be possible to merge this patchset set into
rust-next?

https://lore.kernel.org/rust-for-linux/20251117002452.4068692-1-fujita.tomonori@gmail.com/

I'd like to follow up with adding warn_once() after this series is
merged. There are several TODO comments under rust/ that mention using
WARN_ONCE().


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] rust: Add pr_*_once macros
  2025-11-17  0:24 ` [PATCH v3 2/2] rust: Add pr_*_once macros FUJITA Tomonori
@ 2025-12-23 12:06   ` Gary Guo
  2025-12-25  6:29     ` FUJITA Tomonori
  2026-01-13  6:52     ` FUJITA Tomonori
  0 siblings, 2 replies; 13+ messages in thread
From: Gary Guo @ 2025-12-23 12:06 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: alex.gaynor, ojeda, a.hindborg, aliceryhl, boqun.feng, bjorn3_gh,
	dakr, lossin, rust-for-linux, tmgross

On Mon, 17 Nov 2025 09:24:52 +0900
FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:

> Add Rust version of pr_[emerg|alert|crit|err|warn|notic|info]_once
> macros, which print a message only once.
> 
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>

A meta topic about this one.

I think we're adding too many macros with this. In C we had to do this
way because expressive power of mascros are more limited, but I wonder
if we should just add different flavours with macros.

For example, instead of

	pr_warn_once!("foo");

we could do

	pr_warn!(once, "foo");

If we are adding extra tunables, we could do something similar too.
Given all print macros start with a format string, doing this won't create
any ambiguity.

An added benefit is that now you only need to implement the functionality
once in `print_macro!` and all other macros gain the feature, too.

Best,
Gary

> ---
>  rust/kernel/print.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
> 
> diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
> index af32054be5a2..6fd84389a858 100644
> --- a/rust/kernel/print.rs
> +++ b/rust/kernel/print.rs
> @@ -506,3 +506,73 @@ macro_rules! do_once_lite {
>          ONCE.call_once(|| { $($e)* });
>      }};
>  }
> +
> +/// Prints an emergency-level message (level 0) only once.
> +///
> +/// Equivalent to the kernel's `pr_emerg_once` macro.
> +#[macro_export]
> +macro_rules! pr_emerg_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_emerg!($($arg)*) }
> +    )
> +);
> +
> +/// Prints an alert-level message (level 1) only once.
> +///
> +/// Equivalent to the kernel's `pr_alert_once` macro.
> +#[macro_export]
> +macro_rules! pr_alert_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_alert!($($arg)*) }
> +    )
> +);
> +
> +/// Prints a critical-level message (level 2) only once.
> +///
> +/// Equivalent to the kernel's `pr_crit_once` macro.
> +#[macro_export]
> +macro_rules! pr_crit_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_crit!($($arg)*) }
> +    )
> +);
> +
> +/// Prints an error-level message (level 3) only once.
> +///
> +/// Equivalent to the kernel's `pr_err_once` macro.
> +#[macro_export]
> +macro_rules! pr_err_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_err!($($arg)*) }
> +    )
> +);
> +
> +/// Prints a warning-level message (level 4) only once.
> +///
> +/// Equivalent to the kernel's `pr_warn_once` macro.
> +#[macro_export]
> +macro_rules! pr_warn_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_warn!($($arg)*) }
> +    )
> +);
> +
> +/// Prints a notice-level message (level 5) only once.
> +///
> +/// Equivalent to the kernel's `pr_notice_once` macro.
> +#[macro_export]
> +macro_rules! pr_notice_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_notice!($($arg)*) }
> +    )
> +);
> +
> +/// Prints an info-level message (level 6) only once.
> +///
> +/// Equivalent to the kernel's `pr_info_once` macro.
> +#[macro_export]
> +macro_rules! pr_info_once (
> +    ($($arg:tt)*) => (
> +        $crate::do_once_lite! { $crate::pr_info!($($arg)*) }
> +    )
> +);


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/2] rust: Add support for calling a function exactly once
  2025-11-17  0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
  2025-12-18 11:38   ` Alice Ryhl
@ 2025-12-23 12:18   ` Gary Guo
  2025-12-25  6:14     ` FUJITA Tomonori
  1 sibling, 1 reply; 13+ messages in thread
From: Gary Guo @ 2025-12-23 12:18 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: alex.gaynor, ojeda, a.hindborg, aliceryhl, boqun.feng, bjorn3_gh,
	dakr, lossin, rust-for-linux, tmgross

On Mon, 17 Nov 2025 09:24:51 +0900
FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:

> Add the Rust equivalent of the kernel's `DO_ONCE_LITE` macro. While it
> would be possible to implement the feature entirely as a Rust macro,
> the functionality that can be implemented as regular functions has
> been extracted and implemented as the `OnceLite` struct for better
> code maintainability.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
>  rust/kernel/print.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 83 insertions(+)
> 
> diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
> index 2d743d78d220..af32054be5a2 100644
> --- a/rust/kernel/print.rs
> +++ b/rust/kernel/print.rs
> @@ -11,6 +11,11 @@
>      fmt,
>      prelude::*,
>      str::RawFormatter,
> +    sync::atomic::{
> +        Atomic,
> +        AtomicType,
> +        Relaxed, //
> +    },
>  };
>  
>  // Called from `vsprintf` with format specifier `%pA`.
> @@ -423,3 +428,81 @@ macro_rules! pr_cont (
>          $crate::print_macro!($crate::print::format_strings::CONT, true, $($arg)*)
>      )
>  );
> +
> +/// A lightweight `call_once` primitive.
> +///
> +/// This structure provides the Rust equivalent of the kernel's `DO_ONCE_LITE` macro.
> +/// While it would be possible to implement the feature entirely as a Rust macro,
> +/// the functionality that can be implemented as regular functions has been
> +/// extracted and implemented as the `OnceLite` struct for better code maintainability.
> +pub struct OnceLite(Atomic<State>);
> +
> +#[derive(Clone, Copy, PartialEq, Eq)]
> +#[repr(i32)]
> +enum State {
> +    Incomplete = 0,
> +    Complete = 1,
> +}
> +
> +// SAFETY: `State` and `i32` has the same size and alignment, and it's round-trip
> +// transmutable to `i32`.
> +unsafe impl AtomicType for State {
> +    type Repr = i32;
> +}
> +
> +impl OnceLite {
> +    /// Creates a new [`OnceLite`] in the incomplete state.
> +    #[inline(always)]
> +    #[allow(clippy::new_without_default)]

Maybe put the reason too? Otherwise a reader who hasn't been following
previous discussions closely might be out of context (like me).

> +    pub const fn new() -> Self {
> +        OnceLite(Atomic::new(State::Incomplete))
> +    }
> +
> +    /// Calls the provided function exactly once.
> +    ///
> +    /// There is no other synchronization between two `call_once()`s
> +    /// except that only one will execute `f`, in other words, callers
> +    /// should not use a failed `call_once()` as a proof that another
> +    /// `call_once()` has already finished and the effect is observable
> +    /// to this thread.

Nice! Thanks for putting this in. If this this insn't in this will
definitely be misused (I won't be surprised that it'll be misused anyway
even with this, though)

Reviewed-by: Gary Guo <gary@garyguo.net>

Best,
Gary

> +    pub fn call_once<F>(&self, f: F) -> bool
> +    where
> +        F: FnOnce(),
> +    {
> +        // Avoid expensive cmpxchg if already completed.
> +        // ORDERING: `Relaxed` is used here since no synchronization is required.
> +        let old = self.0.load(Relaxed);
> +        if old == State::Complete {
> +            return false;
> +        }
> +
> +        // ORDERING: `Relaxed` is used here since no synchronization is required.
> +        let old = self.0.xchg(State::Complete, Relaxed);
> +        if old == State::Complete {
> +            return false;
> +        }
> +
> +        f();
> +        true
> +    }
> +}


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/2] rust: Add support for calling a function exactly once
  2025-12-23 12:18   ` Gary Guo
@ 2025-12-25  6:14     ` FUJITA Tomonori
  0 siblings, 0 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2025-12-25  6:14 UTC (permalink / raw)
  To: gary
  Cc: fujita.tomonori, alex.gaynor, ojeda, a.hindborg, aliceryhl,
	boqun.feng, bjorn3_gh, dakr, lossin, rust-for-linux, tmgross

On Tue, 23 Dec 2025 12:18:14 +0000
Gary Guo <gary@garyguo.net> wrote:

>> +/// A lightweight `call_once` primitive.
>> +///
>> +/// This structure provides the Rust equivalent of the kernel's `DO_ONCE_LITE` macro.
>> +/// While it would be possible to implement the feature entirely as a Rust macro,
>> +/// the functionality that can be implemented as regular functions has been
>> +/// extracted and implemented as the `OnceLite` struct for better code maintainability.
>> +pub struct OnceLite(Atomic<State>);
>> +
>> +#[derive(Clone, Copy, PartialEq, Eq)]
>> +#[repr(i32)]
>> +enum State {
>> +    Incomplete = 0,
>> +    Complete = 1,
>> +}
>> +
>> +// SAFETY: `State` and `i32` has the same size and alignment, and it's round-trip
>> +// transmutable to `i32`.
>> +unsafe impl AtomicType for State {
>> +    type Repr = i32;
>> +}
>> +
>> +impl OnceLite {
>> +    /// Creates a new [`OnceLite`] in the incomplete state.
>> +    #[inline(always)]
>> +    #[allow(clippy::new_without_default)]
> 
> Maybe put the reason too? Otherwise a reader who hasn't been following
> previous discussions closely might be out of context (like me).

OnceLite is intended to be used in do_once_lite macro so this needs to
be const and no need to add Default (Default can't be const).

>> +    pub const fn new() -> Self {
>> +        OnceLite(Atomic::new(State::Incomplete))
>> +    }
>> +
>> +    /// Calls the provided function exactly once.
>> +    ///
>> +    /// There is no other synchronization between two `call_once()`s
>> +    /// except that only one will execute `f`, in other words, callers
>> +    /// should not use a failed `call_once()` as a proof that another
>> +    /// `call_once()` has already finished and the effect is observable
>> +    /// to this thread.
> 
> Nice! Thanks for putting this in. If this this insn't in this will
> definitely be misused (I won't be surprised that it'll be misused anyway
> even with this, though)

OnceLite is intended to be used only by do_once_lite so it's placed in
print.rs (if someone needs something like std::sync::Once,
sync::SetOnce should be used instead).

> Reviewed-by: Gary Guo <gary@garyguo.net>

Thanks!

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] rust: Add pr_*_once macros
  2025-12-23 12:06   ` Gary Guo
@ 2025-12-25  6:29     ` FUJITA Tomonori
  2026-01-13  6:52     ` FUJITA Tomonori
  1 sibling, 0 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2025-12-25  6:29 UTC (permalink / raw)
  To: gary
  Cc: fujita.tomonori, alex.gaynor, ojeda, a.hindborg, aliceryhl,
	boqun.feng, bjorn3_gh, dakr, lossin, rust-for-linux, tmgross

On Tue, 23 Dec 2025 12:06:00 +0000
Gary Guo <gary@garyguo.net> wrote:

> On Mon, 17 Nov 2025 09:24:52 +0900
> FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:
> 
>> Add Rust version of pr_[emerg|alert|crit|err|warn|notic|info]_once
>> macros, which print a message only once.
>> 
>> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
>> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> 
> A meta topic about this one.
> 
> I think we're adding too many macros with this. In C we had to do this
> way because expressive power of mascros are more limited, but I wonder
> if we should just add different flavours with macros.
> 
> For example, instead of
> 
> 	pr_warn_once!("foo");
> 
> we could do
> 
> 	pr_warn!(once, "foo");
> 
> If we are adding extra tunables, we could do something similar too.
> Given all print macros start with a format string, doing this won't create
> any ambiguity.
> 
> An added benefit is that now you only need to implement the functionality
> once in `print_macro!` and all other macros gain the feature, too.

I don't have a strong preference either way.

If we’re willing to diverge from the C interface to reduce the number
of macros,

pr!(warn, once, "foo");

?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] rust: Add pr_*_once macros
  2025-12-23 12:06   ` Gary Guo
  2025-12-25  6:29     ` FUJITA Tomonori
@ 2026-01-13  6:52     ` FUJITA Tomonori
  1 sibling, 0 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2026-01-13  6:52 UTC (permalink / raw)
  To: gary
  Cc: fujita.tomonori, alex.gaynor, ojeda, a.hindborg, aliceryhl,
	boqun.feng, bjorn3_gh, dakr, lossin, rust-for-linux, tmgross

On Tue, 23 Dec 2025 12:06:00 +0000
Gary Guo <gary@garyguo.net> wrote:

> On Mon, 17 Nov 2025 09:24:52 +0900
> FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:
> 
>> Add Rust version of pr_[emerg|alert|crit|err|warn|notic|info]_once
>> macros, which print a message only once.
>> 
>> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
>> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> 
> A meta topic about this one.
> 
> I think we're adding too many macros with this. In C we had to do this
> way because expressive power of mascros are more limited, but I wonder
> if we should just add different flavours with macros.
> 
> For example, instead of
> 
> 	pr_warn_once!("foo");
> 
> we could do
> 
> 	pr_warn!(once, "foo");
> 
> If we are adding extra tunables, we could do something similar too.
> Given all print macros start with a format string, doing this won't create
> any ambiguity.
> 
> An added benefit is that now you only need to implement the functionality
> once in `print_macro!` and all other macros gain the feature, too.

There was some related discussion in another thread [1], any other
opinions on this?

[1] https://lore.kernel.org/rust-for-linux/20260108125523.5c7810ae.gary@garyguo.net/


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 0/2] Add support for print exactly once
  2025-11-17  0:24 [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
                   ` (2 preceding siblings ...)
  2025-12-18 11:18 ` [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
@ 2026-01-30  4:51 ` Miguel Ojeda
  2026-01-30 12:34   ` FUJITA Tomonori
  3 siblings, 1 reply; 13+ messages in thread
From: Miguel Ojeda @ 2026-01-30  4:51 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: alex.gaynor, ojeda, a.hindborg, aliceryhl, boqun.feng, bjorn3_gh,
	dakr, gary, lossin, rust-for-linux, tmgross

On Mon, Nov 17, 2025 at 1:25 AM FUJITA Tomonori
<fujita.tomonori@gmail.com> wrote:
>
> This adds the Rust equivalent of the C's DO_ONCE_LITE and pr_*_once
> macros.
>
> A proposal for this feature was made in the past [1], but it didn't
> reach consensus on the implementation and wasn't merged.
>
> Unlike the previous proposal, this implements the C's DO_ONCE_LITE
> mechanism using a single atomic variable. While it would be possible
> to implement the feature entirely as a Rust macro, the functionality
> that can be implemented as regular functions has been extracted and
> implemented as the OnceLite struct for better code readability.
>
> To make it clear that this feature is intended solely for
> print-related functionality (just like in C), the implementation is
> placed in print.rs. If an equivalent of std::sync::Once is needed in
> the future, it should be based on SetOnce rather than OnceLite. Unlike
> std::sync::Once and SetOnce, OnceLite only manages two states:
> incomplete and complete.
>
> The do_once_lite macro places the OnceLite object in the .data..once
> section, which may be zeroed by memset at any time. While this means
> tear reads might happen, OnceLite only manages two states (zero and
> non-zero), so no actual problem occurs in practice.
>
> OnceLite currently uses Atomic<i32>, but may be changed to use
> Atomic<i8> [2] when it becomes available.
>
> [1] https://lore.kernel.org/rust-for-linux/20241126-pr_once_macros-v4-0-410b8ca9643e@tuta.io/
> [2] https://lore.kernel.org/rust-for-linux/20251115050305.3872412-1-fujita.tomonori@gmail.com/

Applied to `rust-next` -- thanks everyone!

I have used this nice cover letter as the basis for a merge commit.
While they were just two commits, I think the cover letter adds some
context that those other commit messages do not.

Tomonori, please double check the merge commit message! And if you did
not intend for this to land in the Git log, please let me know (I am
starting to take more cover letters into the Git log).

    [ Added prefix to title. - Miguel ]

    [ Added prefix to title. Fixed typo. - Miguel ]

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 0/2] Add support for print exactly once
  2026-01-30  4:51 ` Miguel Ojeda
@ 2026-01-30 12:34   ` FUJITA Tomonori
  0 siblings, 0 replies; 13+ messages in thread
From: FUJITA Tomonori @ 2026-01-30 12:34 UTC (permalink / raw)
  To: miguel.ojeda.sandonis
  Cc: fujita.tomonori, alex.gaynor, ojeda, a.hindborg, aliceryhl,
	boqun.feng, bjorn3_gh, dakr, gary, lossin, rust-for-linux,
	tmgross

On Fri, 30 Jan 2026 05:51:42 +0100
Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> On Mon, Nov 17, 2025 at 1:25 AM FUJITA Tomonori
> <fujita.tomonori@gmail.com> wrote:
>>
>> This adds the Rust equivalent of the C's DO_ONCE_LITE and pr_*_once
>> macros.
>>
>> A proposal for this feature was made in the past [1], but it didn't
>> reach consensus on the implementation and wasn't merged.
>>
>> Unlike the previous proposal, this implements the C's DO_ONCE_LITE
>> mechanism using a single atomic variable. While it would be possible
>> to implement the feature entirely as a Rust macro, the functionality
>> that can be implemented as regular functions has been extracted and
>> implemented as the OnceLite struct for better code readability.
>>
>> To make it clear that this feature is intended solely for
>> print-related functionality (just like in C), the implementation is
>> placed in print.rs. If an equivalent of std::sync::Once is needed in
>> the future, it should be based on SetOnce rather than OnceLite. Unlike
>> std::sync::Once and SetOnce, OnceLite only manages two states:
>> incomplete and complete.
>>
>> The do_once_lite macro places the OnceLite object in the .data..once
>> section, which may be zeroed by memset at any time. While this means
>> tear reads might happen, OnceLite only manages two states (zero and
>> non-zero), so no actual problem occurs in practice.
>>
>> OnceLite currently uses Atomic<i32>, but may be changed to use
>> Atomic<i8> [2] when it becomes available.
>>
>> [1] https://lore.kernel.org/rust-for-linux/20241126-pr_once_macros-v4-0-410b8ca9643e@tuta.io/
>> [2] https://lore.kernel.org/rust-for-linux/20251115050305.3872412-1-fujita.tomonori@gmail.com/
> 
> Applied to `rust-next` -- thanks everyone!
> 
> I have used this nice cover letter as the basis for a merge commit.
> While they were just two commits, I think the cover letter adds some
> context that those other commit messages do not.
> 
> Tomonori, please double check the merge commit message! And if you did
> not intend for this to land in the Git log, please let me know (I am
> starting to take more cover letters into the Git log).
> 
>     [ Added prefix to title. - Miguel ]
> 
>     [ Added prefix to title. Fixed typo. - Miguel ]

That sounds like a good idea. Looks good.

I've just tried the rust-next branch and do_once_lite() works as
expected.

Thanks!


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-01-30 12:35 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-17  0:24 [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
2025-11-17  0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
2025-12-18 11:38   ` Alice Ryhl
2025-12-23  6:49     ` FUJITA Tomonori
2025-12-23 12:18   ` Gary Guo
2025-12-25  6:14     ` FUJITA Tomonori
2025-11-17  0:24 ` [PATCH v3 2/2] rust: Add pr_*_once macros FUJITA Tomonori
2025-12-23 12:06   ` Gary Guo
2025-12-25  6:29     ` FUJITA Tomonori
2026-01-13  6:52     ` FUJITA Tomonori
2025-12-18 11:18 ` [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
2026-01-30  4:51 ` Miguel Ojeda
2026-01-30 12:34   ` FUJITA Tomonori

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.