mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04:00
Merge tag 'locking-core-2025-03-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking updates from Ingo Molnar:
"Locking primitives:
- Micro-optimize percpu_{,try_}cmpxchg{64,128}_op() and
{,try_}cmpxchg{64,128} on x86 (Uros Bizjak)
- mutexes: extend debug checks in mutex_lock() (Yunhui Cui)
- Misc cleanups (Uros Bizjak)
Lockdep:
- Fix might_fault() lockdep check of current->mm->mmap_lock (Peter
Zijlstra)
- Don't disable interrupts on RT in disable_irq_nosync_lockdep.*()
(Sebastian Andrzej Siewior)
- Disable KASAN instrumentation of lockdep.c (Waiman Long)
- Add kasan_check_byte() check in lock_acquire() (Waiman Long)
- Misc cleanups (Sebastian Andrzej Siewior)
Rust runtime integration:
- Use Pin for all LockClassKey usages (Mitchell Levy)
- sync: Add accessor for the lock behind a given guard (Alice Ryhl)
- sync: condvar: Add wait_interruptible_freezable() (Alice Ryhl)
- sync: lock: Add an example for Guard:: Lock_ref() (Boqun Feng)
Split-lock detection feature (x86):
- Fix warning mode with disabled mitigation mode (Maksim Davydov)
Locking events:
- Add locking events for rtmutex slow paths (Waiman Long)
- Add locking events for lockdep (Waiman Long)"
* tag 'locking-core-2025-03-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
lockdep: Remove disable_irq_lockdep()
lockdep: Don't disable interrupts on RT in disable_irq_nosync_lockdep.*()
rust: lockdep: Use Pin for all LockClassKey usages
rust: sync: condvar: Add wait_interruptible_freezable()
rust: sync: lock: Add an example for Guard:: Lock_ref()
rust: sync: Add accessor for the lock behind a given guard
locking/lockdep: Add kasan_check_byte() check in lock_acquire()
locking/lockdep: Disable KASAN instrumentation of lockdep.c
locking/lock_events: Add locking events for lockdep
locking/lock_events: Add locking events for rtmutex slow paths
x86/split_lock: Fix the delayed detection logic
lockdep/mm: Fix might_fault() lockdep check of current->mm->mmap_lock
x86/locking: Remove semicolon from "lock" prefix
locking/mutex: Add MUTEX_WARN_ON() into fast path
x86/locking: Use asm_inline for {,try_}cmpxchg{64,128} emulations
x86/locking: Use ALT_OUTPUT_SP() for percpu_{,try_}cmpxchg{64,128}_op()
This commit is contained in:
@@ -11,12 +11,13 @@
|
||||
init::PinInit,
|
||||
pin_init,
|
||||
str::CStr,
|
||||
task::{MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE},
|
||||
task::{
|
||||
MAX_SCHEDULE_TIMEOUT, TASK_FREEZABLE, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE,
|
||||
},
|
||||
time::Jiffies,
|
||||
types::Opaque,
|
||||
};
|
||||
use core::marker::PhantomPinned;
|
||||
use core::ptr;
|
||||
use core::{marker::PhantomPinned, pin::Pin, ptr};
|
||||
use macros::pin_data;
|
||||
|
||||
/// Creates a [`CondVar`] initialiser with the given name and a newly-created lock class.
|
||||
@@ -101,7 +102,7 @@ unsafe impl Sync for CondVar {}
|
||||
|
||||
impl CondVar {
|
||||
/// Constructs a new condvar initialiser.
|
||||
pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self> {
|
||||
pub fn new(name: &'static CStr, key: Pin<&'static LockClassKey>) -> impl PinInit<Self> {
|
||||
pin_init!(Self {
|
||||
_pin: PhantomPinned,
|
||||
// SAFETY: `slot` is valid while the closure is called and both `name` and `key` have
|
||||
@@ -159,6 +160,25 @@ pub fn wait_interruptible<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T,
|
||||
crate::current!().signal_pending()
|
||||
}
|
||||
|
||||
/// Releases the lock and waits for a notification in interruptible and freezable mode.
|
||||
///
|
||||
/// The process is allowed to be frozen during this sleep. No lock should be held when calling
|
||||
/// this function, and there is a lockdep assertion for this. Freezing a task that holds a lock
|
||||
/// can trivially deadlock vs another task that needs that lock to complete before it too can
|
||||
/// hit freezable.
|
||||
#[must_use = "wait_interruptible_freezable returns if a signal is pending, so the caller must check the return value"]
|
||||
pub fn wait_interruptible_freezable<T: ?Sized, B: Backend>(
|
||||
&self,
|
||||
guard: &mut Guard<'_, T, B>,
|
||||
) -> bool {
|
||||
self.wait_internal(
|
||||
TASK_INTERRUPTIBLE | TASK_FREEZABLE,
|
||||
guard,
|
||||
MAX_SCHEDULE_TIMEOUT,
|
||||
);
|
||||
crate::current!().signal_pending()
|
||||
}
|
||||
|
||||
/// Releases the lock and waits for a notification in interruptible mode.
|
||||
///
|
||||
/// Atomically releases the given lock (whose ownership is proven by the guard) and puts the
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
str::CStr,
|
||||
types::{NotThreadSafe, Opaque, ScopeGuard},
|
||||
};
|
||||
use core::{cell::UnsafeCell, marker::PhantomPinned};
|
||||
use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin};
|
||||
use macros::pin_data;
|
||||
|
||||
pub mod mutex;
|
||||
@@ -129,7 +129,7 @@ unsafe impl<T: ?Sized + Send, B: Backend> Sync for Lock<T, B> {}
|
||||
|
||||
impl<T, B: Backend> Lock<T, B> {
|
||||
/// Constructs a new lock initialiser.
|
||||
pub fn new(t: T, name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self> {
|
||||
pub fn new(t: T, name: &'static CStr, key: Pin<&'static LockClassKey>) -> impl PinInit<Self> {
|
||||
pin_init!(Self {
|
||||
data: UnsafeCell::new(t),
|
||||
_pin: PhantomPinned,
|
||||
@@ -199,7 +199,36 @@ pub struct Guard<'a, T: ?Sized, B: Backend> {
|
||||
// SAFETY: `Guard` is sync when the data protected by the lock is also sync.
|
||||
unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {}
|
||||
|
||||
impl<T: ?Sized, B: Backend> Guard<'_, T, B> {
|
||||
impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> {
|
||||
/// Returns the lock that this guard originates from.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The following example shows how to use [`Guard::lock_ref()`] to assert the corresponding
|
||||
/// lock is held.
|
||||
///
|
||||
/// ```
|
||||
/// # use kernel::{new_spinlock, stack_pin_init, sync::lock::{Backend, Guard, Lock}};
|
||||
///
|
||||
/// fn assert_held<T, B: Backend>(guard: &Guard<'_, T, B>, lock: &Lock<T, B>) {
|
||||
/// // Address-equal means the same lock.
|
||||
/// assert!(core::ptr::eq(guard.lock_ref(), lock));
|
||||
/// }
|
||||
///
|
||||
/// // Creates a new lock on the stack.
|
||||
/// stack_pin_init!{
|
||||
/// let l = new_spinlock!(42)
|
||||
/// }
|
||||
///
|
||||
/// let g = l.lock();
|
||||
///
|
||||
/// // `g` originates from `l`.
|
||||
/// assert_held(&g, &l);
|
||||
/// ```
|
||||
pub fn lock_ref(&self) -> &'a Lock<T, B> {
|
||||
self.lock
|
||||
}
|
||||
|
||||
pub(crate) fn do_unlocked<U>(&mut self, cb: impl FnOnce() -> U) -> U {
|
||||
// SAFETY: The caller owns the lock, so it is safe to unlock it.
|
||||
unsafe { B::unlock(self.lock.state.get(), &self.state) };
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
use core::{
|
||||
cell::UnsafeCell,
|
||||
marker::{PhantomData, PhantomPinned},
|
||||
pin::Pin,
|
||||
};
|
||||
|
||||
/// Trait implemented for marker types for global locks.
|
||||
@@ -26,7 +27,7 @@ pub trait GlobalLockBackend {
|
||||
/// The backend used for this global lock.
|
||||
type Backend: Backend + 'static;
|
||||
/// The class for this global lock.
|
||||
fn get_lock_class() -> &'static LockClassKey;
|
||||
fn get_lock_class() -> Pin<&'static LockClassKey>;
|
||||
}
|
||||
|
||||
/// Type used for global locks.
|
||||
@@ -270,7 +271,7 @@ impl $crate::sync::lock::GlobalLockBackend for $name {
|
||||
type Item = $valuety;
|
||||
type Backend = $crate::global_lock_inner!(backend $kind);
|
||||
|
||||
fn get_lock_class() -> &'static $crate::sync::LockClassKey {
|
||||
fn get_lock_class() -> Pin<&'static $crate::sync::LockClassKey> {
|
||||
$crate::static_lock_class!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ pub struct PollCondVar {
|
||||
|
||||
impl PollCondVar {
|
||||
/// Constructs a new condvar initialiser.
|
||||
pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self> {
|
||||
pub fn new(name: &'static CStr, key: Pin<&'static LockClassKey>) -> impl PinInit<Self> {
|
||||
pin_init!(Self {
|
||||
inner <- CondVar::new(name, key),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user