Skip to content

Commit 4b76faf

Browse files
author
Danilo Krummrich
committed
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 <[email protected]> Acked-by: Miguel Ojeda <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Danilo Krummrich <[email protected]>
1 parent 1b56e76 commit 4b76faf

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

rust/kernel/revocable.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ impl<T> Revocable<T> {
154154
/// # Safety
155155
///
156156
/// 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 {
159161
if SYNC {
160162
// SAFETY: Just an FFI call, there are no further requirements.
161163
unsafe { bindings::synchronize_rcu() };
@@ -165,17 +167,22 @@ impl<T> Revocable<T> {
165167
// `compare_exchange` above that takes `is_available` from `true` to `false`.
166168
unsafe { drop_in_place(self.data.get()) };
167169
}
170+
171+
revoke
168172
}
169173

170174
/// Revokes access to and drops the wrapped object.
171175
///
172176
/// Access to the object is revoked immediately to new callers of [`Revocable::try_access`],
173177
/// expecting that there are no concurrent users of the object.
174178
///
179+
/// Returns `true` if `&self` has been revoked with this call, `false` if it was revoked
180+
/// already.
181+
///
175182
/// # Safety
176183
///
177184
/// Callers must ensure that there are no more concurrent users of the revocable object.
178-
pub unsafe fn revoke_nosync(&self) {
185+
pub unsafe fn revoke_nosync(&self) -> bool {
179186
// SAFETY: By the safety requirement of this function, the caller ensures that nobody is
180187
// accessing the data anymore and hence we don't have to wait for the grace period to
181188
// finish.
@@ -189,7 +196,10 @@ impl<T> Revocable<T> {
189196
/// If there are concurrent users of the object (i.e., ones that called
190197
/// [`Revocable::try_access`] beforehand and still haven't dropped the returned guard), this
191198
/// function waits for the concurrent access to complete before dropping the wrapped object.
192-
pub fn revoke(&self) {
199+
///
200+
/// Returns `true` if `&self` has been revoked with this call, `false` if it was revoked
201+
/// already.
202+
pub fn revoke(&self) -> bool {
193203
// SAFETY: By passing `true` we ask `revoke_internal` to wait for the grace period to
194204
// finish.
195205
unsafe { self.revoke_internal::<true>() }

0 commit comments

Comments
 (0)