Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust/revocable: add try_access_with() convenience method

Revocable::try_access() returns a guard through which the wrapped object
can be accessed. Code that can sleep is not allowed while the guard is
held; thus, it is common for the caller to explicitly drop it before
running sleepable code, e.g:

let b = bar.try_access()?;
let reg = b.readl(...);

// Don't forget this or things could go wrong!
drop(b);

something_that_might_sleep();

let b = bar.try_access()?;
let reg2 = b.readl(...);

This is arguably error-prone. try_access_with() provides an arguably
safer alternative, by taking a closure that is run while the guard is
held, and by dropping the guard automatically after the closure
completes. This way, code can be organized more clearly around the
critical sections and the risk of forgetting to release the guard when
needed is considerably reduced:

let reg = bar.try_access_with(|b| b.readl(...))?;

something_that_might_sleep();

let reg2 = bar.try_access_with(|b| b.readl(...))?;

The closure can return nothing, or any value including a Result which is
then wrapped inside the Option returned by try_access_with. Error
management is driver-specific, so users are encouraged to create their
own macros that map and flatten the returned values to something
appropriate for the code they are working on.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20250411-try_with-v4-1-f470ac79e2e2@nvidia.com
[ Link `None`, `Some`, `Option` in doc-comment. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

authored by

Alexandre Courbot and committed by
Danilo Krummrich
80e62fce 96609a19

+16
+16
rust/kernel/revocable.rs
··· 123 123 } 124 124 } 125 125 126 + /// Tries to access the wrapped object and run a closure on it while the guard is held. 127 + /// 128 + /// This is a convenience method to run short non-sleepable code blocks while ensuring the 129 + /// guard is dropped afterwards. [`Self::try_access`] carries the risk that the caller will 130 + /// forget to explicitly drop that returned guard before calling sleepable code; this method 131 + /// adds an extra safety to make sure it doesn't happen. 132 + /// 133 + /// Returns [`None`] if the object has been revoked and is therefore no longer accessible, or 134 + /// the result of the closure wrapped in [`Some`]. If the closure returns a [`Result`] then the 135 + /// return type becomes `Option<Result<>>`, which can be inconvenient. Users are encouraged to 136 + /// define their own macro that turns the [`Option`] into a proper error code and flattens the 137 + /// inner result into it if it makes sense within their subsystem. 138 + pub fn try_access_with<R, F: FnOnce(&T) -> R>(&self, f: F) -> Option<R> { 139 + self.try_access().map(|t| f(&*t)) 140 + } 141 + 126 142 /// # Safety 127 143 /// 128 144 /// Callers must ensure that there are no more concurrent users of the revocable object.