mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 04:03:23 -04:00
Pull locking updates from Ingo Molnar:
"Futexes:
- Use runtime constants for futex_hash computation (K Prateek Nayak,
Peter Zijlstra)
- Optimise the size check get_futex_key() (Sebastian Andrzej Siewior)
- Avoid private hash use-after-free on final put (Felix Hoffmann)
- Tell kmemleak we're not leaking __futex_queues (Peter Zijlstra)
Rust integration updates:
- Implement refcounted interrupt disable and SpinLockIrq for Rust
(Boqun Feng, Heiko Carstens, Joel Fernandes, Lyude Paul)
- Rust sync: add helpers for mb, dma_mb and friends; add generic
memory barriers and use LKMM atomics instead of Rust atomics in the
revocable code (Gary Guo)
- Add abstraction and integrate synchronize_rcu() (Philipp Stanner)
Lock debugging:
- Add qspinlock contended_release tracepoint (Dmitry Ilvokhin, Peter
Zijlstra)
- Enable the printing of held locks of remote running tasks and print
task CPU (Ingo Molnar)
- percpu-rwsem: Annotate intentional data race in readers_active_check()
(Sun Shaojie)
Misc fixes and updates by Boqun Feng, Peter Zijlstra, Fangrui Song,
Naveen Kumar Chaudhary and Thomas Huth"
* tag 'locking-core-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits)
rust: sync: Introduce SpinLockIrq::lock_with() and friends
rust: sync: Add SpinLockIrq
rust: sync: Use super::* in spinlock.rs
rust: helper: Add spin_{un,}lock_irq_{enable,disable}() helpers
rust: Introduce interrupt module
s390/preempt: Enable HAS_SEPARATE_PREEMPT_RESCHED_BITS
arm64: sched/preempt: Enable HAS_SEPARATE_PREEMPT_RESCHED_BITS
preempt: Introduce HAS_SEPARATE_PREEMPT_RESCHED_BITS
sched: Avoid signed comparison of preempt_count() in __cant_migrate()
sched: Remove the unused preempt_offset parameter of __cant_sleep()
locking: Switch to _irq_{disable,enable}() variants in cleanup guards
irq: Add KUnit test for refcounted interrupt enable/disable
irq,spin_lock: Add counted interrupt disabling/enabling
openrisc: Include <linux/cpumask.h> in smp.h
preempt: Introduce __preempt_count_{sub,add}_return()
preempt: Introduce HARDIRQ_DISABLE_BITS
preempt: Track NMI nesting to separate per-CPU counter
futex: Tell kmemleak we're not leaking __futex_queues
x86/paravirt: Trace contended_release on unlock
tracing/lock: Use TRACE_EVENT_FN() for contended_release
...
89 lines
2.7 KiB
Rust
89 lines
2.7 KiB
Rust
// 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.
|
|
#[inline]
|
|
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.
|
|
#[inline]
|
|
pub fn unlock(self) {}
|
|
}
|
|
|
|
impl Default for Guard {
|
|
#[inline]
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Drop for Guard {
|
|
#[inline]
|
|
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.
|
|
#[inline]
|
|
pub fn read_lock() -> Guard {
|
|
Guard::new()
|
|
}
|
|
|
|
/// Wait until all in-flight `call_rcu()` callbacks complete.
|
|
///
|
|
/// Note that this primitive does not necessarily wait for an RCU grace period
|
|
/// to complete. For example, if there are no RCU callbacks queued anywhere
|
|
/// in the system, then [`rcu_barrier()`] is within its rights to return
|
|
/// immediately, without waiting for anything, much less an RCU grace period.
|
|
/// In fact, [`rcu_barrier()`] will normally not result in any RCU grace periods
|
|
/// beyond those that were already destined to be executed.
|
|
///
|
|
/// In kernels built with `CONFIG_RCU_LAZY=y`, this function also hurries all
|
|
/// pending lazy RCU callbacks.
|
|
///
|
|
/// Note that this is one of the RCU primitives which must not be called in
|
|
/// atomic context.
|
|
#[inline]
|
|
pub fn rcu_barrier() {
|
|
// SAFETY: `rcu_barrier()` is always safe to be called. It just might wait for a grace period.
|
|
unsafe { bindings::rcu_barrier() };
|
|
}
|
|
|
|
/// Wait for one RCU grace period.
|
|
///
|
|
/// Waits for all RCU read-side critical sections (such as those established by
|
|
/// a [`Guard`]) at the moment of the function call to finish.
|
|
///
|
|
/// Does not prevent new read-side critical sections from starting, which may
|
|
/// begin and run while this call is blocking.
|
|
///
|
|
/// Note that this is one of the RCU primitives which must not be called in
|
|
/// atomic context.
|
|
#[inline]
|
|
pub fn synchronize_rcu() {
|
|
// SAFETY: `synchronize_rcu()` is always safe to be called from process context.
|
|
unsafe { bindings::synchronize_rcu() };
|
|
}
|