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]>


Reply via email to