* [PATCH locking 01/11] locking/rtmutex: Use struct keyword in kernel-doc comment
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] locking/rtmutex: Use the 'struct' " tip-bot2 for Randy Dunlap
2025-03-07 23:26 ` [PATCH locking 02/11] locking/semaphore: Use wake_q to wake up processes outside lock critical section Boqun Feng
` (10 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Randy Dunlap, Ingo Molnar,
Boqun Feng
From: Randy Dunlap <rdunlap@infradead.org>
Add the "struct" keyword to prevent a kernel-doc warning:
rtmutex_common.h:67: warning: cannot understand function prototype: 'struct rt_wake_q_head '
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Acked-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250111063040.910763-1-rdunlap@infradead.org
---
kernel/locking/rtmutex_common.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h
index c38a2d2d4a7e..78dd3d8c6554 100644
--- a/kernel/locking/rtmutex_common.h
+++ b/kernel/locking/rtmutex_common.h
@@ -59,8 +59,8 @@ struct rt_mutex_waiter {
};
/**
- * rt_wake_q_head - Wrapper around regular wake_q_head to support
- * "sleeping" spinlocks on RT
+ * struct rt_wake_q_head - Wrapper around regular wake_q_head to support
+ * "sleeping" spinlocks on RT
* @head: The regular wake_q_head for sleeping lock variants
* @rtlock_task: Task pointer for RT lock (spin/rwlock) wakeups
*/
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] locking/rtmutex: Use the 'struct' keyword in kernel-doc comment
2025-03-07 23:26 ` [PATCH locking 01/11] locking/rtmutex: Use struct keyword in kernel-doc comment Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Randy Dunlap
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Randy Dunlap @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Randy Dunlap, Boqun Feng, Ingo Molnar, Waiman Long, x86,
linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: b3c5ec8b79bf6bc49cc4850d0949d712830283d7
Gitweb: https://git.kernel.org/tip/b3c5ec8b79bf6bc49cc4850d0949d712830283d7
Author: Randy Dunlap <rdunlap@infradead.org>
AuthorDate: Fri, 07 Mar 2025 15:26:51 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:52:01 +01:00
locking/rtmutex: Use the 'struct' keyword in kernel-doc comment
Add the "struct" keyword to prevent a kernel-doc warning:
rtmutex_common.h:67: warning: cannot understand function prototype: 'struct rt_wake_q_head '
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Waiman Long <longman@redhat.com>
Link: https://lore.kernel.org/r/20250307232717.1759087-2-boqun.feng@gmail.com
---
kernel/locking/rtmutex_common.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h
index c38a2d2..78dd3d8 100644
--- a/kernel/locking/rtmutex_common.h
+++ b/kernel/locking/rtmutex_common.h
@@ -59,8 +59,8 @@ struct rt_mutex_waiter {
};
/**
- * rt_wake_q_head - Wrapper around regular wake_q_head to support
- * "sleeping" spinlocks on RT
+ * struct rt_wake_q_head - Wrapper around regular wake_q_head to support
+ * "sleeping" spinlocks on RT
* @head: The regular wake_q_head for sleeping lock variants
* @rtlock_task: Task pointer for RT lock (spin/rwlock) wakeups
*/
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 02/11] locking/semaphore: Use wake_q to wake up processes outside lock critical section
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
2025-03-07 23:26 ` [PATCH locking 01/11] locking/rtmutex: Use struct keyword in kernel-doc comment Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Waiman Long
2025-03-07 23:26 ` [PATCH locking 03/11] locking/lock_events: Add locking events for rtmutex slow paths Boqun Feng
` (9 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Boqun Feng, Ingo Molnar,
Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
open list:Real-time Linux (PREEMPT_RT):Keyword:PREEMPT_RT
From: Waiman Long <longman@redhat.com>
A circular lock dependency splat has been seen involving down_trylock().
[ 4011.795602] ======================================================
[ 4011.795603] WARNING: possible circular locking dependency detected
[ 4011.795607] 6.12.0-41.el10.s390x+debug
[ 4011.795612] ------------------------------------------------------
[ 4011.795613] dd/32479 is trying to acquire lock:
[ 4011.795617] 0015a20accd0d4f8 ((console_sem).lock){-.-.}-{2:2}, at: down_trylock+0x26/0x90
[ 4011.795636]
[ 4011.795636] but task is already holding lock:
[ 4011.795637] 000000017e461698 (&zone->lock){-.-.}-{2:2}, at: rmqueue_bulk+0xac/0x8f0
the existing dependency chain (in reverse order) is:
-> #4 (&zone->lock){-.-.}-{2:2}:
-> #3 (hrtimer_bases.lock){-.-.}-{2:2}:
-> #2 (&rq->__lock){-.-.}-{2:2}:
-> #1 (&p->pi_lock){-.-.}-{2:2}:
-> #0 ((console_sem).lock){-.-.}-{2:2}:
The console_sem -> pi_lock dependency is due to calling try_to_wake_up()
while holding the console.sem raw_spinlock. This dependency can be broken
by using wake_q to do the wakeup instead of calling try_to_wake_up()
under the console_sem lock. This will also make the semaphore's
raw_spinlock become a terminal lock without taking any further locks
underneath it.
The hrtimer_bases.lock is a raw_spinlock while zone->lock is a
spinlock. The hrtimer_bases.lock -> zone->lock dependency happens via
the debug_objects_fill_pool() helper function in the debugobjects code.
[ 4011.795646] -> #4 (&zone->lock){-.-.}-{2:2}:
[ 4011.795650] __lock_acquire+0xe86/0x1cc0
[ 4011.795655] lock_acquire.part.0+0x258/0x630
[ 4011.795657] lock_acquire+0xb8/0xe0
[ 4011.795659] _raw_spin_lock_irqsave+0xb4/0x120
[ 4011.795663] rmqueue_bulk+0xac/0x8f0
[ 4011.795665] __rmqueue_pcplist+0x580/0x830
[ 4011.795667] rmqueue_pcplist+0xfc/0x470
[ 4011.795669] rmqueue.isra.0+0xdec/0x11b0
[ 4011.795671] get_page_from_freelist+0x2ee/0xeb0
[ 4011.795673] __alloc_pages_noprof+0x2c2/0x520
[ 4011.795676] alloc_pages_mpol_noprof+0x1fc/0x4d0
[ 4011.795681] alloc_pages_noprof+0x8c/0xe0
[ 4011.795684] allocate_slab+0x320/0x460
[ 4011.795686] ___slab_alloc+0xa58/0x12b0
[ 4011.795688] __slab_alloc.isra.0+0x42/0x60
[ 4011.795690] kmem_cache_alloc_noprof+0x304/0x350
[ 4011.795692] fill_pool+0xf6/0x450
[ 4011.795697] debug_object_activate+0xfe/0x360
[ 4011.795700] enqueue_hrtimer+0x34/0x190
[ 4011.795703] __run_hrtimer+0x3c8/0x4c0
[ 4011.795705] __hrtimer_run_queues+0x1b2/0x260
[ 4011.795707] hrtimer_interrupt+0x316/0x760
[ 4011.795709] do_IRQ+0x9a/0xe0
[ 4011.795712] do_irq_async+0xf6/0x160
Normally raw_spinlock to spinlock dependency is not legit
and will be warned if PROVE_RAW_LOCK_NESTING is enabled,
but debug_objects_fill_pool() is an exception as it explicitly
allows this dependency for non-PREEMPT_RT kernel without causing
PROVE_RAW_LOCK_NESTING lockdep splat. As a result, this dependency is
legit and not a bug.
Anyway, semaphore is the only locking primitive left that is still
using try_to_wake_up() to do wakeup inside critical section, all the
other locking primitives had been migrated to use wake_q to do wakeup
outside of the critical section. It is also possible that there are
other circular locking dependencies involving printk/console_sem or
other existing/new semaphores lurking somewhere which may show up in
the future. Let just do the migration now to wake_q to avoid headache
like this.
Reported-by:syzbot+ed801a886dfdbfe7136d@syzkaller.appspotmail.com
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250127013127.3913153-1-longman@redhat.com
---
kernel/locking/semaphore.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c
index 34bfae72f295..de9117c0e671 100644
--- a/kernel/locking/semaphore.c
+++ b/kernel/locking/semaphore.c
@@ -29,6 +29,7 @@
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
+#include <linux/sched/wake_q.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/ftrace.h>
@@ -38,7 +39,7 @@ static noinline void __down(struct semaphore *sem);
static noinline int __down_interruptible(struct semaphore *sem);
static noinline int __down_killable(struct semaphore *sem);
static noinline int __down_timeout(struct semaphore *sem, long timeout);
-static noinline void __up(struct semaphore *sem);
+static noinline void __up(struct semaphore *sem, struct wake_q_head *wake_q);
/**
* down - acquire the semaphore
@@ -183,13 +184,16 @@ EXPORT_SYMBOL(down_timeout);
void __sched up(struct semaphore *sem)
{
unsigned long flags;
+ DEFINE_WAKE_Q(wake_q);
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(list_empty(&sem->wait_list)))
sem->count++;
else
- __up(sem);
+ __up(sem, &wake_q);
raw_spin_unlock_irqrestore(&sem->lock, flags);
+ if (!wake_q_empty(&wake_q))
+ wake_up_q(&wake_q);
}
EXPORT_SYMBOL(up);
@@ -269,11 +273,12 @@ static noinline int __sched __down_timeout(struct semaphore *sem, long timeout)
return __down_common(sem, TASK_UNINTERRUPTIBLE, timeout);
}
-static noinline void __sched __up(struct semaphore *sem)
+static noinline void __sched __up(struct semaphore *sem,
+ struct wake_q_head *wake_q)
{
struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
struct semaphore_waiter, list);
list_del(&waiter->list);
waiter->up = true;
- wake_up_process(waiter->task);
+ wake_q_add(wake_q, waiter->task);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] locking/semaphore: Use wake_q to wake up processes outside lock critical section
2025-03-07 23:26 ` [PATCH locking 02/11] locking/semaphore: Use wake_q to wake up processes outside lock critical section Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Waiman Long
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Waiman Long @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: yzbot+ed801a886dfdbfe7136d, Waiman Long, Boqun Feng, Ingo Molnar,
Linus Torvalds, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 85b2b9c16d053364e2004883140538e73b333cdb
Gitweb: https://git.kernel.org/tip/85b2b9c16d053364e2004883140538e73b333cdb
Author: Waiman Long <longman@redhat.com>
AuthorDate: Fri, 07 Mar 2025 15:26:52 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:52:01 +01:00
locking/semaphore: Use wake_q to wake up processes outside lock critical section
A circular lock dependency splat has been seen involving down_trylock():
======================================================
WARNING: possible circular locking dependency detected
6.12.0-41.el10.s390x+debug
------------------------------------------------------
dd/32479 is trying to acquire lock:
0015a20accd0d4f8 ((console_sem).lock){-.-.}-{2:2}, at: down_trylock+0x26/0x90
but task is already holding lock:
000000017e461698 (&zone->lock){-.-.}-{2:2}, at: rmqueue_bulk+0xac/0x8f0
the existing dependency chain (in reverse order) is:
-> #4 (&zone->lock){-.-.}-{2:2}:
-> #3 (hrtimer_bases.lock){-.-.}-{2:2}:
-> #2 (&rq->__lock){-.-.}-{2:2}:
-> #1 (&p->pi_lock){-.-.}-{2:2}:
-> #0 ((console_sem).lock){-.-.}-{2:2}:
The console_sem -> pi_lock dependency is due to calling try_to_wake_up()
while holding the console_sem raw_spinlock. This dependency can be broken
by using wake_q to do the wakeup instead of calling try_to_wake_up()
under the console_sem lock. This will also make the semaphore's
raw_spinlock become a terminal lock without taking any further locks
underneath it.
The hrtimer_bases.lock is a raw_spinlock while zone->lock is a
spinlock. The hrtimer_bases.lock -> zone->lock dependency happens via
the debug_objects_fill_pool() helper function in the debugobjects code.
-> #4 (&zone->lock){-.-.}-{2:2}:
__lock_acquire+0xe86/0x1cc0
lock_acquire.part.0+0x258/0x630
lock_acquire+0xb8/0xe0
_raw_spin_lock_irqsave+0xb4/0x120
rmqueue_bulk+0xac/0x8f0
__rmqueue_pcplist+0x580/0x830
rmqueue_pcplist+0xfc/0x470
rmqueue.isra.0+0xdec/0x11b0
get_page_from_freelist+0x2ee/0xeb0
__alloc_pages_noprof+0x2c2/0x520
alloc_pages_mpol_noprof+0x1fc/0x4d0
alloc_pages_noprof+0x8c/0xe0
allocate_slab+0x320/0x460
___slab_alloc+0xa58/0x12b0
__slab_alloc.isra.0+0x42/0x60
kmem_cache_alloc_noprof+0x304/0x350
fill_pool+0xf6/0x450
debug_object_activate+0xfe/0x360
enqueue_hrtimer+0x34/0x190
__run_hrtimer+0x3c8/0x4c0
__hrtimer_run_queues+0x1b2/0x260
hrtimer_interrupt+0x316/0x760
do_IRQ+0x9a/0xe0
do_irq_async+0xf6/0x160
Normally a raw_spinlock to spinlock dependency is not legitimate
and will be warned if CONFIG_PROVE_RAW_LOCK_NESTING is enabled,
but debug_objects_fill_pool() is an exception as it explicitly
allows this dependency for non-PREEMPT_RT kernel without causing
PROVE_RAW_LOCK_NESTING lockdep splat. As a result, this dependency is
legitimate and not a bug.
Anyway, semaphore is the only locking primitive left that is still
using try_to_wake_up() to do wakeup inside critical section, all the
other locking primitives had been migrated to use wake_q to do wakeup
outside of the critical section. It is also possible that there are
other circular locking dependencies involving printk/console_sem or
other existing/new semaphores lurking somewhere which may show up in
the future. Let just do the migration now to wake_q to avoid headache
like this.
Reported-by: yzbot+ed801a886dfdbfe7136d@syzkaller.appspotmail.com
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20250307232717.1759087-3-boqun.feng@gmail.com
---
kernel/locking/semaphore.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c
index 34bfae7..de9117c 100644
--- a/kernel/locking/semaphore.c
+++ b/kernel/locking/semaphore.c
@@ -29,6 +29,7 @@
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
+#include <linux/sched/wake_q.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/ftrace.h>
@@ -38,7 +39,7 @@ static noinline void __down(struct semaphore *sem);
static noinline int __down_interruptible(struct semaphore *sem);
static noinline int __down_killable(struct semaphore *sem);
static noinline int __down_timeout(struct semaphore *sem, long timeout);
-static noinline void __up(struct semaphore *sem);
+static noinline void __up(struct semaphore *sem, struct wake_q_head *wake_q);
/**
* down - acquire the semaphore
@@ -183,13 +184,16 @@ EXPORT_SYMBOL(down_timeout);
void __sched up(struct semaphore *sem)
{
unsigned long flags;
+ DEFINE_WAKE_Q(wake_q);
raw_spin_lock_irqsave(&sem->lock, flags);
if (likely(list_empty(&sem->wait_list)))
sem->count++;
else
- __up(sem);
+ __up(sem, &wake_q);
raw_spin_unlock_irqrestore(&sem->lock, flags);
+ if (!wake_q_empty(&wake_q))
+ wake_up_q(&wake_q);
}
EXPORT_SYMBOL(up);
@@ -269,11 +273,12 @@ static noinline int __sched __down_timeout(struct semaphore *sem, long timeout)
return __down_common(sem, TASK_UNINTERRUPTIBLE, timeout);
}
-static noinline void __sched __up(struct semaphore *sem)
+static noinline void __sched __up(struct semaphore *sem,
+ struct wake_q_head *wake_q)
{
struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
struct semaphore_waiter, list);
list_del(&waiter->list);
waiter->up = true;
- wake_up_process(waiter->task);
+ wake_q_add(wake_q, waiter->task);
}
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 03/11] locking/lock_events: Add locking events for rtmutex slow paths
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
2025-03-07 23:26 ` [PATCH locking 01/11] locking/rtmutex: Use struct keyword in kernel-doc comment Boqun Feng
2025-03-07 23:26 ` [PATCH locking 02/11] locking/semaphore: Use wake_q to wake up processes outside lock critical section Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Waiman Long
2025-03-07 23:26 ` [PATCH locking 04/11] locking/lock_events: Add locking events for lockdep Boqun Feng
` (8 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Boqun Feng, Ingo Molnar
From: Waiman Long <longman@redhat.com>
Add locking events for rtlock_slowlock() and rt_mutex_slowlock() for
profiling the slow path behavior of rt_spin_lock() and rt_mutex_lock().
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250213200228.1993588-2-longman@redhat.com
---
kernel/locking/lock_events_list.h | 21 +++++++++++++++++++++
kernel/locking/rtmutex.c | 29 ++++++++++++++++++++++++-----
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/kernel/locking/lock_events_list.h b/kernel/locking/lock_events_list.h
index 97fb6f3f840a..80b11f194c9f 100644
--- a/kernel/locking/lock_events_list.h
+++ b/kernel/locking/lock_events_list.h
@@ -67,3 +67,24 @@ LOCK_EVENT(rwsem_rlock_handoff) /* # of read lock handoffs */
LOCK_EVENT(rwsem_wlock) /* # of write locks acquired */
LOCK_EVENT(rwsem_wlock_fail) /* # of failed write lock acquisitions */
LOCK_EVENT(rwsem_wlock_handoff) /* # of write lock handoffs */
+
+/*
+ * Locking events for rtlock_slowlock()
+ */
+LOCK_EVENT(rtlock_slowlock) /* # of rtlock_slowlock() calls */
+LOCK_EVENT(rtlock_slow_acq1) /* # of locks acquired after wait_lock */
+LOCK_EVENT(rtlock_slow_acq2) /* # of locks acquired in for loop */
+LOCK_EVENT(rtlock_slow_sleep) /* # of sleeps */
+LOCK_EVENT(rtlock_slow_wake) /* # of wakeup's */
+
+/*
+ * Locking events for rt_mutex_slowlock()
+ */
+LOCK_EVENT(rtmutex_slowlock) /* # of rt_mutex_slowlock() calls */
+LOCK_EVENT(rtmutex_slow_block) /* # of rt_mutex_slowlock_block() calls */
+LOCK_EVENT(rtmutex_slow_acq1) /* # of locks acquired after wait_lock */
+LOCK_EVENT(rtmutex_slow_acq2) /* # of locks acquired at the end */
+LOCK_EVENT(rtmutex_slow_acq3) /* # of locks acquired in *block() */
+LOCK_EVENT(rtmutex_slow_sleep) /* # of sleeps */
+LOCK_EVENT(rtmutex_slow_wake) /* # of wakeup's */
+LOCK_EVENT(rtmutex_deadlock) /* # of rt_mutex_handle_deadlock()'s */
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 4a8df1800cbb..c80902eacd79 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -27,6 +27,7 @@
#include <trace/events/lock.h>
#include "rtmutex_common.h"
+#include "lock_events.h"
#ifndef WW_RT
# define build_ww_mutex() (false)
@@ -1612,10 +1613,13 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
struct task_struct *owner;
int ret = 0;
+ lockevent_inc(rtmutex_slow_block);
for (;;) {
/* Try to acquire the lock: */
- if (try_to_take_rt_mutex(lock, current, waiter))
+ if (try_to_take_rt_mutex(lock, current, waiter)) {
+ lockevent_inc(rtmutex_slow_acq3);
break;
+ }
if (timeout && !timeout->task) {
ret = -ETIMEDOUT;
@@ -1638,8 +1642,10 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
owner = NULL;
raw_spin_unlock_irq_wake(&lock->wait_lock, wake_q);
- if (!owner || !rtmutex_spin_on_owner(lock, waiter, owner))
+ if (!owner || !rtmutex_spin_on_owner(lock, waiter, owner)) {
+ lockevent_inc(rtmutex_slow_sleep);
rt_mutex_schedule();
+ }
raw_spin_lock_irq(&lock->wait_lock);
set_current_state(state);
@@ -1694,6 +1700,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
int ret;
lockdep_assert_held(&lock->wait_lock);
+ lockevent_inc(rtmutex_slowlock);
/* Try to acquire the lock again: */
if (try_to_take_rt_mutex(lock, current, NULL)) {
@@ -1701,6 +1708,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
__ww_mutex_check_waiters(rtm, ww_ctx, wake_q);
ww_mutex_lock_acquired(ww, ww_ctx);
}
+ lockevent_inc(rtmutex_slow_acq1);
return 0;
}
@@ -1719,10 +1727,12 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
__ww_mutex_check_waiters(rtm, ww_ctx, wake_q);
ww_mutex_lock_acquired(ww, ww_ctx);
}
+ lockevent_inc(rtmutex_slow_acq2);
} else {
__set_current_state(TASK_RUNNING);
remove_waiter(lock, waiter);
rt_mutex_handle_deadlock(ret, chwalk, lock, waiter);
+ lockevent_inc(rtmutex_deadlock);
}
/*
@@ -1751,6 +1761,7 @@ static inline int __rt_mutex_slowlock_locked(struct rt_mutex_base *lock,
&waiter, wake_q);
debug_rt_mutex_free_waiter(&waiter);
+ lockevent_cond_inc(rtmutex_slow_wake, !wake_q_empty(wake_q));
return ret;
}
@@ -1823,9 +1834,12 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
struct task_struct *owner;
lockdep_assert_held(&lock->wait_lock);
+ lockevent_inc(rtlock_slowlock);
- if (try_to_take_rt_mutex(lock, current, NULL))
+ if (try_to_take_rt_mutex(lock, current, NULL)) {
+ lockevent_inc(rtlock_slow_acq1);
return;
+ }
rt_mutex_init_rtlock_waiter(&waiter);
@@ -1838,8 +1852,10 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
for (;;) {
/* Try to acquire the lock again */
- if (try_to_take_rt_mutex(lock, current, &waiter))
+ if (try_to_take_rt_mutex(lock, current, &waiter)) {
+ lockevent_inc(rtlock_slow_acq2);
break;
+ }
if (&waiter == rt_mutex_top_waiter(lock))
owner = rt_mutex_owner(lock);
@@ -1847,8 +1863,10 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
owner = NULL;
raw_spin_unlock_irq_wake(&lock->wait_lock, wake_q);
- if (!owner || !rtmutex_spin_on_owner(lock, &waiter, owner))
+ if (!owner || !rtmutex_spin_on_owner(lock, &waiter, owner)) {
+ lockevent_inc(rtlock_slow_sleep);
schedule_rtlock();
+ }
raw_spin_lock_irq(&lock->wait_lock);
set_current_state(TASK_RTLOCK_WAIT);
@@ -1865,6 +1883,7 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
debug_rt_mutex_free_waiter(&waiter);
trace_contention_end(lock, 0);
+ lockevent_cond_inc(rtlock_slow_wake, !wake_q_empty(wake_q));
}
static __always_inline void __sched rtlock_slowlock(struct rt_mutex_base *lock)
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] locking/lock_events: Add locking events for rtmutex slow paths
2025-03-07 23:26 ` [PATCH locking 03/11] locking/lock_events: Add locking events for rtmutex slow paths Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Waiman Long
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Waiman Long @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Waiman Long, Boqun Feng, Ingo Molnar, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: b76b44fb656100fcd8482d9102d35d1b6a5129e9
Gitweb: https://git.kernel.org/tip/b76b44fb656100fcd8482d9102d35d1b6a5129e9
Author: Waiman Long <longman@redhat.com>
AuthorDate: Fri, 07 Mar 2025 15:26:53 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:03 +01:00
locking/lock_events: Add locking events for rtmutex slow paths
Add locking events for rtlock_slowlock() and rt_mutex_slowlock() for
profiling the slow path behavior of rt_spin_lock() and rt_mutex_lock().
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20250307232717.1759087-4-boqun.feng@gmail.com
---
kernel/locking/lock_events_list.h | 21 +++++++++++++++++++++
kernel/locking/rtmutex.c | 29 ++++++++++++++++++++++++-----
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/kernel/locking/lock_events_list.h b/kernel/locking/lock_events_list.h
index 97fb6f3..80b11f1 100644
--- a/kernel/locking/lock_events_list.h
+++ b/kernel/locking/lock_events_list.h
@@ -67,3 +67,24 @@ LOCK_EVENT(rwsem_rlock_handoff) /* # of read lock handoffs */
LOCK_EVENT(rwsem_wlock) /* # of write locks acquired */
LOCK_EVENT(rwsem_wlock_fail) /* # of failed write lock acquisitions */
LOCK_EVENT(rwsem_wlock_handoff) /* # of write lock handoffs */
+
+/*
+ * Locking events for rtlock_slowlock()
+ */
+LOCK_EVENT(rtlock_slowlock) /* # of rtlock_slowlock() calls */
+LOCK_EVENT(rtlock_slow_acq1) /* # of locks acquired after wait_lock */
+LOCK_EVENT(rtlock_slow_acq2) /* # of locks acquired in for loop */
+LOCK_EVENT(rtlock_slow_sleep) /* # of sleeps */
+LOCK_EVENT(rtlock_slow_wake) /* # of wakeup's */
+
+/*
+ * Locking events for rt_mutex_slowlock()
+ */
+LOCK_EVENT(rtmutex_slowlock) /* # of rt_mutex_slowlock() calls */
+LOCK_EVENT(rtmutex_slow_block) /* # of rt_mutex_slowlock_block() calls */
+LOCK_EVENT(rtmutex_slow_acq1) /* # of locks acquired after wait_lock */
+LOCK_EVENT(rtmutex_slow_acq2) /* # of locks acquired at the end */
+LOCK_EVENT(rtmutex_slow_acq3) /* # of locks acquired in *block() */
+LOCK_EVENT(rtmutex_slow_sleep) /* # of sleeps */
+LOCK_EVENT(rtmutex_slow_wake) /* # of wakeup's */
+LOCK_EVENT(rtmutex_deadlock) /* # of rt_mutex_handle_deadlock()'s */
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 4a8df18..c80902e 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -27,6 +27,7 @@
#include <trace/events/lock.h>
#include "rtmutex_common.h"
+#include "lock_events.h"
#ifndef WW_RT
# define build_ww_mutex() (false)
@@ -1612,10 +1613,13 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
struct task_struct *owner;
int ret = 0;
+ lockevent_inc(rtmutex_slow_block);
for (;;) {
/* Try to acquire the lock: */
- if (try_to_take_rt_mutex(lock, current, waiter))
+ if (try_to_take_rt_mutex(lock, current, waiter)) {
+ lockevent_inc(rtmutex_slow_acq3);
break;
+ }
if (timeout && !timeout->task) {
ret = -ETIMEDOUT;
@@ -1638,8 +1642,10 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
owner = NULL;
raw_spin_unlock_irq_wake(&lock->wait_lock, wake_q);
- if (!owner || !rtmutex_spin_on_owner(lock, waiter, owner))
+ if (!owner || !rtmutex_spin_on_owner(lock, waiter, owner)) {
+ lockevent_inc(rtmutex_slow_sleep);
rt_mutex_schedule();
+ }
raw_spin_lock_irq(&lock->wait_lock);
set_current_state(state);
@@ -1694,6 +1700,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
int ret;
lockdep_assert_held(&lock->wait_lock);
+ lockevent_inc(rtmutex_slowlock);
/* Try to acquire the lock again: */
if (try_to_take_rt_mutex(lock, current, NULL)) {
@@ -1701,6 +1708,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
__ww_mutex_check_waiters(rtm, ww_ctx, wake_q);
ww_mutex_lock_acquired(ww, ww_ctx);
}
+ lockevent_inc(rtmutex_slow_acq1);
return 0;
}
@@ -1719,10 +1727,12 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
__ww_mutex_check_waiters(rtm, ww_ctx, wake_q);
ww_mutex_lock_acquired(ww, ww_ctx);
}
+ lockevent_inc(rtmutex_slow_acq2);
} else {
__set_current_state(TASK_RUNNING);
remove_waiter(lock, waiter);
rt_mutex_handle_deadlock(ret, chwalk, lock, waiter);
+ lockevent_inc(rtmutex_deadlock);
}
/*
@@ -1751,6 +1761,7 @@ static inline int __rt_mutex_slowlock_locked(struct rt_mutex_base *lock,
&waiter, wake_q);
debug_rt_mutex_free_waiter(&waiter);
+ lockevent_cond_inc(rtmutex_slow_wake, !wake_q_empty(wake_q));
return ret;
}
@@ -1823,9 +1834,12 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
struct task_struct *owner;
lockdep_assert_held(&lock->wait_lock);
+ lockevent_inc(rtlock_slowlock);
- if (try_to_take_rt_mutex(lock, current, NULL))
+ if (try_to_take_rt_mutex(lock, current, NULL)) {
+ lockevent_inc(rtlock_slow_acq1);
return;
+ }
rt_mutex_init_rtlock_waiter(&waiter);
@@ -1838,8 +1852,10 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
for (;;) {
/* Try to acquire the lock again */
- if (try_to_take_rt_mutex(lock, current, &waiter))
+ if (try_to_take_rt_mutex(lock, current, &waiter)) {
+ lockevent_inc(rtlock_slow_acq2);
break;
+ }
if (&waiter == rt_mutex_top_waiter(lock))
owner = rt_mutex_owner(lock);
@@ -1847,8 +1863,10 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
owner = NULL;
raw_spin_unlock_irq_wake(&lock->wait_lock, wake_q);
- if (!owner || !rtmutex_spin_on_owner(lock, &waiter, owner))
+ if (!owner || !rtmutex_spin_on_owner(lock, &waiter, owner)) {
+ lockevent_inc(rtlock_slow_sleep);
schedule_rtlock();
+ }
raw_spin_lock_irq(&lock->wait_lock);
set_current_state(TASK_RTLOCK_WAIT);
@@ -1865,6 +1883,7 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock,
debug_rt_mutex_free_waiter(&waiter);
trace_contention_end(lock, 0);
+ lockevent_cond_inc(rtlock_slow_wake, !wake_q_empty(wake_q));
}
static __always_inline void __sched rtlock_slowlock(struct rt_mutex_base *lock)
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 04/11] locking/lock_events: Add locking events for lockdep
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (2 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 03/11] locking/lock_events: Add locking events for rtmutex slow paths Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Waiman Long
2025-03-07 23:26 ` [PATCH locking 05/11] locking/lockdep: Disable KASAN instrumentation of lockdep.c Boqun Feng
` (7 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Boqun Feng, Ingo Molnar
From: Waiman Long <longman@redhat.com>
Add some lock events to the lockdep for profiling its behavior.
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250213200228.1993588-3-longman@redhat.com
---
kernel/locking/lock_events_list.h | 7 +++++++
kernel/locking/lockdep.c | 8 +++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/lock_events_list.h b/kernel/locking/lock_events_list.h
index 80b11f194c9f..9ef9850aeebe 100644
--- a/kernel/locking/lock_events_list.h
+++ b/kernel/locking/lock_events_list.h
@@ -88,3 +88,10 @@ LOCK_EVENT(rtmutex_slow_acq3) /* # of locks acquired in *block() */
LOCK_EVENT(rtmutex_slow_sleep) /* # of sleeps */
LOCK_EVENT(rtmutex_slow_wake) /* # of wakeup's */
LOCK_EVENT(rtmutex_deadlock) /* # of rt_mutex_handle_deadlock()'s */
+
+/*
+ * Locking events for lockdep
+ */
+LOCK_EVENT(lockdep_acquire)
+LOCK_EVENT(lockdep_lock)
+LOCK_EVENT(lockdep_nocheck)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 4470680f0226..8436f017c74d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -61,6 +61,7 @@
#include <asm/sections.h>
#include "lockdep_internals.h"
+#include "lock_events.h"
#include <trace/events/lock.h>
@@ -170,6 +171,7 @@ static struct task_struct *lockdep_selftest_task_struct;
static int graph_lock(void)
{
lockdep_lock();
+ lockevent_inc(lockdep_lock);
/*
* Make sure that if another CPU detected a bug while
* walking the graph we dont change it (while the other
@@ -5091,8 +5093,12 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
if (unlikely(lock->key == &__lockdep_no_track__))
return 0;
- if (!prove_locking || lock->key == &__lockdep_no_validate__)
+ lockevent_inc(lockdep_acquire);
+
+ if (!prove_locking || lock->key == &__lockdep_no_validate__) {
check = 0;
+ lockevent_inc(lockdep_nocheck);
+ }
if (subclass < NR_LOCKDEP_CACHING_CLASSES)
class = lock->class_cache[subclass];
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] locking/lock_events: Add locking events for lockdep
2025-03-07 23:26 ` [PATCH locking 04/11] locking/lock_events: Add locking events for lockdep Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Waiman Long
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Waiman Long @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Waiman Long, Boqun Feng, Ingo Molnar, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: a94d32446ab5e85c7ba97e48a8c9bd85be4fe889
Gitweb: https://git.kernel.org/tip/a94d32446ab5e85c7ba97e48a8c9bd85be4fe889
Author: Waiman Long <longman@redhat.com>
AuthorDate: Fri, 07 Mar 2025 15:26:54 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:03 +01:00
locking/lock_events: Add locking events for lockdep
Add some lock events to lockdep to profile its behavior.
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20250307232717.1759087-5-boqun.feng@gmail.com
---
kernel/locking/lock_events_list.h | 7 +++++++
kernel/locking/lockdep.c | 8 +++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/lock_events_list.h b/kernel/locking/lock_events_list.h
index 80b11f1..9ef9850 100644
--- a/kernel/locking/lock_events_list.h
+++ b/kernel/locking/lock_events_list.h
@@ -88,3 +88,10 @@ LOCK_EVENT(rtmutex_slow_acq3) /* # of locks acquired in *block() */
LOCK_EVENT(rtmutex_slow_sleep) /* # of sleeps */
LOCK_EVENT(rtmutex_slow_wake) /* # of wakeup's */
LOCK_EVENT(rtmutex_deadlock) /* # of rt_mutex_handle_deadlock()'s */
+
+/*
+ * Locking events for lockdep
+ */
+LOCK_EVENT(lockdep_acquire)
+LOCK_EVENT(lockdep_lock)
+LOCK_EVENT(lockdep_nocheck)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 4470680..8436f01 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -61,6 +61,7 @@
#include <asm/sections.h>
#include "lockdep_internals.h"
+#include "lock_events.h"
#include <trace/events/lock.h>
@@ -170,6 +171,7 @@ static struct task_struct *lockdep_selftest_task_struct;
static int graph_lock(void)
{
lockdep_lock();
+ lockevent_inc(lockdep_lock);
/*
* Make sure that if another CPU detected a bug while
* walking the graph we dont change it (while the other
@@ -5091,8 +5093,12 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
if (unlikely(lock->key == &__lockdep_no_track__))
return 0;
- if (!prove_locking || lock->key == &__lockdep_no_validate__)
+ lockevent_inc(lockdep_acquire);
+
+ if (!prove_locking || lock->key == &__lockdep_no_validate__) {
check = 0;
+ lockevent_inc(lockdep_nocheck);
+ }
if (subclass < NR_LOCKDEP_CACHING_CLASSES)
class = lock->class_cache[subclass];
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 05/11] locking/lockdep: Disable KASAN instrumentation of lockdep.c
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (3 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 04/11] locking/lock_events: Add locking events for lockdep Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Waiman Long
2025-03-07 23:26 ` [PATCH locking 06/11] locking/lockdep: Add kasan_check_byte() check in lock_acquire() Boqun Feng
` (6 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Marco Elver,
Andrey Konovalov, Boqun Feng, Ingo Molnar,
Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
open list:Real-time Linux (PREEMPT_RT):Keyword:PREEMPT_RT
From: Waiman Long <longman@redhat.com>
Both KASAN and LOCKDEP are commonly enabled in building a debug kernel.
Each of them can significantly slow down the speed of a debug kernel.
Enabling KASAN instrumentation of the LOCKDEP code will further slow
thing down.
Since LOCKDEP is a high overhead debugging tool, it will never get
enabled in a production kernel. The LOCKDEP code is also pretty mature
and is unlikely to get major changes. There is also a possibility of
recursion similar to KCSAN.
To evaluate the performance impact of disabling KASAN instrumentation
of lockdep.c, the time to do a parallel build of the Linux defconfig
kernel was used as the benchmark. Two x86-64 systems (Skylake & Zen 2)
and an arm64 system were used as test beds. Two sets of non-RT and RT
kernels with similar configurations except mainly CONFIG_PREEMPT_RT
were used for evaulation.
For the Skylake system:
Kernel Run time Sys time
------ -------- --------
Non-debug kernel (baseline) 0m47.642s 4m19.811s
[CONFIG_KASAN_INLINE=y]
Debug kernel 2m11.108s (x2.8) 38m20.467s (x8.9)
Debug kernel (patched) 1m49.602s (x2.3) 31m28.501s (x7.3)
Debug kernel
(patched + mitigations=off) 1m30.988s (x1.9) 26m41.993s (x6.2)
RT kernel (baseline) 0m54.871s 7m15.340s
[CONFIG_KASAN_INLINE=n]
RT debug kernel 6m07.151s (x6.7) 135m47.428s (x18.7)
RT debug kernel (patched) 3m42.434s (x4.1) 74m51.636s (x10.3)
RT debug kernel
(patched + mitigations=off) 2m40.383s (x2.9) 57m54.369s (x8.0)
[CONFIG_KASAN_INLINE=y]
RT debug kernel 3m22.155s (x3.7) 77m53.018s (x10.7)
RT debug kernel (patched) 2m36.700s (x2.9) 54m31.195s (x7.5)
RT debug kernel
(patched + mitigations=off) 2m06.110s (x2.3) 45m49.493s (x6.3)
For the Zen 2 system:
Kernel Run time Sys time
------ -------- --------
Non-debug kernel (baseline) 1m42.806s 39m48.714s
[CONFIG_KASAN_INLINE=y]
Debug kernel 4m04.524s (x2.4) 125m35.904s (x3.2)
Debug kernel (patched) 3m56.241s (x2.3) 127m22.378s (x3.2)
Debug kernel
(patched + mitigations=off) 2m38.157s (x1.5) 92m35.680s (x2.3)
RT kernel (baseline) 1m51.500s 14m56.322s
[CONFIG_KASAN_INLINE=n]
RT debug kernel 16m04.962s (x8.7) 244m36.463s (x16.4)
RT debug kernel (patched) 9m09.073s (x4.9) 129m28.439s (x8.7)
RT debug kernel
(patched + mitigations=off) 3m31.662s (x1.9) 51m01.391s (x3.4)
For the arm64 system:
Kernel Run time Sys time
------ -------- --------
Non-debug kernel (baseline) 1m56.844s 8m47.150s
Debug kernel 3m54.774s (x2.0) 92m30.098s (x10.5)
Debug kernel (patched) 3m32.429s (x1.8) 77m40.779s (x8.8)
RT kernel (baseline) 4m01.641s 18m16.777s
[CONFIG_KASAN_INLINE=n]
RT debug kernel 19m32.977s (x4.9) 304m23.965s (x16.7)
RT debug kernel (patched) 16m28.354s (x4.1) 234m18.149s (x12.8)
Turning the mitigations off doesn't seems to have any noticeable impact
on the performance of the arm64 system. So the mitigation=off entries
aren't included.
For the x86 CPUs, cpu mitigations has a much bigger
impact on performance, especially the RT debug kernel with
CONFIG_KASAN_INLINE=n. The SRSO mitigation in Zen 2 has an especially
big impact on the debug kernel. It is also the majority of the slowdown
with mitigations on. It is because the patched ret instruction slows
down function returns. A lot of helper functions that are normally
compiled out or inlined may become real function calls in the debug
kernel.
With CONFIG_KASAN_INLINE=n, the KASAN instrumentation inserts a
lot of __asan_loadX*() and __kasan_check_read() function calls to memory
access portion of the code. The lockdep's __lock_acquire() function,
for instance, has 66 __asan_loadX*() and 6 __kasan_check_read() calls
added with KASAN instrumentation. Of course, the actual numbers may vary
depending on the compiler used and the exact version of the lockdep code.
With the Skylake test system, the parallel kernel build times reduction
of the RT debug kernel with this patch are:
CONFIG_KASAN_INLINE=n: -37%
CONFIG_KASAN_INLINE=y: -22%
The time reduction is less with CONFIG_KASAN_INLINE=y, but it is still
significant.
Setting CONFIG_KASAN_INLINE=y can result in a significant performance
improvement. The major drawback is a significant increase in the size
of kernel text. In the case of vmlinux, its text size increases from
45997948 to 67606807. That is a 47% size increase (about 21 Mbytes). The
size increase of other kernel modules should be similar.
With the newly added rtmutex and lockdep lock events, the relevant
event counts for the test runs with the Skylake system were:
Event type Debug kernel RT debug kernel
---------- ------------ ---------------
lockdep_acquire 1,968,663,277 5,425,313,953
rtlock_slowlock - 401,701,156
rtmutex_slowlock - 139,672
The __lock_acquire() calls in the RT debug kernel are x2.8 times of the
non-RT debug kernel with the same workload. Since the __lock_acquire()
function is a big hitter in term of performance slowdown, this makes
the RT debug kernel much slower than the non-RT one. The average lock
nesting depth is likely to be higher in the RT debug kernel too leading
to longer execution time in the __lock_acquire() function.
As the small advantage of enabling KASAN instrumentation to catch
potential memory access error in the lockdep debugging tool is probably
not worth the drawback of further slowing down a debug kernel, disable
KASAN instrumentation in the lockdep code to allow the debug kernels
to regain some performance back, especially for the RT debug kernels.
Signed-off-by: Waiman Long <longman@redhat.com>
Reviewed-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250213200228.1993588-4-longman@redhat.com
---
kernel/locking/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile
index 0db4093d17b8..a114949eeed5 100644
--- a/kernel/locking/Makefile
+++ b/kernel/locking/Makefile
@@ -5,7 +5,8 @@ KCOV_INSTRUMENT := n
obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o
-# Avoid recursion lockdep -> sanitizer -> ... -> lockdep.
+# Avoid recursion lockdep -> sanitizer -> ... -> lockdep & improve performance.
+KASAN_SANITIZE_lockdep.o := n
KCSAN_SANITIZE_lockdep.o := n
ifdef CONFIG_FUNCTION_TRACER
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] locking/lockdep: Disable KASAN instrumentation of lockdep.c
2025-03-07 23:26 ` [PATCH locking 05/11] locking/lockdep: Disable KASAN instrumentation of lockdep.c Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Waiman Long
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Waiman Long @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Waiman Long, Boqun Feng, Ingo Molnar, Marco Elver,
Andrey Konovalov, Linus Torvalds, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: ee57ab5a32129f599ee1d358548dbebcb5e45953
Gitweb: https://git.kernel.org/tip/ee57ab5a32129f599ee1d358548dbebcb5e45953
Author: Waiman Long <longman@redhat.com>
AuthorDate: Fri, 07 Mar 2025 15:26:55 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:03 +01:00
locking/lockdep: Disable KASAN instrumentation of lockdep.c
Both KASAN and LOCKDEP are commonly enabled in building a debug kernel.
Each of them can significantly slow down the speed of a debug kernel.
Enabling KASAN instrumentation of the LOCKDEP code will further slow
things down.
Since LOCKDEP is a high overhead debugging tool, it will never get
enabled in a production kernel. The LOCKDEP code is also pretty mature
and is unlikely to get major changes. There is also a possibility of
recursion similar to KCSAN.
To evaluate the performance impact of disabling KASAN instrumentation
of lockdep.c, the time to do a parallel build of the Linux defconfig
kernel was used as the benchmark. Two x86-64 systems (Skylake & Zen 2)
and an arm64 system were used as test beds. Two sets of non-RT and RT
kernels with similar configurations except mainly CONFIG_PREEMPT_RT
were used for evaluation.
For the Skylake system:
Kernel Run time Sys time
------ -------- --------
Non-debug kernel (baseline) 0m47.642s 4m19.811s
[CONFIG_KASAN_INLINE=y]
Debug kernel 2m11.108s (x2.8) 38m20.467s (x8.9)
Debug kernel (patched) 1m49.602s (x2.3) 31m28.501s (x7.3)
Debug kernel
(patched + mitigations=off) 1m30.988s (x1.9) 26m41.993s (x6.2)
RT kernel (baseline) 0m54.871s 7m15.340s
[CONFIG_KASAN_INLINE=n]
RT debug kernel 6m07.151s (x6.7) 135m47.428s (x18.7)
RT debug kernel (patched) 3m42.434s (x4.1) 74m51.636s (x10.3)
RT debug kernel
(patched + mitigations=off) 2m40.383s (x2.9) 57m54.369s (x8.0)
[CONFIG_KASAN_INLINE=y]
RT debug kernel 3m22.155s (x3.7) 77m53.018s (x10.7)
RT debug kernel (patched) 2m36.700s (x2.9) 54m31.195s (x7.5)
RT debug kernel
(patched + mitigations=off) 2m06.110s (x2.3) 45m49.493s (x6.3)
For the Zen 2 system:
Kernel Run time Sys time
------ -------- --------
Non-debug kernel (baseline) 1m42.806s 39m48.714s
[CONFIG_KASAN_INLINE=y]
Debug kernel 4m04.524s (x2.4) 125m35.904s (x3.2)
Debug kernel (patched) 3m56.241s (x2.3) 127m22.378s (x3.2)
Debug kernel
(patched + mitigations=off) 2m38.157s (x1.5) 92m35.680s (x2.3)
RT kernel (baseline) 1m51.500s 14m56.322s
[CONFIG_KASAN_INLINE=n]
RT debug kernel 16m04.962s (x8.7) 244m36.463s (x16.4)
RT debug kernel (patched) 9m09.073s (x4.9) 129m28.439s (x8.7)
RT debug kernel
(patched + mitigations=off) 3m31.662s (x1.9) 51m01.391s (x3.4)
For the arm64 system:
Kernel Run time Sys time
------ -------- --------
Non-debug kernel (baseline) 1m56.844s 8m47.150s
Debug kernel 3m54.774s (x2.0) 92m30.098s (x10.5)
Debug kernel (patched) 3m32.429s (x1.8) 77m40.779s (x8.8)
RT kernel (baseline) 4m01.641s 18m16.777s
[CONFIG_KASAN_INLINE=n]
RT debug kernel 19m32.977s (x4.9) 304m23.965s (x16.7)
RT debug kernel (patched) 16m28.354s (x4.1) 234m18.149s (x12.8)
Turning the mitigations off doesn't seems to have any noticeable impact
on the performance of the arm64 system. So the mitigation=off entries
aren't included.
For the x86 CPUs, CPU mitigations has a much bigger
impact on performance, especially the RT debug kernel with
CONFIG_KASAN_INLINE=n. The SRSO mitigation in Zen 2 has an especially
big impact on the debug kernel. It is also the majority of the slowdown
with mitigations on. It is because the patched RET instruction slows
down function returns. A lot of helper functions that are normally
compiled out or inlined may become real function calls in the debug
kernel.
With !CONFIG_KASAN_INLINE, the KASAN instrumentation inserts a
lot of __asan_loadX*() and __kasan_check_read() function calls to memory
access portion of the code. The lockdep's __lock_acquire() function,
for instance, has 66 __asan_loadX*() and 6 __kasan_check_read() calls
added with KASAN instrumentation. Of course, the actual numbers may vary
depending on the compiler used and the exact version of the lockdep code.
With the Skylake test system, the parallel kernel build times reduction
of the RT debug kernel with this patch are:
CONFIG_KASAN_INLINE=n: -37%
CONFIG_KASAN_INLINE=y: -22%
The time reduction is less with CONFIG_KASAN_INLINE=y, but it is still
significant.
Setting CONFIG_KASAN_INLINE=y can result in a significant performance
improvement. The major drawback is a significant increase in the size
of kernel text. In the case of vmlinux, its text size increases from
45997948 to 67606807. That is a 47% size increase (about 21 Mbytes). The
size increase of other kernel modules should be similar.
With the newly added rtmutex and lockdep lock events, the relevant
event counts for the test runs with the Skylake system were:
Event type Debug kernel RT debug kernel
---------- ------------ ---------------
lockdep_acquire 1,968,663,277 5,425,313,953
rtlock_slowlock - 401,701,156
rtmutex_slowlock - 139,672
The __lock_acquire() calls in the RT debug kernel are x2.8 times of the
non-RT debug kernel with the same workload. Since the __lock_acquire()
function is a big hitter in term of performance slowdown, this makes
the RT debug kernel much slower than the non-RT one. The average lock
nesting depth is likely to be higher in the RT debug kernel too leading
to longer execution time in the __lock_acquire() function.
As the small advantage of enabling KASAN instrumentation to catch
potential memory access error in the lockdep debugging tool is probably
not worth the drawback of further slowing down a debug kernel, disable
KASAN instrumentation in the lockdep code to allow the debug kernels
to regain some performance back, especially for the RT debug kernels.
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20250307232717.1759087-6-boqun.feng@gmail.com
---
kernel/locking/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile
index 0db4093..a114949 100644
--- a/kernel/locking/Makefile
+++ b/kernel/locking/Makefile
@@ -5,7 +5,8 @@ KCOV_INSTRUMENT := n
obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o
-# Avoid recursion lockdep -> sanitizer -> ... -> lockdep.
+# Avoid recursion lockdep -> sanitizer -> ... -> lockdep & improve performance.
+KASAN_SANITIZE_lockdep.o := n
KCSAN_SANITIZE_lockdep.o := n
ifdef CONFIG_FUNCTION_TRACER
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 06/11] locking/lockdep: Add kasan_check_byte() check in lock_acquire()
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (4 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 05/11] locking/lockdep: Disable KASAN instrumentation of lockdep.c Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Waiman Long
2025-03-07 23:26 ` [PATCH locking 07/11] rust: sync: Add accessor for the lock behind a given guard Boqun Feng
` (5 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Marco Elver,
Andrey Konovalov, Boqun Feng, Ingo Molnar
From: Waiman Long <longman@redhat.com>
KASAN instrumentation of lockdep has been disabled as we don't need
KASAN to check the validity of lockdep internal data structures and
incur unnecessary performance overhead. However, the lockdep_map pointer
passed in externally may not be valid (e.g. use-after-free) and we run
the risk of using garbage data resulting in false lockdep reports.
Add kasan_check_byte() call in lock_acquire() for non kernel core data
object to catch invalid lockdep_map and print out a KASAN report before
any lockdep splat, if any.
Suggested-by: Marco Elver <elver@google.com>
Signed-off-by: Waiman Long <longman@redhat.com>
Reviewed-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250214195242.2480920-1-longman@redhat.com
---
kernel/locking/lockdep.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 8436f017c74d..b15757e63626 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -57,6 +57,7 @@
#include <linux/lockdep.h>
#include <linux/context_tracking.h>
#include <linux/console.h>
+#include <linux/kasan.h>
#include <asm/sections.h>
@@ -5830,6 +5831,14 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
if (!debug_locks)
return;
+ /*
+ * As KASAN instrumentation is disabled and lock_acquire() is usually
+ * the first lockdep call when a task tries to acquire a lock, add
+ * kasan_check_byte() here to check for use-after-free and other
+ * memory errors.
+ */
+ kasan_check_byte(lock);
+
if (unlikely(!lockdep_enabled())) {
/* XXX allow trylock from NMI ?!? */
if (lockdep_nmi() && !trylock) {
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] locking/lockdep: Add kasan_check_byte() check in lock_acquire()
2025-03-07 23:26 ` [PATCH locking 06/11] locking/lockdep: Add kasan_check_byte() check in lock_acquire() Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Waiman Long
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Waiman Long @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Marco Elver, Waiman Long, Boqun Feng, Ingo Molnar,
Andrey Konovalov, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: de4b59d652646cf00cf632174348ca2266099edc
Gitweb: https://git.kernel.org/tip/de4b59d652646cf00cf632174348ca2266099edc
Author: Waiman Long <longman@redhat.com>
AuthorDate: Fri, 07 Mar 2025 15:26:56 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:04 +01:00
locking/lockdep: Add kasan_check_byte() check in lock_acquire()
KASAN instrumentation of lockdep has been disabled, as we don't need
KASAN to check the validity of lockdep internal data structures and
incur unnecessary performance overhead. However, the lockdep_map pointer
passed in externally may not be valid (e.g. use-after-free) and we run
the risk of using garbage data resulting in false lockdep reports.
Add kasan_check_byte() call in lock_acquire() for non kernel core data
object to catch invalid lockdep_map and print out a KASAN report before
any lockdep splat, if any.
Suggested-by: Marco Elver <elver@google.com>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Link: https://lore.kernel.org/r/20250214195242.2480920-1-longman@redhat.com
Link: https://lore.kernel.org/r/20250307232717.1759087-7-boqun.feng@gmail.com
---
kernel/locking/lockdep.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 8436f01..b15757e 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -57,6 +57,7 @@
#include <linux/lockdep.h>
#include <linux/context_tracking.h>
#include <linux/console.h>
+#include <linux/kasan.h>
#include <asm/sections.h>
@@ -5830,6 +5831,14 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
if (!debug_locks)
return;
+ /*
+ * As KASAN instrumentation is disabled and lock_acquire() is usually
+ * the first lockdep call when a task tries to acquire a lock, add
+ * kasan_check_byte() here to check for use-after-free and other
+ * memory errors.
+ */
+ kasan_check_byte(lock);
+
if (unlikely(!lockdep_enabled())) {
/* XXX allow trylock from NMI ?!? */
if (lockdep_nmi() && !trylock) {
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 07/11] rust: sync: Add accessor for the lock behind a given guard
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (5 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 06/11] locking/lockdep: Add kasan_check_byte() check in lock_acquire() Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Alice Ryhl
2025-03-07 23:26 ` [PATCH locking 08/11] rust: sync: lock: Add an example for Guard::lock_ref() Boqun Feng
` (4 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Alice Ryhl, Fiona Behrens,
Boqun Feng, Ingo Molnar, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, open list:RUST
From: Alice Ryhl <aliceryhl@google.com>
In order to assert a particular `Guard` is associated with a particular
`Lock`, add an accessor to obtain a reference to the underlying `Lock`
of a `Guard`.
Binder needs this assertion to ensure unsafe list operations are done
with the correct lock held.
[Boqun: Capitalize the title and reword the commit log]
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250205-guard-get-lock-v2-1-ba32a8c1d5b7@google.com
---
rust/kernel/sync/lock.rs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index eb80048e0110..8e7e6d5f61e4 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -199,7 +199,12 @@ 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.
+ 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) };
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] rust: sync: Add accessor for the lock behind a given guard
2025-03-07 23:26 ` [PATCH locking 07/11] rust: sync: Add accessor for the lock behind a given guard Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Alice Ryhl
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Alice Ryhl @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Alice Ryhl, Boqun Feng, Ingo Molnar, Fiona Behrens, x86,
linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 8f65291dae0e75941cf76e427088e5612c4d692e
Gitweb: https://git.kernel.org/tip/8f65291dae0e75941cf76e427088e5612c4d692e
Author: Alice Ryhl <aliceryhl@google.com>
AuthorDate: Fri, 07 Mar 2025 15:26:57 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:04 +01:00
rust: sync: Add accessor for the lock behind a given guard
In order to assert a particular `Guard` is associated with a particular
`Lock`, add an accessor to obtain a reference to the underlying `Lock`
of a `Guard`.
Binder needs this assertion to ensure unsafe list operations are done
with the correct lock held.
[Boqun: Capitalize the title and reword the commit log]
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Link: https://lore.kernel.org/r/20250205-guard-get-lock-v2-1-ba32a8c1d5b7@google.com
Link: https://lore.kernel.org/r/20250307232717.1759087-8-boqun.feng@gmail.com
---
rust/kernel/sync/lock.rs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index eb80048..8e7e6d5 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -199,7 +199,12 @@ 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.
+ 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) };
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 08/11] rust: sync: lock: Add an example for Guard::lock_ref()
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (6 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 07/11] rust: sync: Add accessor for the lock behind a given guard Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] rust: sync: lock: Add an example for Guard:: Lock_ref() tip-bot2 for Boqun Feng
2025-03-07 23:26 ` [PATCH locking 09/11] rust: sync: condvar: Add wait_interruptible_freezable() Boqun Feng
` (3 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Boqun Feng, Benno Lossin,
Alice Ryhl, Ingo Molnar, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Trevor Gross,
open list:RUST
To provide examples on usage of `Guard::lock_ref()` along with the unit
test, an "assert a lock is held by a guard" example is added.
[boqun: Apply feedback from Benno]
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250223072114.3715-1-boqun.feng@gmail.com
---
rust/kernel/sync/lock.rs | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index 8e7e6d5f61e4..f53e87d04cd2 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -201,6 +201,30 @@ unsafe impl<T: Sync + ?Sized, B: Backend> Sync for 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
}
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] rust: sync: lock: Add an example for Guard:: Lock_ref()
2025-03-07 23:26 ` [PATCH locking 08/11] rust: sync: lock: Add an example for Guard::lock_ref() Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Boqun Feng
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Boqun Feng @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Boqun Feng, Ingo Molnar, Benno Lossin, Alice Ryhl, x86,
linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: c2849afafd08a1c3ad881129de48ebe1642f7675
Gitweb: https://git.kernel.org/tip/c2849afafd08a1c3ad881129de48ebe1642f7675
Author: Boqun Feng <boqun.feng@gmail.com>
AuthorDate: Fri, 07 Mar 2025 15:26:58 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:04 +01:00
rust: sync: lock: Add an example for Guard:: Lock_ref()
To provide examples on usage of `Guard::lock_ref()` along with the unit
test, an "assert a lock is held by a guard" example is added.
(Also apply feedback from Benno.)
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250223072114.3715-1-boqun.feng@gmail.com
Link: https://lore.kernel.org/r/20250307232717.1759087-9-boqun.feng@gmail.com
---
rust/kernel/sync/lock.rs | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index 8e7e6d5..f53e87d 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -201,6 +201,30 @@ unsafe impl<T: Sync + ?Sized, B: Backend> Sync for 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
}
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 09/11] rust: sync: condvar: Add wait_interruptible_freezable()
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (7 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 08/11] rust: sync: lock: Add an example for Guard::lock_ref() Boqun Feng
@ 2025-03-07 23:26 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Alice Ryhl
2025-03-07 23:27 ` [PATCH locking 10/11] rust: lockdep: Remove support for dynamically allocated LockClassKeys Boqun Feng
` (2 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:26 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Alice Ryhl, Boqun Feng,
Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Mitchell Levy,
Danilo Krummrich, Christian Brauner, Martin Rodriguez Reboredo,
open list:RUST
From: Alice Ryhl <aliceryhl@google.com>
To support waiting for a `CondVar` as a freezable process, add a
wait_interruptible_freezable() function.
Binder needs this function in the appropriate places to freeze a process
where some of its threads are blocked on the Binder driver.
[Boqun: Capitalize the title, reword the commit log and rephrase the
function doc comment with the impersonal style to align with rest of the
file]
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250204-condvar-freeze-v2-1-804483096260@google.com
---
rust/kernel/sync/condvar.rs | 23 ++++++++++++++++++++++-
rust/kernel/task.rs | 2 ++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs
index 7df565038d7d..5c1e546a26c3 100644
--- a/rust/kernel/sync/condvar.rs
+++ b/rust/kernel/sync/condvar.rs
@@ -11,7 +11,9 @@
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,
};
@@ -159,6 +161,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
diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs
index 07bc22a7645c..ea43a3b8d9c5 100644
--- a/rust/kernel/task.rs
+++ b/rust/kernel/task.rs
@@ -23,6 +23,8 @@
pub const TASK_INTERRUPTIBLE: c_int = bindings::TASK_INTERRUPTIBLE as c_int;
/// Bitmask for tasks that are sleeping in an uninterruptible state.
pub const TASK_UNINTERRUPTIBLE: c_int = bindings::TASK_UNINTERRUPTIBLE as c_int;
+/// Bitmask for tasks that are sleeping in a freezable state.
+pub const TASK_FREEZABLE: c_int = bindings::TASK_FREEZABLE as c_int;
/// Convenience constant for waking up tasks regardless of whether they are in interruptible or
/// uninterruptible sleep.
pub const TASK_NORMAL: c_uint = bindings::TASK_NORMAL as c_uint;
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] rust: sync: condvar: Add wait_interruptible_freezable()
2025-03-07 23:26 ` [PATCH locking 09/11] rust: sync: condvar: Add wait_interruptible_freezable() Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Alice Ryhl
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Alice Ryhl @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Alice Ryhl, Boqun Feng, Ingo Molnar, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 70b9c8563c9c29102a785d4822f0d77d33fee808
Gitweb: https://git.kernel.org/tip/70b9c8563c9c29102a785d4822f0d77d33fee808
Author: Alice Ryhl <aliceryhl@google.com>
AuthorDate: Fri, 07 Mar 2025 15:26:59 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:04 +01:00
rust: sync: condvar: Add wait_interruptible_freezable()
To support waiting for a `CondVar` as a freezable process, add a
wait_interruptible_freezable() function.
Binder needs this function in the appropriate places to freeze a process
where some of its threads are blocked on the Binder driver.
[ Boqun: Cleaned up the changelog and documentation. ]
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20250307232717.1759087-10-boqun.feng@gmail.com
---
rust/kernel/sync/condvar.rs | 23 ++++++++++++++++++++++-
rust/kernel/task.rs | 2 ++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs
index 7df5650..5c1e546 100644
--- a/rust/kernel/sync/condvar.rs
+++ b/rust/kernel/sync/condvar.rs
@@ -11,7 +11,9 @@ use crate::{
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,
};
@@ -159,6 +161,25 @@ impl CondVar {
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
diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs
index 07bc22a..ea43a3b 100644
--- a/rust/kernel/task.rs
+++ b/rust/kernel/task.rs
@@ -23,6 +23,8 @@ pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX;
pub const TASK_INTERRUPTIBLE: c_int = bindings::TASK_INTERRUPTIBLE as c_int;
/// Bitmask for tasks that are sleeping in an uninterruptible state.
pub const TASK_UNINTERRUPTIBLE: c_int = bindings::TASK_UNINTERRUPTIBLE as c_int;
+/// Bitmask for tasks that are sleeping in a freezable state.
+pub const TASK_FREEZABLE: c_int = bindings::TASK_FREEZABLE as c_int;
/// Convenience constant for waking up tasks regardless of whether they are in interruptible or
/// uninterruptible sleep.
pub const TASK_NORMAL: c_uint = bindings::TASK_NORMAL as c_uint;
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 10/11] rust: lockdep: Remove support for dynamically allocated LockClassKeys
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (8 preceding siblings ...)
2025-03-07 23:26 ` [PATCH locking 09/11] rust: sync: condvar: Add wait_interruptible_freezable() Boqun Feng
@ 2025-03-07 23:27 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Mitchell Levy
2025-03-07 23:27 ` [PATCH locking 11/11] rust: lockdep: Use Pin for all LockClassKey usages Boqun Feng
2025-03-08 0:01 ` [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15 Ingo Molnar
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:27 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Mitchell Levy, Alice Ryhl,
stable, Benno Lossin, Boqun Feng, Miguel Ojeda, Alex Gaynor,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Lyude Paul, Wedson Almeida Filho, Martin Rodriguez Reboredo,
open list:RUST
From: Mitchell Levy <levymitchell0@gmail.com>
Currently, dynamically allocated LockCLassKeys can be used from the Rust
side without having them registered. This is a soundness issue, so
remove them.
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/rust-for-linux/20240815074519.2684107-3-nmi@metaspace.dk/
Cc: stable@vger.kernel.org
Fixes: 6ea5aa08857a ("rust: sync: introduce `LockClassKey`")
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250207-rust-lockdep-v4-1-7a50a7e88656@gmail.com
---
rust/kernel/sync.rs | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 3498fb344dc9..16eab9138b2b 100644
--- a/rust/kernel/sync.rs
+++ b/rust/kernel/sync.rs
@@ -30,28 +30,20 @@
unsafe impl Sync for LockClassKey {}
impl LockClassKey {
- /// Creates a new lock class key.
- pub const fn new() -> Self {
- Self(Opaque::uninit())
- }
-
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
self.0.get()
}
}
-impl Default for LockClassKey {
- fn default() -> Self {
- Self::new()
- }
-}
-
/// Defines a new static lock class and returns a pointer to it.
#[doc(hidden)]
#[macro_export]
macro_rules! static_lock_class {
() => {{
- static CLASS: $crate::sync::LockClassKey = $crate::sync::LockClassKey::new();
+ static CLASS: $crate::sync::LockClassKey =
+ // SAFETY: lockdep expects uninitialized memory when it's handed a statically allocated
+ // lock_class_key
+ unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
&CLASS
}};
}
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] rust: lockdep: Remove support for dynamically allocated LockClassKeys
2025-03-07 23:27 ` [PATCH locking 10/11] rust: lockdep: Remove support for dynamically allocated LockClassKeys Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Mitchell Levy
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Mitchell Levy @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Alice Ryhl, Mitchell Levy, Boqun Feng, Ingo Molnar, Benno Lossin,
stable, x86, linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 966944f3711665db13e214fef6d02982c49bb972
Gitweb: https://git.kernel.org/tip/966944f3711665db13e214fef6d02982c49bb972
Author: Mitchell Levy <levymitchell0@gmail.com>
AuthorDate: Fri, 07 Mar 2025 15:27:00 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:52:00 +01:00
rust: lockdep: Remove support for dynamically allocated LockClassKeys
Currently, dynamically allocated LockCLassKeys can be used from the Rust
side without having them registered. This is a soundness issue, so
remove them.
Fixes: 6ea5aa08857a ("rust: sync: introduce `LockClassKey`")
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20250307232717.1759087-11-boqun.feng@gmail.com
---
rust/kernel/sync.rs | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 3498fb3..16eab91 100644
--- a/rust/kernel/sync.rs
+++ b/rust/kernel/sync.rs
@@ -30,28 +30,20 @@ pub struct LockClassKey(Opaque<bindings::lock_class_key>);
unsafe impl Sync for LockClassKey {}
impl LockClassKey {
- /// Creates a new lock class key.
- pub const fn new() -> Self {
- Self(Opaque::uninit())
- }
-
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
self.0.get()
}
}
-impl Default for LockClassKey {
- fn default() -> Self {
- Self::new()
- }
-}
-
/// Defines a new static lock class and returns a pointer to it.
#[doc(hidden)]
#[macro_export]
macro_rules! static_lock_class {
() => {{
- static CLASS: $crate::sync::LockClassKey = $crate::sync::LockClassKey::new();
+ static CLASS: $crate::sync::LockClassKey =
+ // SAFETY: lockdep expects uninitialized memory when it's handed a statically allocated
+ // lock_class_key
+ unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
&CLASS
}};
}
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH locking 11/11] rust: lockdep: Use Pin for all LockClassKey usages
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (9 preceding siblings ...)
2025-03-07 23:27 ` [PATCH locking 10/11] rust: lockdep: Remove support for dynamically allocated LockClassKeys Boqun Feng
@ 2025-03-07 23:27 ` Boqun Feng
2025-03-08 0:08 ` [tip: locking/core] " tip-bot2 for Mitchell Levy
2025-03-08 0:01 ` [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15 Ingo Molnar
11 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-07 23:27 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra
Cc: Will Deacon, Waiman Long, linux-kernel, Mitchell Levy,
Benno Lossin, Boqun Feng, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Ingo Molnar, Danilo Krummrich, Wedson Almeida Filho,
Christian Brauner, Lyude Paul, Martin Rodriguez Reboredo,
Konstantin Andrikopoulos, Roland Xu, open list:RUST
From: Mitchell Levy <levymitchell0@gmail.com>
Reintroduce dynamically-allocated LockClassKeys such that they are
automatically (de)registered. Require that all usages of LockClassKeys
ensure that they are Pin'd.
Currently, only `'static` LockClassKeys are supported, so Pin is
redundant. However, it is intended that dynamically-allocated
LockClassKeys will eventually be supported, so using Pin from the outset
will make that change simpler.
Closes: https://github.com/Rust-for-Linux/linux/issues/1102
Suggested-by: Benno Lossin <benno.lossin@proton.me>
Suggested-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20250207-rust-lockdep-v4-2-7a50a7e88656@gmail.com
---
rust/helpers/helpers.c | 1 +
rust/helpers/sync.c | 13 ++++++++
rust/kernel/sync.rs | 57 +++++++++++++++++++++++++++++++--
rust/kernel/sync/condvar.rs | 5 ++-
rust/kernel/sync/lock.rs | 4 +--
rust/kernel/sync/lock/global.rs | 5 +--
rust/kernel/sync/poll.rs | 2 +-
rust/kernel/workqueue.rs | 2 +-
8 files changed, 77 insertions(+), 12 deletions(-)
create mode 100644 rust/helpers/sync.c
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 0640b7e115be..4c1a10a419cf 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -30,6 +30,7 @@
#include "signal.c"
#include "slab.c"
#include "spinlock.c"
+#include "sync.c"
#include "task.c"
#include "uaccess.c"
#include "vmalloc.c"
diff --git a/rust/helpers/sync.c b/rust/helpers/sync.c
new file mode 100644
index 000000000000..ff7e68b48810
--- /dev/null
+++ b/rust/helpers/sync.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/lockdep.h>
+
+void rust_helper_lockdep_register_key(struct lock_class_key *k)
+{
+ lockdep_register_key(k);
+}
+
+void rust_helper_lockdep_unregister_key(struct lock_class_key *k)
+{
+ lockdep_unregister_key(k);
+}
diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 16eab9138b2b..4104bc26471a 100644
--- a/rust/kernel/sync.rs
+++ b/rust/kernel/sync.rs
@@ -5,6 +5,8 @@
//! This module contains the kernel APIs related to synchronisation that have been ported or
//! wrapped for usage by Rust code in the kernel.
+use crate::pin_init;
+use crate::prelude::*;
use crate::types::Opaque;
mod arc;
@@ -23,15 +25,64 @@
/// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
#[repr(transparent)]
-pub struct LockClassKey(Opaque<bindings::lock_class_key>);
+#[pin_data(PinnedDrop)]
+pub struct LockClassKey {
+ #[pin]
+ inner: Opaque<bindings::lock_class_key>,
+}
// SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and
// provides its own synchronization.
unsafe impl Sync for LockClassKey {}
impl LockClassKey {
+ /// Initializes a dynamically allocated lock class key. In the common case of using a
+ /// statically allocated lock class key, the static_lock_class! macro should be used instead.
+ ///
+ /// # Example
+ /// ```
+ /// # use kernel::{c_str, stack_pin_init};
+ /// # use kernel::alloc::KBox;
+ /// # use kernel::types::ForeignOwnable;
+ /// # use kernel::sync::{LockClassKey, SpinLock};
+ ///
+ /// let key = KBox::pin_init(LockClassKey::new_dynamic(), GFP_KERNEL)?;
+ /// let key_ptr = key.into_foreign();
+ ///
+ /// {
+ /// stack_pin_init!(let num: SpinLock<u32> = SpinLock::new(
+ /// 0,
+ /// c_str!("my_spinlock"),
+ /// // SAFETY: `key_ptr` is returned by the above `into_foreign()`, whose
+ /// // `from_foreign()` has not yet been called.
+ /// unsafe { <Pin<KBox<LockClassKey>> as ForeignOwnable>::borrow(key_ptr) }
+ /// ));
+ /// }
+ ///
+ /// // SAFETY: We dropped `num`, the only use of the key, so the result of the previous
+ /// // `borrow` has also been dropped. Thus, it's safe to use from_foreign.
+ /// unsafe { drop(<Pin<KBox<LockClassKey>> as ForeignOwnable>::from_foreign(key_ptr)) };
+ ///
+ /// # Ok::<(), Error>(())
+ /// ```
+ pub fn new_dynamic() -> impl PinInit<Self> {
+ pin_init!(Self {
+ // SAFETY: lockdep_register_key expects an uninitialized block of memory
+ inner <- Opaque::ffi_init(|slot| unsafe { bindings::lockdep_register_key(slot) })
+ })
+ }
+
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
- self.0.get()
+ self.inner.get()
+ }
+}
+
+#[pinned_drop]
+impl PinnedDrop for LockClassKey {
+ fn drop(self: Pin<&mut Self>) {
+ // SAFETY: self.as_ptr was registered with lockdep and self is pinned, so the address
+ // hasn't changed. Thus, it's safe to pass to unregister.
+ unsafe { bindings::lockdep_unregister_key(self.as_ptr()) }
}
}
@@ -44,7 +95,7 @@ macro_rules! static_lock_class {
// SAFETY: lockdep expects uninitialized memory when it's handed a statically allocated
// lock_class_key
unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
- &CLASS
+ $crate::prelude::Pin::static_ref(&CLASS)
}};
}
diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs
index 5c1e546a26c3..fbf68ada582f 100644
--- a/rust/kernel/sync/condvar.rs
+++ b/rust/kernel/sync/condvar.rs
@@ -17,8 +17,7 @@
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.
@@ -103,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
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index f53e87d04cd2..360a10a9216d 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -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,
diff --git a/rust/kernel/sync/lock/global.rs b/rust/kernel/sync/lock/global.rs
index 480ee724e3cc..d65f94b5caf2 100644
--- a/rust/kernel/sync/lock/global.rs
+++ b/rust/kernel/sync/lock/global.rs
@@ -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!()
}
}
diff --git a/rust/kernel/sync/poll.rs b/rust/kernel/sync/poll.rs
index d5f17153b424..c4934f82d68b 100644
--- a/rust/kernel/sync/poll.rs
+++ b/rust/kernel/sync/poll.rs
@@ -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),
})
diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
index 0cd100d2aefb..6b6f3ad08951 100644
--- a/rust/kernel/workqueue.rs
+++ b/rust/kernel/workqueue.rs
@@ -369,7 +369,7 @@ unsafe impl<T: ?Sized, const ID: u64> Sync for Work<T, ID> {}
impl<T: ?Sized, const ID: u64> Work<T, ID> {
/// Creates a new instance of [`Work`].
#[inline]
- 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>
where
T: WorkItem<ID>,
{
--
2.47.1
^ permalink raw reply related [flat|nested] 31+ messages in thread* [tip: locking/core] rust: lockdep: Use Pin for all LockClassKey usages
2025-03-07 23:27 ` [PATCH locking 11/11] rust: lockdep: Use Pin for all LockClassKey usages Boqun Feng
@ 2025-03-08 0:08 ` tip-bot2 for Mitchell Levy
0 siblings, 0 replies; 31+ messages in thread
From: tip-bot2 for Mitchell Levy @ 2025-03-08 0:08 UTC (permalink / raw)
To: linux-tip-commits
Cc: Benno Lossin, Boqun Feng, Mitchell Levy, Ingo Molnar, x86,
linux-kernel
The following commit has been merged into the locking/core branch of tip:
Commit-ID: f73ca66f0d7f4371d172d6f5b1f9a00e367ba921
Gitweb: https://git.kernel.org/tip/f73ca66f0d7f4371d172d6f5b1f9a00e367ba921
Author: Mitchell Levy <levymitchell0@gmail.com>
AuthorDate: Fri, 07 Mar 2025 15:27:01 -08:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Sat, 08 Mar 2025 00:55:04 +01:00
rust: lockdep: Use Pin for all LockClassKey usages
Reintroduce dynamically-allocated LockClassKeys such that they are
automatically (de)registered. Require that all usages of LockClassKeys
ensure that they are Pin'd.
Currently, only `'static` LockClassKeys are supported, so Pin is
redundant. However, it is intended that dynamically-allocated
LockClassKeys will eventually be supported, so using Pin from the outset
will make that change simpler.
Closes: https://github.com/Rust-for-Linux/linux/issues/1102
Suggested-by: Benno Lossin <benno.lossin@proton.me>
Suggested-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250307232717.1759087-12-boqun.feng@gmail.com
---
rust/helpers/helpers.c | 1 +-
rust/helpers/sync.c | 13 +++++++-
rust/kernel/sync.rs | 57 ++++++++++++++++++++++++++++++--
rust/kernel/sync/condvar.rs | 5 +--
rust/kernel/sync/lock.rs | 4 +-
rust/kernel/sync/lock/global.rs | 5 +--
rust/kernel/sync/poll.rs | 2 +-
rust/kernel/workqueue.rs | 2 +-
8 files changed, 77 insertions(+), 12 deletions(-)
create mode 100644 rust/helpers/sync.c
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 0640b7e..4c1a10a 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -30,6 +30,7 @@
#include "signal.c"
#include "slab.c"
#include "spinlock.c"
+#include "sync.c"
#include "task.c"
#include "uaccess.c"
#include "vmalloc.c"
diff --git a/rust/helpers/sync.c b/rust/helpers/sync.c
new file mode 100644
index 0000000..ff7e68b
--- /dev/null
+++ b/rust/helpers/sync.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/lockdep.h>
+
+void rust_helper_lockdep_register_key(struct lock_class_key *k)
+{
+ lockdep_register_key(k);
+}
+
+void rust_helper_lockdep_unregister_key(struct lock_class_key *k)
+{
+ lockdep_unregister_key(k);
+}
diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 16eab91..4104bc2 100644
--- a/rust/kernel/sync.rs
+++ b/rust/kernel/sync.rs
@@ -5,6 +5,8 @@
//! This module contains the kernel APIs related to synchronisation that have been ported or
//! wrapped for usage by Rust code in the kernel.
+use crate::pin_init;
+use crate::prelude::*;
use crate::types::Opaque;
mod arc;
@@ -23,15 +25,64 @@ pub use locked_by::LockedBy;
/// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
#[repr(transparent)]
-pub struct LockClassKey(Opaque<bindings::lock_class_key>);
+#[pin_data(PinnedDrop)]
+pub struct LockClassKey {
+ #[pin]
+ inner: Opaque<bindings::lock_class_key>,
+}
// SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and
// provides its own synchronization.
unsafe impl Sync for LockClassKey {}
impl LockClassKey {
+ /// Initializes a dynamically allocated lock class key. In the common case of using a
+ /// statically allocated lock class key, the static_lock_class! macro should be used instead.
+ ///
+ /// # Example
+ /// ```
+ /// # use kernel::{c_str, stack_pin_init};
+ /// # use kernel::alloc::KBox;
+ /// # use kernel::types::ForeignOwnable;
+ /// # use kernel::sync::{LockClassKey, SpinLock};
+ ///
+ /// let key = KBox::pin_init(LockClassKey::new_dynamic(), GFP_KERNEL)?;
+ /// let key_ptr = key.into_foreign();
+ ///
+ /// {
+ /// stack_pin_init!(let num: SpinLock<u32> = SpinLock::new(
+ /// 0,
+ /// c_str!("my_spinlock"),
+ /// // SAFETY: `key_ptr` is returned by the above `into_foreign()`, whose
+ /// // `from_foreign()` has not yet been called.
+ /// unsafe { <Pin<KBox<LockClassKey>> as ForeignOwnable>::borrow(key_ptr) }
+ /// ));
+ /// }
+ ///
+ /// // SAFETY: We dropped `num`, the only use of the key, so the result of the previous
+ /// // `borrow` has also been dropped. Thus, it's safe to use from_foreign.
+ /// unsafe { drop(<Pin<KBox<LockClassKey>> as ForeignOwnable>::from_foreign(key_ptr)) };
+ ///
+ /// # Ok::<(), Error>(())
+ /// ```
+ pub fn new_dynamic() -> impl PinInit<Self> {
+ pin_init!(Self {
+ // SAFETY: lockdep_register_key expects an uninitialized block of memory
+ inner <- Opaque::ffi_init(|slot| unsafe { bindings::lockdep_register_key(slot) })
+ })
+ }
+
pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
- self.0.get()
+ self.inner.get()
+ }
+}
+
+#[pinned_drop]
+impl PinnedDrop for LockClassKey {
+ fn drop(self: Pin<&mut Self>) {
+ // SAFETY: self.as_ptr was registered with lockdep and self is pinned, so the address
+ // hasn't changed. Thus, it's safe to pass to unregister.
+ unsafe { bindings::lockdep_unregister_key(self.as_ptr()) }
}
}
@@ -44,7 +95,7 @@ macro_rules! static_lock_class {
// SAFETY: lockdep expects uninitialized memory when it's handed a statically allocated
// lock_class_key
unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
- &CLASS
+ $crate::prelude::Pin::static_ref(&CLASS)
}};
}
diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs
index 5c1e546..fbf68ad 100644
--- a/rust/kernel/sync/condvar.rs
+++ b/rust/kernel/sync/condvar.rs
@@ -17,8 +17,7 @@ use crate::{
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.
@@ -103,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
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index f53e87d..360a10a 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -12,7 +12,7 @@ use crate::{
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,
diff --git a/rust/kernel/sync/lock/global.rs b/rust/kernel/sync/lock/global.rs
index 480ee72..d65f94b 100644
--- a/rust/kernel/sync/lock/global.rs
+++ b/rust/kernel/sync/lock/global.rs
@@ -13,6 +13,7 @@ use crate::{
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 @@ macro_rules! global_lock {
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!()
}
}
diff --git a/rust/kernel/sync/poll.rs b/rust/kernel/sync/poll.rs
index d5f1715..c4934f8 100644
--- a/rust/kernel/sync/poll.rs
+++ b/rust/kernel/sync/poll.rs
@@ -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),
})
diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
index 0cd100d..6b6f3ad 100644
--- a/rust/kernel/workqueue.rs
+++ b/rust/kernel/workqueue.rs
@@ -369,7 +369,7 @@ unsafe impl<T: ?Sized, const ID: u64> Sync for Work<T, ID> {}
impl<T: ?Sized, const ID: u64> Work<T, ID> {
/// Creates a new instance of [`Work`].
#[inline]
- 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>
where
T: WorkItem<ID>,
{
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15
2025-03-07 23:26 ` [PATCH locking 00/11] " Boqun Feng
` (10 preceding siblings ...)
2025-03-07 23:27 ` [PATCH locking 11/11] rust: lockdep: Use Pin for all LockClassKey usages Boqun Feng
@ 2025-03-08 0:01 ` Ingo Molnar
2025-03-08 0:04 ` Boqun Feng
11 siblings, 1 reply; 31+ messages in thread
From: Ingo Molnar @ 2025-03-08 0:01 UTC (permalink / raw)
To: Boqun Feng
Cc: Peter Zijlstra, Will Deacon, Waiman Long, linux-kernel,
Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
open list:RUST:Keyword:b(?i:rust)b
* Boqun Feng <boqun.feng@gmail.com> wrote:
> Hi Ingo & Peter,
>
> As discussed, I'm resending the pull request for lockdep and Rust
> locking for v6.15 in the format of email patches. I dropped one patch
> and will postpone it for v6.16 because of a bug [1], and I think the fix
> [2] needs more reviews.
>
> [1]: https://lore.kernel.org/lkml/20250306122413.GBZ8mT7Z61Tmgnh5Y9@fat_crate.local/
> [2]: https://lore.kernel.org/lkml/Z8t8imzJVhWyDvhC@boqun-archlinux/
>
> Regards,
> Boqun
>
> Alice Ryhl (2):
> rust: sync: Add accessor for the lock behind a given guard
> rust: sync: condvar: Add wait_interruptible_freezable()
>
> Boqun Feng (1):
> rust: sync: lock: Add an example for Guard::lock_ref()
>
> Mitchell Levy (2):
> rust: lockdep: Remove support for dynamically allocated LockClassKeys
> rust: lockdep: Use Pin for all LockClassKey usages
>
> Randy Dunlap (1):
> locking/rtmutex: Use struct keyword in kernel-doc comment
>
> Waiman Long (5):
> locking/semaphore: Use wake_q to wake up processes outside lock
> critical section
> locking/lock_events: Add locking events for rtmutex slow paths
> locking/lock_events: Add locking events for lockdep
> locking/lockdep: Disable KASAN instrumentation of lockdep.c
> locking/lockdep: Add kasan_check_byte() check in lock_acquire()
Thanks Boqun!
I've applied these 3 patches to the tip:locking/urgent tree:
locking/semaphore: Use wake_q to wake up processes outside lock critical section
locking/rtmutex: Use the 'struct' keyword in kernel-doc comment
rust: lockdep: Remove support for dynamically allocated LockClassKeys
As a general rule, if a patch is marked Cc: stable, it must also be
applied to current upstream.
I have applied the others to tip:locking/core:
locking/lock_events: Add locking events for rtmutex slow pathsa94d32446ab5 locking/lock_events: Add locking events for lockdep
locking/lockdep: Disable KASAN instrumentation of lockdep.c
locking/lockdep: Add kasan_check_byte() check in lock_acquire()
rust: sync: Add accessor for the lock behind a given guard
rust: sync: lock: Add an example for Guard:: Lock_ref()
rust: sync: condvar: Add wait_interruptible_freezable()
rust: lockdep: Use Pin for all LockClassKey usages
I cleaned up changelogs where necessary - for example we generally
don't include printk timestamps in changelogs, unless it's relevant,
plus there were a number of typos and grammar mistakes left in some of
the changelogs.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15
2025-03-08 0:01 ` [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15 Ingo Molnar
@ 2025-03-08 0:04 ` Boqun Feng
2025-03-08 0:11 ` Ingo Molnar
0 siblings, 1 reply; 31+ messages in thread
From: Boqun Feng @ 2025-03-08 0:04 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, Will Deacon, Waiman Long, linux-kernel,
Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
open list:RUST:Keyword:b(?i:rust)b
On Sat, Mar 08, 2025 at 01:01:45AM +0100, Ingo Molnar wrote:
>
> * Boqun Feng <boqun.feng@gmail.com> wrote:
>
> > Hi Ingo & Peter,
> >
> > As discussed, I'm resending the pull request for lockdep and Rust
> > locking for v6.15 in the format of email patches. I dropped one patch
> > and will postpone it for v6.16 because of a bug [1], and I think the fix
> > [2] needs more reviews.
> >
> > [1]: https://lore.kernel.org/lkml/20250306122413.GBZ8mT7Z61Tmgnh5Y9@fat_crate.local/
> > [2]: https://lore.kernel.org/lkml/Z8t8imzJVhWyDvhC@boqun-archlinux/
> >
> > Regards,
> > Boqun
> >
> > Alice Ryhl (2):
> > rust: sync: Add accessor for the lock behind a given guard
> > rust: sync: condvar: Add wait_interruptible_freezable()
> >
> > Boqun Feng (1):
> > rust: sync: lock: Add an example for Guard::lock_ref()
> >
> > Mitchell Levy (2):
> > rust: lockdep: Remove support for dynamically allocated LockClassKeys
> > rust: lockdep: Use Pin for all LockClassKey usages
> >
> > Randy Dunlap (1):
> > locking/rtmutex: Use struct keyword in kernel-doc comment
> >
> > Waiman Long (5):
> > locking/semaphore: Use wake_q to wake up processes outside lock
> > critical section
> > locking/lock_events: Add locking events for rtmutex slow paths
> > locking/lock_events: Add locking events for lockdep
> > locking/lockdep: Disable KASAN instrumentation of lockdep.c
> > locking/lockdep: Add kasan_check_byte() check in lock_acquire()
>
> Thanks Boqun!
>
Thanks.
> I've applied these 3 patches to the tip:locking/urgent tree:
>
> locking/semaphore: Use wake_q to wake up processes outside lock critical section
> locking/rtmutex: Use the 'struct' keyword in kernel-doc comment
> rust: lockdep: Remove support for dynamically allocated LockClassKeys
>
> As a general rule, if a patch is marked Cc: stable, it must also be
> applied to current upstream.
>
Do you prefer a separate pull request for the future? I can send one for
urgent and one for locking/core.
> I have applied the others to tip:locking/core:
>
> locking/lock_events: Add locking events for rtmutex slow pathsa94d32446ab5 locking/lock_events: Add locking events for lockdep
> locking/lockdep: Disable KASAN instrumentation of lockdep.c
> locking/lockdep: Add kasan_check_byte() check in lock_acquire()
> rust: sync: Add accessor for the lock behind a given guard
> rust: sync: lock: Add an example for Guard:: Lock_ref()
> rust: sync: condvar: Add wait_interruptible_freezable()
> rust: lockdep: Use Pin for all LockClassKey usages
>
> I cleaned up changelogs where necessary - for example we generally
> don't include printk timestamps in changelogs, unless it's relevant,
Got it, I will avoid them in the future.
> plus there were a number of typos and grammar mistakes left in some of
> the changelogs.
>
Will take a look at your updates and keep working on improve them,
thanks!
Regards,
Boqun
> Thanks,
>
> Ingo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15
2025-03-08 0:04 ` Boqun Feng
@ 2025-03-08 0:11 ` Ingo Molnar
2025-03-08 0:11 ` Boqun Feng
0 siblings, 1 reply; 31+ messages in thread
From: Ingo Molnar @ 2025-03-08 0:11 UTC (permalink / raw)
To: Boqun Feng
Cc: Peter Zijlstra, Will Deacon, Waiman Long, linux-kernel,
Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
open list:RUST:Keyword:b(?i:rust)b
* Boqun Feng <boqun.feng@gmail.com> wrote:
> On Sat, Mar 08, 2025 at 01:01:45AM +0100, Ingo Molnar wrote:
> >
> > * Boqun Feng <boqun.feng@gmail.com> wrote:
> >
> > > Hi Ingo & Peter,
> > >
> > > As discussed, I'm resending the pull request for lockdep and Rust
> > > locking for v6.15 in the format of email patches. I dropped one patch
> > > and will postpone it for v6.16 because of a bug [1], and I think the fix
> > > [2] needs more reviews.
> > >
> > > [1]: https://lore.kernel.org/lkml/20250306122413.GBZ8mT7Z61Tmgnh5Y9@fat_crate.local/
> > > [2]: https://lore.kernel.org/lkml/Z8t8imzJVhWyDvhC@boqun-archlinux/
> > >
> > > Regards,
> > > Boqun
> > >
> > > Alice Ryhl (2):
> > > rust: sync: Add accessor for the lock behind a given guard
> > > rust: sync: condvar: Add wait_interruptible_freezable()
> > >
> > > Boqun Feng (1):
> > > rust: sync: lock: Add an example for Guard::lock_ref()
> > >
> > > Mitchell Levy (2):
> > > rust: lockdep: Remove support for dynamically allocated LockClassKeys
> > > rust: lockdep: Use Pin for all LockClassKey usages
> > >
> > > Randy Dunlap (1):
> > > locking/rtmutex: Use struct keyword in kernel-doc comment
> > >
> > > Waiman Long (5):
> > > locking/semaphore: Use wake_q to wake up processes outside lock
> > > critical section
> > > locking/lock_events: Add locking events for rtmutex slow paths
> > > locking/lock_events: Add locking events for lockdep
> > > locking/lockdep: Disable KASAN instrumentation of lockdep.c
> > > locking/lockdep: Add kasan_check_byte() check in lock_acquire()
> >
> > Thanks Boqun!
> >
>
> Thanks.
>
> > I've applied these 3 patches to the tip:locking/urgent tree:
> >
> > locking/semaphore: Use wake_q to wake up processes outside lock critical section
> > locking/rtmutex: Use the 'struct' keyword in kernel-doc comment
> > rust: lockdep: Remove support for dynamically allocated LockClassKeys
> >
> > As a general rule, if a patch is marked Cc: stable, it must also be
> > applied to current upstream.
> >
>
> Do you prefer a separate pull request for the future? I can send one for
> urgent and one for locking/core.
One tree is fine - maybe indicate which ones are urgent material and
keep them at the head of the tree?
Thanks,
Ingo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH locking 00/11] LOCKDEP and Rust locking changes for v6.15
2025-03-08 0:11 ` Ingo Molnar
@ 2025-03-08 0:11 ` Boqun Feng
0 siblings, 0 replies; 31+ messages in thread
From: Boqun Feng @ 2025-03-08 0:11 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, Will Deacon, Waiman Long, linux-kernel,
Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
open list:RUST:Keyword:b(?i:rust)b
On Sat, Mar 08, 2025 at 01:11:36AM +0100, Ingo Molnar wrote:
[...]
> > > I've applied these 3 patches to the tip:locking/urgent tree:
> > >
> > > locking/semaphore: Use wake_q to wake up processes outside lock critical section
> > > locking/rtmutex: Use the 'struct' keyword in kernel-doc comment
> > > rust: lockdep: Remove support for dynamically allocated LockClassKeys
> > >
> > > As a general rule, if a patch is marked Cc: stable, it must also be
> > > applied to current upstream.
> > >
> >
> > Do you prefer a separate pull request for the future? I can send one for
> > urgent and one for locking/core.
>
> One tree is fine - maybe indicate which ones are urgent material and
> keep them at the head of the tree?
>
Sounds good to me, will do.
Regards,
Boqun
> Thanks,
>
> Ingo
^ permalink raw reply [flat|nested] 31+ messages in thread