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: indicate whether `data` has been revoked already

Return a boolean from Revocable::revoke() and Revocable::revoke_nosync()
to indicate whether the data has been revoked already.

Return true if the data hasn't been revoked yet (i.e. this call revoked
the data), false otherwise.

This is required by Devres in order to synchronize the completion of the
revoke process.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20250612121817.1621-3-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

+14 -4
+14 -4
rust/kernel/revocable.rs
··· 154 154 /// # Safety 155 155 /// 156 156 /// Callers must ensure that there are no more concurrent users of the revocable object. 157 - unsafe fn revoke_internal<const SYNC: bool>(&self) { 158 - if self.is_available.swap(false, Ordering::Relaxed) { 157 + unsafe fn revoke_internal<const SYNC: bool>(&self) -> bool { 158 + let revoke = self.is_available.swap(false, Ordering::Relaxed); 159 + 160 + if revoke { 159 161 if SYNC { 160 162 // SAFETY: Just an FFI call, there are no further requirements. 161 163 unsafe { bindings::synchronize_rcu() }; ··· 167 165 // `compare_exchange` above that takes `is_available` from `true` to `false`. 168 166 unsafe { drop_in_place(self.data.get()) }; 169 167 } 168 + 169 + revoke 170 170 } 171 171 172 172 /// Revokes access to and drops the wrapped object. ··· 176 172 /// Access to the object is revoked immediately to new callers of [`Revocable::try_access`], 177 173 /// expecting that there are no concurrent users of the object. 178 174 /// 175 + /// Returns `true` if `&self` has been revoked with this call, `false` if it was revoked 176 + /// already. 177 + /// 179 178 /// # Safety 180 179 /// 181 180 /// Callers must ensure that there are no more concurrent users of the revocable object. 182 - pub unsafe fn revoke_nosync(&self) { 181 + pub unsafe fn revoke_nosync(&self) -> bool { 183 182 // SAFETY: By the safety requirement of this function, the caller ensures that nobody is 184 183 // accessing the data anymore and hence we don't have to wait for the grace period to 185 184 // finish. ··· 196 189 /// If there are concurrent users of the object (i.e., ones that called 197 190 /// [`Revocable::try_access`] beforehand and still haven't dropped the returned guard), this 198 191 /// function waits for the concurrent access to complete before dropping the wrapped object. 199 - pub fn revoke(&self) { 192 + /// 193 + /// Returns `true` if `&self` has been revoked with this call, `false` if it was revoked 194 + /// already. 195 + pub fn revoke(&self) -> bool { 200 196 // SAFETY: By passing `true` we ask `revoke_internal` to wait for the grace period to 201 197 // finish. 202 198 unsafe { self.revoke_internal::<true>() }