[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <tencent_E9A9DFA5B2C6059DAF39777A40FB86753606@qq.com>
Date: Sun, 2 Mar 2025 19:51:46 +0800
From: Guangbo Cui <2407018371@...com>
To: lyude@...hat.com
Cc: a.hindborg@...nel.org,
alex.gaynor@...il.com,
aliceryhl@...gle.com,
benno.lossin@...ton.me,
bjorn3_gh@...tonmail.com,
boqun.feng@...il.com,
gary@...yguo.net,
linux-kernel@...r.kernel.org,
longman@...hat.com,
mingo@...hat.com,
ojeda@...nel.org,
peterz@...radead.org,
rust-for-linux@...r.kernel.org,
tglx@...utronix.de,
tmgross@...ch.edu,
wedsonaf@...il.com,
will@...nel.org
Subject: Re: [PATCH v9 6/9] rust: sync: Add SpinLockIrq
> +/// A kernel `spinlock_t` lock backend that is acquired in interrupt disabled contexts.
> +pub struct SpinLockIrqBackend;
> +
> +/// A [`Guard`] acquired from locking a [`SpinLockIrq`] using [`lock()`].
> +///
> +/// This is simply a type alias for a [`Guard`] returned from locking a [`SpinLockIrq`] using
> +/// [`lock_with()`]. It will unlock the [`SpinLockIrq`] and decrement the local processor's
> +/// interrupt disablement refcount upon being dropped.
> +///
> +/// [`Guard`]: super::Guard
> +/// [`lock()`]: SpinLockIrq::lock
> +/// [`lock_with()`]: SpinLockIrq::lock_with
> +pub type SpinLockIrqGuard<'a, T> = super::Guard<'a, T, SpinLockIrqBackend>;
> +
> +// SAFETY: The underlying kernel `spinlock_t` object ensures mutual exclusion. `relock` uses the
> +// default implementation that always calls the same locking method.
> +unsafe impl super::Backend for SpinLockIrqBackend {
> + type State = bindings::spinlock_t;
> + type GuardState = ();
> +
> + unsafe fn init(
> + ptr: *mut Self::State,
> + name: *const crate::ffi::c_char,
> + key: *mut bindings::lock_class_key,
> + ) {
> + // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and
> + // `key` are valid for read indefinitely.
> + unsafe { bindings::__spin_lock_init(ptr, name, key) }
> + }
> +
> + unsafe fn lock(ptr: *mut Self::State) -> Self::GuardState {
> + // SAFETY: The safety requirements of this function ensure that `ptr` points to valid
> + // memory, and that it has been initialised before.
> + unsafe { bindings::spin_lock_irq_disable(ptr) }
> + }
> +
> + unsafe fn unlock(ptr: *mut Self::State, _guard_state: &Self::GuardState) {
> + // SAFETY: The safety requirements of this function ensure that `ptr` is valid and that the
> + // caller is the owner of the spinlock.
> + unsafe { bindings::spin_unlock_irq_enable(ptr) }
> + }
> +
> + unsafe fn try_lock(ptr: *mut Self::State) -> Option<Self::GuardState> {
> + // SAFETY: The `ptr` pointer is guaranteed to be valid and initialized before use.
> + let result = unsafe { bindings::spin_trylock_irq_disable(ptr) };
> +
> + if result != 0 {
> + Some(())
> + } else {
> + None
> + }
> + }
> +
> + unsafe fn assert_is_held(ptr: *mut Self::State) {
> + // SAFETY: The `ptr` pointer is guaranteed to be valid and initialized before use.
> + unsafe { bindings::spin_assert_is_held(ptr) }
> + }
> +}
It would be nice to add `SpinLockIrqBackend` to `global_lock`.
---
rust/kernel/sync/lock/global.rs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rust/kernel/sync/lock/global.rs b/rust/kernel/sync/lock/global.rs
index 480ee724e3..60b88f362b 100644
--- a/rust/kernel/sync/lock/global.rs
+++ b/rust/kernel/sync/lock/global.rs
@@ -298,4 +298,7 @@ macro_rules! global_lock_inner {
(backend SpinLock) => {
$crate::sync::lock::spinlock::SpinLockBackend
};
+ (backend SpinLockIrq) => {
+ $crate::sync::lock::spinlock::SpinLockIrqBackend
+ };
}
--
Best regards,
Guangbo Cui
Powered by blists - more mailing lists