On Tue, Jun 24, 2025 at 06:15:43PM +0200, Danilo Krummrich wrote: > Oh, so you meant adding this to the safety comment. Yes, that makes sense. Maybe > ScopeGuard works too, as you say. diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs index 2591cacecb7b..afd73a8c6012 100644 --- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -14,7 +14,7 @@ prelude::*, revocable::{Revocable, RevocableGuard}, sync::{rcu, Completion}, - types::{ARef, ForeignOwnable, Opaque}, + types::{ARef, ForeignOwnable, ScopeGuard, Opaque}, }; use core::ops::Deref; @@ -177,15 +177,15 @@ fn data(&self) -> &Revocable<T> { // hence `ptr` must be a valid pointer to `Inner`. let inner = unsafe { &*ptr.cast::<Inner<T>>() }; + // Ensure that `inner` can't be used anymore after we signal completion of this callback. + let inner = ScopeGuard::new_with_data(inner, |inner| inner.devm.complete_all()); + if !inner.data.revoke() { // If `revoke()` returns false, it means that `Devres::drop` already started revoking // `data` for us. Hence we have to wait until `Devres::drop` signals that it // completed revoking `data`. inner.revoke.wait_for_completion(); } - - // Signal that we're done using `inner`. - inner.devm.complete_all(); } fn remove_action(&self) -> bool { Is this what you thought of?