summaryrefslogtreecommitdiff
path: root/rust/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel')
-rw-r--r--rust/kernel/devres.rs7
1 files changed, 7 insertions, 0 deletions
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<T: Send + 'static> Devres<T> {
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<T: Send + 'static> Drop for Devres<T> {
// 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`