xref: /linux/rust/kernel/sync/rcu.rs (revision f4cdf7ca9a1fdcca413157df19753f388a5a224e)
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, types::NotThreadSafe};
8 
9 /// Evidence that the RCU read side lock is held on the current thread/CPU.
10 ///
11 /// The type is explicitly not `Send` because this property is per-thread/CPU.
12 ///
13 /// # Invariants
14 ///
15 /// The RCU read side lock is actually held while instances of this guard exist.
16 pub struct Guard(NotThreadSafe);
17 
18 impl Guard {
19     /// Acquires the RCU read side lock and returns a guard.
20     #[inline]
21     pub fn new() -> Self {
22         // SAFETY: An FFI call with no additional requirements.
23         unsafe { bindings::rcu_read_lock() };
24         // INVARIANT: The RCU read side lock was just acquired above.
25         Self(NotThreadSafe)
26     }
27 
28     /// Explicitly releases the RCU read side lock.
29     #[inline]
30     pub fn unlock(self) {}
31 }
32 
33 impl Default for Guard {
34     #[inline]
35     fn default() -> Self {
36         Self::new()
37     }
38 }
39 
40 impl Drop for Guard {
41     #[inline]
42     fn drop(&mut self) {
43         // SAFETY: By the type invariants, the RCU read side is locked, so it is ok to unlock it.
44         unsafe { bindings::rcu_read_unlock() };
45     }
46 }
47 
48 /// Acquires the RCU read side lock.
49 #[inline]
50 pub fn read_lock() -> Guard {
51     Guard::new()
52 }
53 
54 /// Wait until all in-flight `call_rcu()` callbacks complete.
55 ///
56 /// Note that this primitive does not necessarily wait for an RCU grace period
57 /// to complete. For example, if there are no RCU callbacks queued anywhere
58 /// in the system, then [`rcu_barrier()`] is within its rights to return
59 /// immediately, without waiting for anything, much less an RCU grace period.
60 /// In fact, [`rcu_barrier()`] will normally not result in any RCU grace periods
61 /// beyond those that were already destined to be executed.
62 ///
63 /// In kernels built with `CONFIG_RCU_LAZY=y`, this function also hurries all
64 /// pending lazy RCU callbacks.
65 ///
66 /// Note that this is one of the RCU primitives which must not be called in
67 /// atomic context.
68 #[inline]
69 pub fn rcu_barrier() {
70     // SAFETY: `rcu_barrier()` is always safe to be called. It just might wait for a grace period.
71     unsafe { bindings::rcu_barrier() };
72 }
73 
74 /// Wait for one RCU grace period.
75 ///
76 /// Waits for all RCU read-side critical sections (such as those established by
77 /// a [`Guard`]) at the moment of the function call to finish.
78 ///
79 /// Does not prevent new read-side critical sections from starting, which may
80 /// begin and run while this call is blocking.
81 ///
82 /// Note that this is one of the RCU primitives which must not be called in
83 /// atomic context.
84 #[inline]
85 pub fn synchronize_rcu() {
86     // SAFETY: `synchronize_rcu()` is always safe to be called from process context.
87     unsafe { bindings::synchronize_rcu() };
88 }
89