[PATCH 0/3] rust: sync: add SetOnce::try_get_or_populate()

From: Alice Ryhl

Date: Wed Jul 22 2026 - 05:19:21 EST


The SetOnce::populate() method does not internally synchronize callers
that fail to populate the value with the successful call. This means
that naive loops using as_ref() and populate() can lead to spinning on
the initialization, which is best avoided. Thus, provide a helper that
avoids this issue using a user-provided lock.

One potential alternative is to change populate() so that the failing
caller actually does synchronize with the successful call to populate().
However, this is somewhat tricky:

* There are users of SetOnce that construct it in const context, and we
currently don't have the ability to do that for most locks, so we
cannot easily add a lock to SetOnce.
* Just spinning on the atomic is undesirable unless we disable
preemption in the success path. If we do disable preemption, then that
raises complications for handling the PREEMPT_RT case.
* It also raises questions about deadlocks if populate() is called from
irqs.

By using a user-provided lock, we do not have to worry about these
issues inside SetOnce.

This series is based on char-misc-next.

Signed-off-by: Alice Ryhl <aliceryhl@xxxxxxxxxx>
---
Alice Ryhl (3):
rust: sync: return `Result<&T, T>` from `SetOnce::populate()`
rust: sync: add SetOnce::try_get_or_populate()
rust_binder: use SetOnce::try_get_or_populate()

drivers/android/binder/process.rs | 16 +++--------
rust/kernel/module_param.rs | 8 +++---
rust/kernel/sync/set_once.rs | 58 ++++++++++++++++++++++++++++++++-------
3 files changed, 56 insertions(+), 26 deletions(-)
---
base-commit: 2cedf2272f1bb42471e646868ac572cc5752bd91
change-id: 20260721-setonce-populate-f2a9b61aeb1d

Best regards,
--
Alice Ryhl <aliceryhl@xxxxxxxxxx>