Skip to content

Commit 0a6f906

Browse files
wedsonafDanilo Krummrich
authored andcommitted
rust: add rcu abstraction
Add a simple abstraction to guard critical code sections with an rcu read lock. Co-developed-by: Andreas Hindborg <[email protected]> Signed-off-by: Andreas Hindborg <[email protected]> Signed-off-by: Wedson Almeida Filho <[email protected]> Signed-off-by: Danilo Krummrich <[email protected]>
1 parent 9452b05 commit 0a6f906

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

rust/helpers/helpers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "mutex.c"
1717
#include "page.c"
1818
#include "rbtree.c"
19+
#include "rcu.c"
1920
#include "refcount.c"
2021
#include "signal.c"
2122
#include "slab.c"

rust/helpers/rcu.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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+
10+
void rust_helper_rcu_read_unlock(void)
11+
{
12+
rcu_read_unlock();
13+
}

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`](srctree/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)