Re: [PATCH v1 1/2] rust: Add support for calling a function exactly once

Boqun Feng
2025-11-14T15:03:12Z

On Wed, Nov 12, 2025 at 10:10:14AM +0100, Andreas Hindborg wrote:
> Boqun Feng <boqun.feng@gmail.com> writes:
>
> > On Wed, Nov 12, 2025 at 06:43:49AM +0900, FUJITA Tomonori wrote:
> >> On Mon, 10 Nov 2025 21:17:08 -0800
> >> Boqun Feng <boqun.feng@gmail.com> wrote:
> >>
> >> > On Tue, Nov 11, 2025 at 12:09:49PM +0900, FUJITA Tomonori wrote:
> >> >> On Mon, 10 Nov 2025 08:14:56 -0800
> >> >> Boqun Feng <boqun.feng@gmail.com> wrote:
> >> >>
> >> >> > On Mon, Nov 10, 2025 at 06:21:50PM +0900, FUJITA Tomonori wrote:
> >> >> >> On Fri, 7 Nov 2025 09:03:01 +0000
> >> >> >> Alice Ryhl <aliceryhl@google.com> wrote:
> >> >> >>
> >> >> >> >> That's my point (and probably also Andreas' point), we already has the
> >> >> >> >> type `SetOnce` to do this, no need for a `OnceLite` type if not
> >> >> >> >> necessary, and the fact that it can be zero'd by debugfs doesn't change
> >> >> >> >> it as I explained above.
> >> >> >> >
> >> >> >> > The SetOnce type doesn't do the same thing as OnceLite. SetOnce has
> >> >> >> > three different states, but OnceLite only needs two. I don't think we
> >> >> >> > should be reusing SetOnce here.
> >> >> >
> >> >> > I mean 3 states should cover 2 states, right? In this case we only need
> >> >> > to support SetOnce<()>, so I think it's fine, see below:
> >> >>
> >> >> Yeah, that would remove access to the value member, but I think that
> >> >> init member could still be accessed in an unintended way.
> >> >>
> >> >
> >> > What an unintended way you mean? Do you have an example?
> >>
> >> From my understanding, the init member of SetOnce is designed to be
> >> accessed by using atomic operations, only through its methods. If we
> >> use SetOnce for OnceLite, however, the init member would be written
> >> using non-atomic operations, which is what I referred to as the
> >> "unintended way" since I don't believe Andreas intended it to be
> >> modified in that manner; i.e., not through its methods or by
> >> non-atomic operations.
> >>
> >
> > Ok, the "non-atomic operations" seems to be a distraction for me to see
> > the real problem ;-) Let's clear things out a bit.
> >
> > First of all, data races are not allowed in kernel, but kernel has
> > special rules about data races, namely, a few operation should be
> > treated as "per-byte atomics" so that they will have defined behaviors.
> > This is kinda a gray area, but it's what it is.
>
> In general, I would assume that a 32 bit rust atomic read racing with
> "per-byte atomic" writes to the field is not great. We would risk
> observing torn writes?
>

Given that OnceLite only has one byte that can be non-zero, it's fine.
Also if that's a problem, we should just change the memset() part as I
posted [1]. I believe that's a better fix (regardless of using i8 or
i32).

Regards,
Boqun

[1]: https://lore.kernel.org/rust-for-linux/aRPvjQJLdzvxLUpr@tardis.local/

> We could use a u8 atomic in this case?
>
>
> Best regards,
> Andreas Hindborg
>
>
>