Re: [PATCH v9 6/9] rust: sync: Add SpinLockIrq

From: Guangbo Cui
Date: Sun Mar 02 2025 - 07:04:15 EST


> +/// 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