Skip to content

Commit 8830532

Browse files
committed
rust: sync: Add LockdepMap abstraction
This allows Rust code to explicitly integrate types with lockdep. Signed-off-by: Asahi Lina <[email protected]>
1 parent 8f37ff8 commit 8830532

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

rust/bindings/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/iosys-map.h>
2424
#include <linux/io-pgtable.h>
2525
#include <linux/ktime.h>
26+
#include <linux/lockdep.h>
2627
#include <linux/of.h>
2728
#include <linux/of_address.h>
2829
#include <linux/of_device.h>

rust/helpers.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <linux/dma-mapping.h>
3030
#include <linux/err.h>
3131
#include <linux/errname.h>
32+
#include <linux/instruction_pointer.h>
33+
#include <linux/lockdep.h>
3234
#include <linux/of.h>
3335
#include <linux/of_device.h>
3436
#include <linux/platform_device.h>
@@ -159,6 +161,20 @@ u64 rust_helper_siphash(const void *data, size_t len,
159161
}
160162
EXPORT_SYMBOL_GPL(rust_helper_siphash);
161163

164+
void rust_helper_lock_acquire_ret(struct lockdep_map *lock, unsigned int subclass,
165+
int trylock, int read, int check,
166+
struct lockdep_map *nest_lock)
167+
{
168+
lock_acquire(lock, subclass, trylock, read, check, nest_lock, _RET_IP_);
169+
}
170+
EXPORT_SYMBOL_GPL(rust_helper_lock_acquire_ret);
171+
172+
void rust_helper_lock_release_ret(struct lockdep_map *lock)
173+
{
174+
lock_release(lock, _RET_IP_);
175+
}
176+
EXPORT_SYMBOL_GPL(rust_helper_lock_release_ret);
177+
162178
void rust_helper_xa_init_flags(struct xarray *xa, gfp_t flags)
163179
{
164180
xa_init_flags(xa, flags);

rust/kernel/sync/lockdep.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,43 @@ pub(crate) fn caller_lock_class() -> (LockClassKey, &'static CStr) {
187187
}
188188
}
189189
}
190+
191+
pub(crate) struct LockdepMap(Opaque<bindings::lockdep_map>);
192+
pub(crate) struct LockdepGuard<'a>(&'a LockdepMap);
193+
194+
#[allow(dead_code)]
195+
impl LockdepMap {
196+
#[track_caller]
197+
pub(crate) fn new() -> Self {
198+
let map = Opaque::uninit();
199+
let (key, name) = caller_lock_class();
200+
201+
unsafe {
202+
bindings::lockdep_init_map_type(
203+
map.get(),
204+
name.as_char_ptr(),
205+
key.as_ptr(),
206+
0,
207+
bindings::lockdep_wait_type_LD_WAIT_INV as _,
208+
bindings::lockdep_wait_type_LD_WAIT_INV as _,
209+
bindings::lockdep_lock_type_LD_LOCK_NORMAL as _,
210+
)
211+
};
212+
213+
LockdepMap(map)
214+
}
215+
216+
#[inline(always)]
217+
pub(crate) fn lock(&self) -> LockdepGuard<'_> {
218+
unsafe { bindings::lock_acquire_ret(self.0.get(), 0, 0, 1, 1, core::ptr::null_mut()) };
219+
220+
LockdepGuard(self)
221+
}
222+
}
223+
224+
impl<'a> Drop for LockdepGuard<'a> {
225+
#[inline(always)]
226+
fn drop(&mut self) {
227+
unsafe { bindings::lock_release_ret(self.0 .0.get()) };
228+
}
229+
}

0 commit comments

Comments
 (0)