diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs index 4a1e5eec78ab..ebb5c19e851e 100644 --- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -269,6 +269,11 @@ impl Devres { if inner.data.revoke() { inner.revocation.complete_all(); + } else { + // Devres::drop() is concurrently revoking; wait for it to finish `drop_in_place()` + // before returning to `devres_release_all()`, ensuring `T` is fully torn down before + // the device finishes unbinding. + inner.revocation.wait_for_completion(); } } @@ -366,6 +371,8 @@ impl Drop for Devres { // SAFETY: When `drop` runs, it is guaranteed that nobody is accessing the revocable data // anymore, hence it is safe not to wait for the grace period to finish. if unsafe { self.data().revoke_nosync() } { + self.inner.revocation.complete_all(); + // We revoked `self.data` before devres did, hence try to remove it. if self.remove_node() { // SAFETY: In `Self::new` we have taken an additional reference count of `self.data`