[PATCH v12 13/15] rust: sync: lock/global: Add Backend parameter to GlobalGuard

From: Lyude Paul
Date: Thu Jul 17 2025 - 15:22:18 EST


Due to the introduction of sync::lock::Backend::Context, it's now possible
for normal locks to return a Guard with a different Backend than their
respective lock (e.g. Backend::BackendInContext). We want to be able to
support global locks with contexts as well, so add a trait bound to
explicitly specify which Backend is in use for a GlobalGuard.

Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx>
---
rust/kernel/sync/lock/global.rs | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/rust/kernel/sync/lock/global.rs b/rust/kernel/sync/lock/global.rs
index f846ecf9168e7..f9a9c4bdc46b0 100644
--- a/rust/kernel/sync/lock/global.rs
+++ b/rust/kernel/sync/lock/global.rs
@@ -77,14 +77,14 @@ pub unsafe fn init(&'static self) {
}

/// Lock this global lock.
- pub fn lock(&'static self) -> GlobalGuard<'static, G> {
+ pub fn lock(&'static self) -> GlobalGuard<'static, G, G::Backend> {
GlobalGuard {
inner: self.inner.lock(),
}
}

/// Try to lock this global lock.
- pub fn try_lock(&'static self) -> Option<GlobalGuard<'static, G>> {
+ pub fn try_lock(&'static self) -> Option<GlobalGuard<'static, G, G::Backend>> {
Some(GlobalGuard {
inner: self.inner.try_lock()?,
})
@@ -94,11 +94,11 @@ pub fn try_lock(&'static self) -> Option<GlobalGuard<'static, G>> {
/// A guard for a [`GlobalLock`].
///
/// See [`global_lock!`] for examples.
-pub struct GlobalGuard<'a, G: GlobalLockBackend> {
- inner: Guard<'a, G::Item, G::Backend>,
+pub struct GlobalGuard<'a, G: GlobalLockBackend, B: Backend> {
+ inner: Guard<'a, G::Item, B>,
}

-impl<'a, G: GlobalLockBackend> core::ops::Deref for GlobalGuard<'a, G> {
+impl<'a, G: GlobalLockBackend, B: Backend> core::ops::Deref for GlobalGuard<'a, G, B> {
type Target = G::Item;

fn deref(&self) -> &Self::Target {
@@ -106,7 +106,7 @@ fn deref(&self) -> &Self::Target {
}
}

-impl<'a, G: GlobalLockBackend> core::ops::DerefMut for GlobalGuard<'a, G> {
+impl<'a, G: GlobalLockBackend, B: Backend> core::ops::DerefMut for GlobalGuard<'a, G, B> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
@@ -154,7 +154,7 @@ impl<T: ?Sized, G: GlobalLockBackend> GlobalLockedBy<T, G> {
/// Access the value immutably.
///
/// The caller must prove shared access to the lock.
- pub fn as_ref<'a>(&'a self, _guard: &'a GlobalGuard<'_, G>) -> &'a T {
+ pub fn as_ref<'a, B: Backend>(&'a self, _guard: &'a GlobalGuard<'_, G, B>) -> &'a T {
// SAFETY: The lock is globally unique, so there can only be one guard.
unsafe { &*self.value.get() }
}
@@ -162,7 +162,7 @@ pub fn as_ref<'a>(&'a self, _guard: &'a GlobalGuard<'_, G>) -> &'a T {
/// Access the value mutably.
///
/// The caller must prove shared exclusive to the lock.
- pub fn as_mut<'a>(&'a self, _guard: &'a mut GlobalGuard<'_, G>) -> &'a mut T {
+ pub fn as_mut<'a, B: Backend>(&'a self, _guard: &'a mut GlobalGuard<'_, G, B>) -> &'a mut T {
// SAFETY: The lock is globally unique, so there can only be one guard.
unsafe { &mut *self.value.get() }
}
@@ -216,7 +216,7 @@ pub fn get_mut(&mut self) -> &mut T {
/// ```
/// # mod ex {
/// # use kernel::prelude::*;
-/// use kernel::sync::{GlobalGuard, GlobalLockedBy};
+/// use kernel::sync::{Backend, GlobalGuard, GlobalLockedBy};
///
/// kernel::sync::global_lock! {
/// // SAFETY: Initialized in module initializer before first use.
@@ -232,7 +232,7 @@ pub fn get_mut(&mut self) -> &mut T {
/// /// Increment the counter in this instance.
/// ///
/// /// The caller must hold the `MY_MUTEX` mutex.
-/// fn increment(&self, guard: &mut GlobalGuard<'_, MY_MUTEX>) -> u32 {
+/// fn increment<B: Backend>(&self, guard: &mut GlobalGuard<'_, MY_MUTEX, B>) -> u32 {
/// let my_counter = self.my_counter.as_mut(guard);
/// *my_counter += 1;
/// *my_counter
--
2.50.0