Skip to content

Commit bd102b8

Browse files
committed
rust: sync: Add dummy LockClassKey implementation for !CONFIG_LOCKDEP
Lock classes aren't used without lockdep. The C side declares the key as an empty struct in that case, but let's make it an explicit ZST in Rust, implemented in a separate module. This allows us to more easily guarantee that the lockdep code will be trivially optimized out without CONFIG_LOCKDEP, including LockClassKey arguments that are passed around. Depending on whether CONFIG_LOCKDEP is enabled or not, we then import the real lockdep implementation or the dummy one. Signed-off-by: Asahi Lina <[email protected]>
1 parent 17f4af3 commit bd102b8

3 files changed

Lines changed: 55 additions & 21 deletions

File tree

rust/kernel/sync.rs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,24 @@
55
//! This module contains the kernel APIs related to synchronisation that have been ported or
66
//! wrapped for usage by Rust code in the kernel.
77
8-
use crate::types::Opaque;
9-
108
mod arc;
119
mod condvar;
1210
pub mod lock;
1311
mod locked_by;
1412

13+
#[cfg(CONFIG_LOCKDEP)]
14+
mod lockdep;
15+
#[cfg(not(CONFIG_LOCKDEP))]
16+
mod no_lockdep;
17+
#[cfg(not(CONFIG_LOCKDEP))]
18+
use no_lockdep as lockdep;
19+
1520
pub use arc::{Arc, ArcBorrow, UniqueArc};
1621
pub use condvar::CondVar;
1722
pub use lock::{mutex::Mutex, spinlock::SpinLock};
23+
pub use lockdep::LockClassKey;
1824
pub use locked_by::LockedBy;
1925

20-
/// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
21-
#[repr(transparent)]
22-
pub struct LockClassKey(Opaque<bindings::lock_class_key>);
23-
24-
// SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and
25-
// provides its own synchronization.
26-
unsafe impl Sync for LockClassKey {}
27-
28-
impl LockClassKey {
29-
/// Creates a new lock class key.
30-
pub const fn new() -> Self {
31-
Self(Opaque::uninit())
32-
}
33-
34-
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
35-
self.0.get()
36-
}
37-
}
38-
3926
/// Defines a new static lock class and returns a pointer to it.
4027
#[doc(hidden)]
4128
#[macro_export]

rust/kernel/sync/lockdep.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Lockdep utilities.
4+
//!
5+
//! This module abstracts the parts of the kernel lockdep API relevant to Rust
6+
//! modules, including lock classes.
7+
8+
use crate::types::Opaque;
9+
10+
/// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
11+
#[repr(transparent)]
12+
pub struct LockClassKey(Opaque<bindings::lock_class_key>);
13+
14+
impl LockClassKey {
15+
/// Creates a new lock class key.
16+
pub const fn new() -> Self {
17+
Self(Opaque::uninit())
18+
}
19+
20+
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
21+
self.0.get()
22+
}
23+
}
24+
25+
// SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and
26+
// provides its own synchronization.
27+
unsafe impl Sync for LockClassKey {}
28+

rust/kernel/sync/no_lockdep.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Dummy lockdep utilities.
4+
//!
5+
//! Takes the place of the `lockdep` module when lockdep is disabled.
6+
7+
/// A dummy, zero-sized lock class.
8+
pub struct LockClassKey();
9+
10+
impl LockClassKey {
11+
/// Creates a new dummy lock class key.
12+
pub const fn new() -> Self {
13+
Self()
14+
}
15+
16+
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
17+
core::ptr::null_mut()
18+
}
19+
}

0 commit comments

Comments
 (0)