From: Lyude Paul <lyude@redhat.com>
To: rust-for-linux@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Tamir Duberstein" <tamird@gmail.com>,
"Filipe Xavier" <felipe_life@live.com>,
"Martin Rodriguez Reboredo" <yakoyoku@gmail.com>,
"Valentin Obst" <kernel@valentinobst.de>,
"Danilo Krummrich" <dakr@kernel.org>,
"Wedson Almeida Filho" <walmeida@microsoft.com>
Subject: [PATCH 1/3] rust: sync: Add Lock::is_locked()
Date: Wed, 20 Nov 2024 17:30:41 -0500 [thread overview]
Message-ID: <20241120223442.2491136-2-lyude@redhat.com> (raw)
In-Reply-To: <20241120223442.2491136-1-lyude@redhat.com>
Now that we've added a Lock::from_raw() function and exposed Guard::new(),
it would be good to actually add the ability to assert the current state
of a lock to ensure correctness for unsafe code using these functions.
To do so, let's add Lock::is_locked() which simply returns whether or not a
Lock is acquired. We'll use this in the next few commits to add some debug
assertions.
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
rust/helpers/spinlock.c | 5 +++++
rust/kernel/sync/lock.rs | 18 ++++++++++++++++++
rust/kernel/sync/lock/mutex.rs | 5 +++++
rust/kernel/sync/lock/spinlock.rs | 5 +++++
4 files changed, 33 insertions(+)
diff --git a/rust/helpers/spinlock.c b/rust/helpers/spinlock.c
index b7b0945e8b3cb..90216a69e3ea1 100644
--- a/rust/helpers/spinlock.c
+++ b/rust/helpers/spinlock.c
@@ -26,3 +26,8 @@ int rust_helper_spin_trylock(spinlock_t *lock)
{
return spin_trylock(lock);
}
+
+bool rust_helper_spin_is_locked(spinlock_t *lock)
+{
+ return spin_is_locked(lock);
+}
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index 139f17f2ec86b..542f846ac02b2 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -85,6 +85,13 @@ unsafe fn relock(ptr: *mut Self::State, guard_state: &mut Self::GuardState) {
// SAFETY: The safety requirements ensure that the lock is initialised.
*guard_state = unsafe { Self::lock(ptr) };
}
+
+ /// Returns whether or not the lock is currently acquired.
+ ///
+ /// # Safety
+ ///
+ /// Callers must ensure that `ptr` is a valid initialised pointer to this lock type.
+ unsafe fn is_locked(ptr: *mut Self::State) -> bool;
}
/// A mutual exclusion primitive.
@@ -170,6 +177,17 @@ pub fn try_lock(&self) -> Option<Guard<'_, T, B>> {
// that `init` was called.
unsafe { B::try_lock(self.state.get()).map(|state| Guard::new(self, state)) }
}
+
+ /// Return whether or not the lock is currently acquired.
+ ///
+ /// Keep in mind that this function is inherently racy: a lock could immediately be acquired or
+ /// released after this function returns. As such, the return value from this function should be
+ /// treated as a snapshot for debugging purposes.
+ pub fn is_locked(&self) -> bool {
+ // SAFETY: The constructor of the type calls `init`, so the existence of the object proves
+ // that `init` was called.
+ unsafe { B::is_locked(self.state.get()) }
+ }
}
/// A lock guard.
diff --git a/rust/kernel/sync/lock/mutex.rs b/rust/kernel/sync/lock/mutex.rs
index 0e946ebefce12..f21b1f14cbe1b 100644
--- a/rust/kernel/sync/lock/mutex.rs
+++ b/rust/kernel/sync/lock/mutex.rs
@@ -126,4 +126,9 @@ unsafe fn try_lock(ptr: *mut Self::State) -> Option<Self::GuardState> {
None
}
}
+
+ unsafe fn is_locked(ptr: *mut Self::State) -> bool {
+ // SAFETY: The `ptr` pointer is guaranteed to be valid and initialized before use.
+ unsafe { bindings::mutex_is_locked(ptr) }
+ }
}
diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spinlock.rs
index 9f4d128bed983..cfccf5e900b80 100644
--- a/rust/kernel/sync/lock/spinlock.rs
+++ b/rust/kernel/sync/lock/spinlock.rs
@@ -125,4 +125,9 @@ unsafe fn try_lock(ptr: *mut Self::State) -> Option<Self::GuardState> {
None
}
}
+
+ unsafe fn is_locked(ptr: *mut Self::State) -> bool {
+ // SAFETY: The `ptr` pointer is guaranteed to be valid and initialized before use.
+ unsafe { bindings::spin_is_locked(ptr) }
+ }
}
--
2.47.0
next prev parent reply other threads:[~2024-11-20 22:35 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-20 22:30 [PATCH 0/3] rust: sync: Add Lock::is_locked() Lyude Paul
2024-11-20 22:30 ` Lyude Paul [this message]
2024-11-20 23:53 ` [PATCH 1/3] " Boqun Feng
2024-11-20 22:30 ` [PATCH 2/3] rust: sync: Assert Lock::is_locked in Guard::new for debug builds Lyude Paul
2024-11-20 23:59 ` Boqun Feng
2024-11-22 20:30 ` Lyude Paul
2024-11-25 21:30 ` Boqun Feng
2024-11-20 22:30 ` [PATCH 3/3] rust: sync: Add Guard::new_unchecked() Lyude Paul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241120223442.2491136-2-lyude@redhat.com \
--to=lyude@redhat.com \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=felipe_life@live.com \
--cc=gary@garyguo.net \
--cc=kernel@valentinobst.de \
--cc=linux-kernel@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@gmail.com \
--cc=tmgross@umich.edu \
--cc=walmeida@microsoft.com \
--cc=yakoyoku@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.