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 <[email protected]> --- 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 <[email protected]>

