]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rust: add rcu abstraction
authorWedson Almeida Filho <wedsonaf@gmail.com>
Thu, 19 Dec 2024 17:04:06 +0000 (18:04 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Dec 2024 16:19:26 +0000 (17:19 +0100)
Add a simple abstraction to guard critical code sections with an rcu
read lock.

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
Co-developed-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Tested-by: Fabien Parent <fabien.parent@linaro.org>
Link: https://lore.kernel.org/r/20241219170425.12036-5-dakr@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
MAINTAINERS
rust/helpers/helpers.c
rust/helpers/rcu.c [new file with mode: 0644]
rust/kernel/sync.rs
rust/kernel/sync/rcu.rs [new file with mode: 0644]

index f330a08cd293902a4b3401bbd4674caab6870d83..8e02ab45184ac571e060d3065307d0a2ff795ae8 100644 (file)
@@ -19691,6 +19691,7 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 F:     Documentation/RCU/
 F:     include/linux/rcu*
 F:     kernel/rcu/
+F:     rust/kernel/sync/rcu.rs
 X:     Documentation/RCU/torture.rst
 X:     include/linux/srcu*.h
 X:     kernel/rcu/srcu*.c
index dcf827a61b52e71e46fd5378878602eef5e538b6..060750af65245758e72ce52d7236e330c9a7c124 100644 (file)
@@ -20,6 +20,7 @@
 #include "page.c"
 #include "pid_namespace.c"
 #include "rbtree.c"
+#include "rcu.c"
 #include "refcount.c"
 #include "security.c"
 #include "signal.c"
diff --git a/rust/helpers/rcu.c b/rust/helpers/rcu.c
new file mode 100644 (file)
index 0000000..f1cec65
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/rcupdate.h>
+
+void rust_helper_rcu_read_lock(void)
+{
+       rcu_read_lock();
+}
+
+void rust_helper_rcu_read_unlock(void)
+{
+       rcu_read_unlock();
+}
index 1eab7ebf25fd39d343bdab5856152177b4bfa8d4..0654008198b2bec4a3b7a0b6010544ec7e282997 100644 (file)
@@ -12,6 +12,7 @@ mod condvar;
 pub mod lock;
 mod locked_by;
 pub mod poll;
+pub mod rcu;
 
 pub use arc::{Arc, ArcBorrow, UniqueArc};
 pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};
diff --git a/rust/kernel/sync/rcu.rs b/rust/kernel/sync/rcu.rs
new file mode 100644 (file)
index 0000000..b51d915
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! RCU support.
+//!
+//! C header: [`include/linux/rcupdate.h`](srctree/include/linux/rcupdate.h)
+
+use crate::{bindings, types::NotThreadSafe};
+
+/// Evidence that the RCU read side lock is held on the current thread/CPU.
+///
+/// The type is explicitly not `Send` because this property is per-thread/CPU.
+///
+/// # Invariants
+///
+/// The RCU read side lock is actually held while instances of this guard exist.
+pub struct Guard(NotThreadSafe);
+
+impl Guard {
+    /// Acquires the RCU read side lock and returns a guard.
+    pub fn new() -> Self {
+        // SAFETY: An FFI call with no additional requirements.
+        unsafe { bindings::rcu_read_lock() };
+        // INVARIANT: The RCU read side lock was just acquired above.
+        Self(NotThreadSafe)
+    }
+
+    /// Explicitly releases the RCU read side lock.
+    pub fn unlock(self) {}
+}
+
+impl Default for Guard {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Drop for Guard {
+    fn drop(&mut self) {
+        // SAFETY: By the type invariants, the RCU read side is locked, so it is ok to unlock it.
+        unsafe { bindings::rcu_read_unlock() };
+    }
+}
+
+/// Acquires the RCU read side lock.
+pub fn read_lock() -> Guard {
+    Guard::new()
+}