Skip to content

Commit 0b4baaf

Browse files
committed
rust: add rcu abstraction
Based on wedsonaf@02541e6
1 parent 9b58f17 commit 0b4baaf

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

rust/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ RUST_HELPERS := \
1414
err \
1515
kunit \
1616
mutex \
17+
rcu \
1718
refcount \
1819
signal \
1920
spinlock\

rust/helpers/rcu.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/rcupdate.h>
4+
5+
void rust_helper_rcu_read_lock(void)
6+
{
7+
rcu_read_lock();
8+
}
9+
EXPORT_SYMBOL_GPL(rust_helper_rcu_read_lock);
10+
11+
void rust_helper_rcu_read_unlock(void)
12+
{
13+
rcu_read_unlock();
14+
}
15+
EXPORT_SYMBOL_GPL(rust_helper_rcu_read_unlock);

rust/kernel/sync.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod arc;
1111
mod condvar;
1212
pub mod lock;
1313
mod locked_by;
14+
pub mod rcu;
1415

1516
pub use arc::{Arc, ArcBorrow, UniqueArc};
1617
pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};

rust/kernel/sync/rcu.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! RCU support.
4+
//!
5+
//! C header: [`include/linux/rcupdate.h`](../../../../include/linux/rcupdate.h)
6+
7+
use crate::bindings;
8+
use core::marker::PhantomData;
9+
10+
/// Evidence that the RCU read side lock is held on the current thread/CPU.
11+
///
12+
/// The type is explicitly not `Send` because this property is per-thread/CPU.
13+
///
14+
/// # Invariants
15+
///
16+
/// The RCU read side lock is actually held while instances of this guard exist.
17+
pub struct Guard {
18+
_not_send: PhantomData<*mut ()>,
19+
}
20+
21+
impl Guard {
22+
/// Acquires the RCU read side lock and returns a guard.
23+
pub fn new() -> Self {
24+
// SAFETY: An FFI call with no additional requirements.
25+
unsafe { bindings::rcu_read_lock() };
26+
// INVARIANT: The RCU read side lock was just acquired above.
27+
Self {
28+
_not_send: PhantomData,
29+
}
30+
}
31+
32+
/// Explicitly releases the RCU read side lock.
33+
pub fn unlock(self) {}
34+
}
35+
36+
impl Default for Guard {
37+
fn default() -> Self {
38+
Self::new()
39+
}
40+
}
41+
42+
impl Drop for Guard {
43+
fn drop(&mut self) {
44+
// SAFETY: By the type invariants, the rcu read side is locked, so it is ok to unlock it.
45+
unsafe { bindings::rcu_read_unlock() };
46+
}
47+
}
48+
49+
/// Acquires the RCU read side lock.
50+
pub fn read_lock() -> Guard {
51+
Guard::new()
52+
}

0 commit comments

Comments
 (0)