mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Lock context annotation fixes
@ 2026-02-25 18:32 Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 1/4] locking: Fix rwlock and spinlock lock context annotations Bart Van Assche
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Bart Van Assche @ 2026-02-25 18:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, linux-kernel,
	Marco Elver, Christoph Hellwig, Steven Rostedt, Nick Desaulniers,
	Nathan Chancellor, Kees Cook, Jann Horn, Bart Van Assche

Hi Peter,

Some of the lock context annotations that have been introduced during the most
recent merge window were incomplete or incorrect. Hence this patch series with
fixes. Please consider this patch series for the current kernel development
cycle.

Thanks,

Bart.

Changes compared to v1:
 - Expanded Cc-list. Added the linux-kernel mailing list and more kernel developers
   to the Cc-list.
 - Added Maarten's Acked-by to patch 3/4.

Bart Van Assche (4):
  locking: Fix rwlock and spinlock lock context annotations
  signal: Fix the lock_task_sighand() annotation
  ww-mutex: Fix the ww_acquire_ctx function annotations
  Revert "lockdep: Annotate lockdep assertions for context analysis"

 include/linux/lockdep.h        | 12 ++++++------
 include/linux/rwlock.h         |  4 ++--
 include/linux/rwlock_api_smp.h |  6 ++++--
 include/linux/sched/signal.h   |  2 +-
 include/linux/spinlock.h       |  3 ++-
 include/linux/ww_mutex.h       |  4 ++--
 lib/test_context-analysis.c    |  6 +++---
 mm/kfence/report.c             |  1 +
 8 files changed, 21 insertions(+), 17 deletions(-)


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 1/4] locking: Fix rwlock and spinlock lock context annotations
  2026-02-25 18:32 [PATCH v2 0/4] Lock context annotation fixes Bart Van Assche
@ 2026-02-25 18:32 ` Bart Van Assche
  2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 2/4] signal: Fix the lock_task_sighand() annotation Bart Van Assche
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2026-02-25 18:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, linux-kernel,
	Marco Elver, Christoph Hellwig, Steven Rostedt, Nick Desaulniers,
	Nathan Chancellor, Kees Cook, Jann Horn, Bart Van Assche

Fix two incorrect rwlock_t lock context annotations. Add the raw_spinlock_t
lock context annotations that are missing.

Fixes: f16a802d402d ("locking/rwlock, spinlock: Support Clang's context analysis")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/rwlock.h         | 4 ++--
 include/linux/rwlock_api_smp.h | 6 ++++--
 include/linux/spinlock.h       | 3 ++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index 3390d21c95dd..21ceefc4a49f 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -30,10 +30,10 @@ do {								\
 
 #ifdef CONFIG_DEBUG_SPINLOCK
  extern void do_raw_read_lock(rwlock_t *lock) __acquires_shared(lock);
- extern int do_raw_read_trylock(rwlock_t *lock);
+ extern int do_raw_read_trylock(rwlock_t *lock) __cond_acquires_shared(true, lock);
  extern void do_raw_read_unlock(rwlock_t *lock) __releases_shared(lock);
  extern void do_raw_write_lock(rwlock_t *lock) __acquires(lock);
- extern int do_raw_write_trylock(rwlock_t *lock);
+extern int do_raw_write_trylock(rwlock_t *lock) __cond_acquires(true, lock);
  extern void do_raw_write_unlock(rwlock_t *lock) __releases(lock);
 #else
 # define do_raw_read_lock(rwlock)	do {__acquire_shared(lock); arch_read_lock(&(rwlock)->raw_lock); } while (0)
diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h
index 61a852609eab..9e02a5f28cd1 100644
--- a/include/linux/rwlock_api_smp.h
+++ b/include/linux/rwlock_api_smp.h
@@ -23,7 +23,7 @@ void __lockfunc _raw_write_lock_bh(rwlock_t *lock)	__acquires(lock);
 void __lockfunc _raw_read_lock_irq(rwlock_t *lock)	__acquires_shared(lock);
 void __lockfunc _raw_write_lock_irq(rwlock_t *lock)	__acquires(lock);
 unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock)
-							__acquires(lock);
+							__acquires_shared(lock);
 unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock)
 							__acquires(lock);
 int __lockfunc _raw_read_trylock(rwlock_t *lock)	__cond_acquires_shared(true, lock);
@@ -36,7 +36,7 @@ void __lockfunc _raw_read_unlock_irq(rwlock_t *lock)	__releases_shared(lock);
 void __lockfunc _raw_write_unlock_irq(rwlock_t *lock)	__releases(lock);
 void __lockfunc
 _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
-							__releases(lock);
+							__releases_shared(lock);
 void __lockfunc
 _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 							__releases(lock);
@@ -116,6 +116,7 @@ _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 #endif
 
 static inline int __raw_read_trylock(rwlock_t *lock)
+	__cond_acquires_shared(true, lock)
 {
 	preempt_disable();
 	if (do_raw_read_trylock(lock)) {
@@ -127,6 +128,7 @@ static inline int __raw_read_trylock(rwlock_t *lock)
 }
 
 static inline int __raw_write_trylock(rwlock_t *lock)
+	__cond_acquires(true, lock)
 {
 	preempt_disable();
 	if (do_raw_write_trylock(lock)) {
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index e1e2f144af9b..241277cd34cf 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -178,7 +178,7 @@ do {									\
 
 #ifdef CONFIG_DEBUG_SPINLOCK
  extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock);
- extern int do_raw_spin_trylock(raw_spinlock_t *lock);
+ extern int do_raw_spin_trylock(raw_spinlock_t *lock) __cond_acquires(true, lock);
  extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock);
 #else
 static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
@@ -189,6 +189,7 @@ static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
 }
 
 static inline int do_raw_spin_trylock(raw_spinlock_t *lock)
+	__cond_acquires(true, lock)
 {
 	int ret = arch_spin_trylock(&(lock)->raw_lock);
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 2/4] signal: Fix the lock_task_sighand() annotation
  2026-02-25 18:32 [PATCH v2 0/4] Lock context annotation fixes Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 1/4] locking: Fix rwlock and spinlock lock context annotations Bart Van Assche
@ 2026-02-25 18:32 ` Bart Van Assche
  2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 3/4] ww-mutex: Fix the ww_acquire_ctx function annotations Bart Van Assche
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2026-02-25 18:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, linux-kernel,
	Marco Elver, Christoph Hellwig, Steven Rostedt, Nick Desaulniers,
	Nathan Chancellor, Kees Cook, Jann Horn, Bart Van Assche

lock_task_sighand() may return NULL. Make this clear in its lock context
annotation.

Fixes: 04e49d926f43 ("sched: Enable context analysis for core.c and fair.c")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/sched/signal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index a22248aebcf9..a4835a7de07e 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -739,7 +739,7 @@ static inline int thread_group_empty(struct task_struct *p)
 
 extern struct sighand_struct *lock_task_sighand(struct task_struct *task,
 						unsigned long *flags)
-	__acquires(&task->sighand->siglock);
+	__cond_acquires(nonnull, &task->sighand->siglock);
 
 static inline void unlock_task_sighand(struct task_struct *task,
 						unsigned long *flags)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 3/4] ww-mutex: Fix the ww_acquire_ctx function annotations
  2026-02-25 18:32 [PATCH v2 0/4] Lock context annotation fixes Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 1/4] locking: Fix rwlock and spinlock lock context annotations Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 2/4] signal: Fix the lock_task_sighand() annotation Bart Van Assche
@ 2026-02-25 18:32 ` Bart Van Assche
  2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
  2026-02-25 18:32 ` [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis" Bart Van Assche
  2026-02-25 18:44 ` [PATCH v2 0/4] Lock context annotation fixes Marco Elver
  4 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2026-02-25 18:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, linux-kernel,
	Marco Elver, Christoph Hellwig, Steven Rostedt, Nick Desaulniers,
	Nathan Chancellor, Kees Cook, Jann Horn, Bart Van Assche,
	Maarten Lankhorst

The ww_acquire_done() call is optional. Reflect this in the annotations of
ww_acquire_done().

Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: 47907461e4f6 ("locking/ww_mutex: Support Clang's context analysis")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/ww_mutex.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/ww_mutex.h b/include/linux/ww_mutex.h
index 85b1fff02fde..0c95ead5a297 100644
--- a/include/linux/ww_mutex.h
+++ b/include/linux/ww_mutex.h
@@ -181,7 +181,7 @@ static inline void ww_acquire_init(struct ww_acquire_ctx *ctx,
  * data structures.
  */
 static inline void ww_acquire_done(struct ww_acquire_ctx *ctx)
-	__releases(ctx) __acquires_shared(ctx) __no_context_analysis
+	__must_hold(ctx)
 {
 #ifdef DEBUG_WW_MUTEXES
 	lockdep_assert_held(ctx);
@@ -199,7 +199,7 @@ static inline void ww_acquire_done(struct ww_acquire_ctx *ctx)
  * mutexes have been released with ww_mutex_unlock.
  */
 static inline void ww_acquire_fini(struct ww_acquire_ctx *ctx)
-	__releases_shared(ctx) __no_context_analysis
+	__releases(ctx) __no_context_analysis
 {
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 	mutex_release(&ctx->first_lock_dep_map, _THIS_IP_);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis"
  2026-02-25 18:32 [PATCH v2 0/4] Lock context annotation fixes Bart Van Assche
                   ` (2 preceding siblings ...)
  2026-02-25 18:32 ` [PATCH v2 3/4] ww-mutex: Fix the ww_acquire_ctx function annotations Bart Van Assche
@ 2026-02-25 18:32 ` Bart Van Assche
  2026-02-25 18:40   ` Marco Elver
  2026-02-25 18:44 ` [PATCH v2 0/4] Lock context annotation fixes Marco Elver
  4 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche @ 2026-02-25 18:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, linux-kernel,
	Marco Elver, Christoph Hellwig, Steven Rostedt, Nick Desaulniers,
	Nathan Chancellor, Kees Cook, Jann Horn, Bart Van Assche

lockdep_assert_held() supports all data structures that have a member
with the name dep_map. __assume_ctx_lock() only supports data structures
that support lock context annotation. Remove __assume_ctx_lock() from
lockdep_assert_held(). This patch fixes the following build errors if
lock context analysis is enabled for the entire kernel tree:

drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
  451 |         lockdep_assert_held_write(&tty->ldisc_sem);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
  451 |         lockdep_assert_held_write(&tty->ldisc_sem);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fixes: 7c451541743c ("lockdep: Annotate lockdep assertions for context analysis")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/lockdep.h     | 12 ++++++------
 lib/test_context-analysis.c |  6 +++---
 mm/kfence/report.c          |  1 +
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 621566345406..dd634103b014 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -282,16 +282,16 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
 	do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
 
 #define lockdep_assert_held(l)		\
-	do { lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD); __assume_ctx_lock(l); } while (0)
+	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
 
 #define lockdep_assert_not_held(l)	\
 	lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
 
 #define lockdep_assert_held_write(l)	\
-	do { lockdep_assert(lockdep_is_held_type(l, 0)); __assume_ctx_lock(l); } while (0)
+	lockdep_assert(lockdep_is_held_type(l, 0))
 
 #define lockdep_assert_held_read(l)	\
-	do { lockdep_assert(lockdep_is_held_type(l, 1)); __assume_shared_ctx_lock(l); } while (0)
+	lockdep_assert(lockdep_is_held_type(l, 1))
 
 #define lockdep_assert_held_once(l)		\
 	lockdep_assert_once(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
@@ -389,10 +389,10 @@ extern int lockdep_is_held(const void *);
 #define lockdep_assert(c)			do { } while (0)
 #define lockdep_assert_once(c)			do { } while (0)
 
-#define lockdep_assert_held(l)			__assume_ctx_lock(l)
+#define lockdep_assert_held(l)			do { (void)(l); } while (0)
 #define lockdep_assert_not_held(l)		do { (void)(l); } while (0)
-#define lockdep_assert_held_write(l)		__assume_ctx_lock(l)
-#define lockdep_assert_held_read(l)		__assume_shared_ctx_lock(l)
+#define lockdep_assert_held_write(l)		do { (void)(l); } while (0)
+#define lockdep_assert_held_read(l)		do { (void)(l); } while (0)
 #define lockdep_assert_held_once(l)		do { (void)(l); } while (0)
 #define lockdep_assert_none_held_once()	do { } while (0)
 
diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
index 140efa8a9763..9846da75e9a3 100644
--- a/lib/test_context-analysis.c
+++ b/lib/test_context-analysis.c
@@ -68,7 +68,7 @@ static void __used test_common_helpers(void)
 	}											\
 	static void __used test_##class##_assert(struct test_##class##_data *d)			\
 	{											\
-		lockdep_assert_held(&d->lock);							\
+		__assume_ctx_lock(&d->lock);							\
 		op(d->counter);									\
 	}											\
 	static void __used test_##class##_guard(struct test_##class##_data *d)			\
@@ -199,7 +199,7 @@ static void __used test_mutex_trylock(struct test_mutex_data *d, atomic_t *a)
 
 static void __used test_mutex_assert(struct test_mutex_data *d)
 {
-	lockdep_assert_held(&d->mtx);
+	__assume_ctx_lock(&d->mtx);
 	d->counter++;
 }
 
@@ -311,7 +311,7 @@ static void __used test_rwsem_writer(struct test_rwsem_data *d)
 
 static void __used test_rwsem_assert(struct test_rwsem_data *d)
 {
-	rwsem_assert_held_nolockdep(&d->sem);
+	__assume_ctx_lock(&d->sem);
 	d->counter++;
 }
 
diff --git a/mm/kfence/report.c b/mm/kfence/report.c
index 787e87c26926..d50a3f256650 100644
--- a/mm/kfence/report.c
+++ b/mm/kfence/report.c
@@ -263,6 +263,7 @@ void kfence_report_error(unsigned long address, bool is_write, struct pt_regs *r
 
 	if (meta) {
 		lockdep_assert_held(&meta->lock);
+		__assume_ctx_lock(&meta->lock);
 		pr_err("\n");
 		kfence_print_object(NULL, meta);
 	}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis"
  2026-02-25 18:32 ` [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis" Bart Van Assche
@ 2026-02-25 18:40   ` Marco Elver
  2026-02-25 19:22     ` Marco Elver
  2026-02-25 19:27     ` Bart Van Assche
  0 siblings, 2 replies; 13+ messages in thread
From: Marco Elver @ 2026-02-25 18:40 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
	Waiman Long, linux-kernel, Christoph Hellwig, Steven Rostedt,
	Nick Desaulniers, Nathan Chancellor, Kees Cook, Jann Horn

On Wed, 25 Feb 2026 at 19:33, Bart Van Assche <bvanassche@acm.org> wrote:
>
> lockdep_assert_held() supports all data structures that have a member
> with the name dep_map. __assume_ctx_lock() only supports data structures
> that support lock context annotation. Remove __assume_ctx_lock() from
> lockdep_assert_held(). This patch fixes the following build errors if
> lock context analysis is enabled for the entire kernel tree:
>
> drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
>   451 |         lockdep_assert_held_write(&tty->ldisc_sem);
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
>   451 |         lockdep_assert_held_write(&tty->ldisc_sem);
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I think that's a hint that that we should just ld_semaphore a
first-class context_lock_struct. That will enable the analysis for all
ld_semaphore users.

> Fixes: 7c451541743c ("lockdep: Annotate lockdep assertions for context analysis")
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>  include/linux/lockdep.h     | 12 ++++++------
>  lib/test_context-analysis.c |  6 +++---
>  mm/kfence/report.c          |  1 +
>  3 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
> index 621566345406..dd634103b014 100644
> --- a/include/linux/lockdep.h
> +++ b/include/linux/lockdep.h
> @@ -282,16 +282,16 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
>         do { WARN_ON_ONCE(debug_locks && !(cond)); } while (0)
>
>  #define lockdep_assert_held(l)         \
> -       do { lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD); __assume_ctx_lock(l); } while (0)
> +       lockdep_assert(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
>
>  #define lockdep_assert_not_held(l)     \
>         lockdep_assert(lockdep_is_held(l) != LOCK_STATE_HELD)
>
>  #define lockdep_assert_held_write(l)   \
> -       do { lockdep_assert(lockdep_is_held_type(l, 0)); __assume_ctx_lock(l); } while (0)
> +       lockdep_assert(lockdep_is_held_type(l, 0))
>
>  #define lockdep_assert_held_read(l)    \
> -       do { lockdep_assert(lockdep_is_held_type(l, 1)); __assume_shared_ctx_lock(l); } while (0)
> +       lockdep_assert(lockdep_is_held_type(l, 1))
>
>  #define lockdep_assert_held_once(l)            \
>         lockdep_assert_once(lockdep_is_held(l) != LOCK_STATE_NOT_HELD)
> @@ -389,10 +389,10 @@ extern int lockdep_is_held(const void *);
>  #define lockdep_assert(c)                      do { } while (0)
>  #define lockdep_assert_once(c)                 do { } while (0)
>
> -#define lockdep_assert_held(l)                 __assume_ctx_lock(l)
> +#define lockdep_assert_held(l)                 do { (void)(l); } while (0)
>  #define lockdep_assert_not_held(l)             do { (void)(l); } while (0)
> -#define lockdep_assert_held_write(l)           __assume_ctx_lock(l)
> -#define lockdep_assert_held_read(l)            __assume_shared_ctx_lock(l)
> +#define lockdep_assert_held_write(l)           do { (void)(l); } while (0)
> +#define lockdep_assert_held_read(l)            do { (void)(l); } while (0)
>  #define lockdep_assert_held_once(l)            do { (void)(l); } while (0)
>  #define lockdep_assert_none_held_once()        do { } while (0)
>
> diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
> index 140efa8a9763..9846da75e9a3 100644
> --- a/lib/test_context-analysis.c
> +++ b/lib/test_context-analysis.c
> @@ -68,7 +68,7 @@ static void __used test_common_helpers(void)
>         }                                                                                       \
>         static void __used test_##class##_assert(struct test_##class##_data *d)                 \
>         {                                                                                       \
> -               lockdep_assert_held(&d->lock);                                                  \
> +               __assume_ctx_lock(&d->lock);                                                    \
>                 op(d->counter);                                                                 \
>         }                                                                                       \
>         static void __used test_##class##_guard(struct test_##class##_data *d)                  \
> @@ -199,7 +199,7 @@ static void __used test_mutex_trylock(struct test_mutex_data *d, atomic_t *a)
>
>  static void __used test_mutex_assert(struct test_mutex_data *d)
>  {
> -       lockdep_assert_held(&d->mtx);
> +       __assume_ctx_lock(&d->mtx);
>         d->counter++;

These tests were supposed to demonstrate exactly that
lockdep_assert_held() works and doesn't require adding more pointless
annotations.

Our lockdep_assert follow this exact pattern:
https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#assert-capability-and-assert-shared-capability

>         d->counter++;
>  }
>
> diff --git a/mm/kfence/report.c b/mm/kfence/report.c
> index 787e87c26926..d50a3f256650 100644
> --- a/mm/kfence/report.c
> +++ b/mm/kfence/report.c
> @@ -263,6 +263,7 @@ void kfence_report_error(unsigned long address, bool is_write, struct pt_regs *r
>
>         if (meta) {
>                 lockdep_assert_held(&meta->lock);
> +               __assume_ctx_lock(&meta->lock);

And this example here is exactly the reason why this is wrong - I
don't want pointless annotations like this.

Thanks.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/4] Lock context annotation fixes
  2026-02-25 18:32 [PATCH v2 0/4] Lock context annotation fixes Bart Van Assche
                   ` (3 preceding siblings ...)
  2026-02-25 18:32 ` [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis" Bart Van Assche
@ 2026-02-25 18:44 ` Marco Elver
  4 siblings, 0 replies; 13+ messages in thread
From: Marco Elver @ 2026-02-25 18:44 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
	Waiman Long, linux-kernel, Christoph Hellwig, Steven Rostedt,
	Nick Desaulniers, Nathan Chancellor, Kees Cook, Jann Horn

On Wed, 25 Feb 2026 at 19:33, Bart Van Assche <bvanassche@acm.org> wrote:
>
> Hi Peter,
>
> Some of the lock context annotations that have been introduced during the most
> recent merge window were incomplete or incorrect. Hence this patch series with
> fixes. Please consider this patch series for the current kernel development
> cycle.
>
> Thanks,
>
> Bart.
>
> Changes compared to v1:
>  - Expanded Cc-list. Added the linux-kernel mailing list and more kernel developers
>    to the Cc-list.
>  - Added Maarten's Acked-by to patch 3/4.
>
> Bart Van Assche (4):
>   locking: Fix rwlock and spinlock lock context annotations
>   signal: Fix the lock_task_sighand() annotation
>   ww-mutex: Fix the ww_acquire_ctx function annotations

I think the above look fine.

>   Revert "lockdep: Annotate lockdep assertions for context analysis"

But this one is a Nack - it makes the programming model worse. If
there are lockdep_assert'able locks, those just need to become
context_lock_structs.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis"
  2026-02-25 18:40   ` Marco Elver
@ 2026-02-25 19:22     ` Marco Elver
  2026-02-25 19:27     ` Bart Van Assche
  1 sibling, 0 replies; 13+ messages in thread
From: Marco Elver @ 2026-02-25 19:22 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
	Waiman Long, linux-kernel, Christoph Hellwig, Steven Rostedt,
	Nick Desaulniers, Nathan Chancellor, Kees Cook, Jann Horn

On Wed, 25 Feb 2026 at 19:40, Marco Elver <elver@google.com> wrote:
>
> On Wed, 25 Feb 2026 at 19:33, Bart Van Assche <bvanassche@acm.org> wrote:
> >
> > lockdep_assert_held() supports all data structures that have a member
> > with the name dep_map. __assume_ctx_lock() only supports data structures
> > that support lock context annotation. Remove __assume_ctx_lock() from
> > lockdep_assert_held(). This patch fixes the following build errors if
> > lock context analysis is enabled for the entire kernel tree:
> >
> > drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
> >   451 |         lockdep_assert_held_write(&tty->ldisc_sem);
> >       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
> >   451 |         lockdep_assert_held_write(&tty->ldisc_sem);
> >       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> I think that's a hint that that we should just ld_semaphore a
> first-class context_lock_struct. That will enable the analysis for all
> ld_semaphore users.

If it helps, I did this in an early iteration which resolved the above
issues: https://lore.kernel.org/all/20250304092417.2873893-32-elver@google.com/

Should work as-is, just needs some renames of the macros which were
renamed since then (and drop the __assert_cap from the init function
which was subsumed by init guards).

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis"
  2026-02-25 18:40   ` Marco Elver
  2026-02-25 19:22     ` Marco Elver
@ 2026-02-25 19:27     ` Bart Van Assche
  1 sibling, 0 replies; 13+ messages in thread
From: Bart Van Assche @ 2026-02-25 19:27 UTC (permalink / raw)
  To: Marco Elver
  Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
	Waiman Long, linux-kernel, Christoph Hellwig, Steven Rostedt,
	Nick Desaulniers, Nathan Chancellor, Kees Cook, Jann Horn

On 2/25/26 10:40 AM, Marco Elver wrote:
> On Wed, 25 Feb 2026 at 19:33, Bart Van Assche <bvanassche@acm.org> wrote:
>>
>> lockdep_assert_held() supports all data structures that have a member
>> with the name dep_map. __assume_ctx_lock() only supports data structures
>> that support lock context annotation. Remove __assume_ctx_lock() from
>> lockdep_assert_held(). This patch fixes the following build errors if
>> lock context analysis is enabled for the entire kernel tree:
>>
>> drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
>>    451 |         lockdep_assert_held_write(&tty->ldisc_sem);
>>        |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>
>> drivers/tty/tty_ldisc.c:451:2: error: call to '__assume_ctx_lock' is ambiguous
>>    451 |         lockdep_assert_held_write(&tty->ldisc_sem);
>>        |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> I think that's a hint that that we should just ld_semaphore a
> first-class context_lock_struct. That will enable the analysis for all
> ld_semaphore users.

This seems to be sufficient to solve the build errors if patch 4/4 is 
dropped:

diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index b5a5f32fdfd1..9be0a2c8bb40 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -192,6 +192,7 @@ struct kernfs_elem_attr {
   * accessible.  Dereferencing elem or any other outer entity requires
   * active reference.
   */
+context_lock_struct(kernfs_node);
  struct kernfs_node {
         atomic_t                count;
         atomic_t                active;
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index c5cccc3fc1e8..2977873b84c5 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -14,6 +14,7 @@ struct tty_struct;
  /*
   * the semaphore definition
   */
+context_lock_struct(ld_semaphore);
  struct ld_semaphore {
         atomic_long_t           count;
         raw_spinlock_t          wait_lock;

Bart.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip: locking/core] ww-mutex: Fix the ww_acquire_ctx function annotations
  2026-02-25 18:32 ` [PATCH v2 3/4] ww-mutex: Fix the ww_acquire_ctx function annotations Bart Van Assche
@ 2026-02-28 10:56   ` tip-bot2 for Bart Van Assche
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Bart Van Assche @ 2026-02-28 10:56 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Bart Van Assche, Peter Zijlstra (Intel),
	Maarten Lankhorst, Marco Elver, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     3dcef70e41ab13483803c536ddea8d5f1803ee25
Gitweb:        https://git.kernel.org/tip/3dcef70e41ab13483803c536ddea8d5f1803ee25
Author:        Bart Van Assche <bvanassche@acm.org>
AuthorDate:    Wed, 25 Feb 2026 10:32:43 -08:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:20 +01:00

ww-mutex: Fix the ww_acquire_ctx function annotations

The ww_acquire_done() call is optional. Reflect this in the annotations of
ww_acquire_done().

Fixes: 47907461e4f6 ("locking/ww_mutex: Support Clang's context analysis")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Acked-by: Marco Elver <elver@google.com>
Link: https://patch.msgid.link/20260225183244.4035378-4-bvanassche@acm.org
---
 include/linux/ww_mutex.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/ww_mutex.h b/include/linux/ww_mutex.h
index 85b1fff..0c95ead 100644
--- a/include/linux/ww_mutex.h
+++ b/include/linux/ww_mutex.h
@@ -181,7 +181,7 @@ static inline void ww_acquire_init(struct ww_acquire_ctx *ctx,
  * data structures.
  */
 static inline void ww_acquire_done(struct ww_acquire_ctx *ctx)
-	__releases(ctx) __acquires_shared(ctx) __no_context_analysis
+	__must_hold(ctx)
 {
 #ifdef DEBUG_WW_MUTEXES
 	lockdep_assert_held(ctx);
@@ -199,7 +199,7 @@ static inline void ww_acquire_done(struct ww_acquire_ctx *ctx)
  * mutexes have been released with ww_mutex_unlock.
  */
 static inline void ww_acquire_fini(struct ww_acquire_ctx *ctx)
-	__releases_shared(ctx) __no_context_analysis
+	__releases(ctx) __no_context_analysis
 {
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 	mutex_release(&ctx->first_lock_dep_map, _THIS_IP_);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip: locking/core] signal: Fix the lock_task_sighand() annotation
  2026-02-25 18:32 ` [PATCH v2 2/4] signal: Fix the lock_task_sighand() annotation Bart Van Assche
@ 2026-02-28 10:56   ` tip-bot2 for Bart Van Assche
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Bart Van Assche @ 2026-02-28 10:56 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Bart Van Assche, Peter Zijlstra (Intel), Marco Elver, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     39be7b21af24d1d2ed3b18caac57dd219fef226e
Gitweb:        https://git.kernel.org/tip/39be7b21af24d1d2ed3b18caac57dd219fef226e
Author:        Bart Van Assche <bvanassche@acm.org>
AuthorDate:    Wed, 25 Feb 2026 10:32:42 -08:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:19 +01:00

signal: Fix the lock_task_sighand() annotation

lock_task_sighand() may return NULL. Make this clear in its lock context
annotation.

Fixes: 04e49d926f43 ("sched: Enable context analysis for core.c and fair.c")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Marco Elver <elver@google.com>
Link: https://patch.msgid.link/20260225183244.4035378-3-bvanassche@acm.org
---
 include/linux/sched/signal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index a22248a..a4835a7 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -739,7 +739,7 @@ static inline int thread_group_empty(struct task_struct *p)
 
 extern struct sighand_struct *lock_task_sighand(struct task_struct *task,
 						unsigned long *flags)
-	__acquires(&task->sighand->siglock);
+	__cond_acquires(nonnull, &task->sighand->siglock);
 
 static inline void unlock_task_sighand(struct task_struct *task,
 						unsigned long *flags)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip: locking/core] locking: Fix rwlock and spinlock lock context annotations
  2026-02-25 18:32 ` [PATCH v2 1/4] locking: Fix rwlock and spinlock lock context annotations Bart Van Assche
@ 2026-02-28 10:56   ` tip-bot2 for Bart Van Assche
  2026-03-12 16:36     ` Bart Van Assche
  0 siblings, 1 reply; 13+ messages in thread
From: tip-bot2 for Bart Van Assche @ 2026-02-28 10:56 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Bart Van Assche, Peter Zijlstra (Intel), Marco Elver, x86, linux-kernel

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     38e18d825f7281fdc16d3241df5115ce6eaeaf79
Gitweb:        https://git.kernel.org/tip/38e18d825f7281fdc16d3241df5115ce6eaeaf79
Author:        Bart Van Assche <bvanassche@acm.org>
AuthorDate:    Wed, 25 Feb 2026 10:32:41 -08:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:19 +01:00

locking: Fix rwlock and spinlock lock context annotations

Fix two incorrect rwlock_t lock context annotations. Add the raw_spinlock_t
lock context annotations that are missing.

Fixes: f16a802d402d ("locking/rwlock, spinlock: Support Clang's context analysis")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Marco Elver <elver@google.com>
Link: https://patch.msgid.link/20260225183244.4035378-2-bvanassche@acm.org
---
 include/linux/rwlock.h         | 4 ++--
 include/linux/rwlock_api_smp.h | 6 ++++--
 include/linux/spinlock.h       | 3 ++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index 3390d21..21ceefc 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -30,10 +30,10 @@ do {								\
 
 #ifdef CONFIG_DEBUG_SPINLOCK
  extern void do_raw_read_lock(rwlock_t *lock) __acquires_shared(lock);
- extern int do_raw_read_trylock(rwlock_t *lock);
+ extern int do_raw_read_trylock(rwlock_t *lock) __cond_acquires_shared(true, lock);
  extern void do_raw_read_unlock(rwlock_t *lock) __releases_shared(lock);
  extern void do_raw_write_lock(rwlock_t *lock) __acquires(lock);
- extern int do_raw_write_trylock(rwlock_t *lock);
+extern int do_raw_write_trylock(rwlock_t *lock) __cond_acquires(true, lock);
  extern void do_raw_write_unlock(rwlock_t *lock) __releases(lock);
 #else
 # define do_raw_read_lock(rwlock)	do {__acquire_shared(lock); arch_read_lock(&(rwlock)->raw_lock); } while (0)
diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h
index 61a8526..9e02a5f 100644
--- a/include/linux/rwlock_api_smp.h
+++ b/include/linux/rwlock_api_smp.h
@@ -23,7 +23,7 @@ void __lockfunc _raw_write_lock_bh(rwlock_t *lock)	__acquires(lock);
 void __lockfunc _raw_read_lock_irq(rwlock_t *lock)	__acquires_shared(lock);
 void __lockfunc _raw_write_lock_irq(rwlock_t *lock)	__acquires(lock);
 unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock)
-							__acquires(lock);
+							__acquires_shared(lock);
 unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock)
 							__acquires(lock);
 int __lockfunc _raw_read_trylock(rwlock_t *lock)	__cond_acquires_shared(true, lock);
@@ -36,7 +36,7 @@ void __lockfunc _raw_read_unlock_irq(rwlock_t *lock)	__releases_shared(lock);
 void __lockfunc _raw_write_unlock_irq(rwlock_t *lock)	__releases(lock);
 void __lockfunc
 _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
-							__releases(lock);
+							__releases_shared(lock);
 void __lockfunc
 _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 							__releases(lock);
@@ -116,6 +116,7 @@ _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 #endif
 
 static inline int __raw_read_trylock(rwlock_t *lock)
+	__cond_acquires_shared(true, lock)
 {
 	preempt_disable();
 	if (do_raw_read_trylock(lock)) {
@@ -127,6 +128,7 @@ static inline int __raw_read_trylock(rwlock_t *lock)
 }
 
 static inline int __raw_write_trylock(rwlock_t *lock)
+	__cond_acquires(true, lock)
 {
 	preempt_disable();
 	if (do_raw_write_trylock(lock)) {
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index e1e2f14..241277c 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -178,7 +178,7 @@ do {									\
 
 #ifdef CONFIG_DEBUG_SPINLOCK
  extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock);
- extern int do_raw_spin_trylock(raw_spinlock_t *lock);
+ extern int do_raw_spin_trylock(raw_spinlock_t *lock) __cond_acquires(true, lock);
  extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock);
 #else
 static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
@@ -189,6 +189,7 @@ static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
 }
 
 static inline int do_raw_spin_trylock(raw_spinlock_t *lock)
+	__cond_acquires(true, lock)
 {
 	int ret = arch_spin_trylock(&(lock)->raw_lock);
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [tip: locking/core] locking: Fix rwlock and spinlock lock context annotations
  2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
@ 2026-03-12 16:36     ` Bart Van Assche
  0 siblings, 0 replies; 13+ messages in thread
From: Bart Van Assche @ 2026-03-12 16:36 UTC (permalink / raw)
  To: linux-kernel, linux-tip-commits; +Cc: Peter Zijlstra (Intel), Marco Elver, x86

On 2/28/26 2:56 AM, tip-bot2 for Bart Van Assche wrote:
> The following commit has been merged into the locking/core branch of tip:
> 
> Commit-ID:     38e18d825f7281fdc16d3241df5115ce6eaeaf79
> Gitweb:        https://git.kernel.org/tip/38e18d825f7281fdc16d3241df5115ce6eaeaf79
> Author:        Bart Van Assche <bvanassche@acm.org>
> AuthorDate:    Wed, 25 Feb 2026 10:32:41 -08:00
> Committer:     Peter Zijlstra <peterz@infradead.org>
> CommitterDate: Fri, 27 Feb 2026 16:40:19 +01:00
> 
> locking: Fix rwlock and spinlock lock context annotations

Hi Peter,

Thank you for having queued this patch.

Since some of my other patches depend on this patch, will this patch be
sent to Linus during the current rc cycle? I'm asking this because I
can't find this patch in Linus' master branch:

$ git fetch origin
$ git log --reverse --format=oneline v6.19..origin/master 
include/linux/rwlock_api_smp.h
f16a802d402d735a55731f8c94952b3bbb5ddfe8 locking/rwlock, spinlock: 
Support Clang's context analysis
e4588c25c9d122b5847b88e18b184404b6959160 compiler-context-analysis: 
Remove __cond_lock() function-like helper
7a562d5d2396c9c78fbbced7ae81bcfcfa0fde3f (tag: locking-core-2026-02-08) 
locking/rwlock: Fix write_trylock_irqsave() with CONFIG_INLINE_WRITE_TRYLOCK

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-03-12 16:36 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-25 18:32 [PATCH v2 0/4] Lock context annotation fixes Bart Van Assche
2026-02-25 18:32 ` [PATCH v2 1/4] locking: Fix rwlock and spinlock lock context annotations Bart Van Assche
2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
2026-03-12 16:36     ` Bart Van Assche
2026-02-25 18:32 ` [PATCH v2 2/4] signal: Fix the lock_task_sighand() annotation Bart Van Assche
2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
2026-02-25 18:32 ` [PATCH v2 3/4] ww-mutex: Fix the ww_acquire_ctx function annotations Bart Van Assche
2026-02-28 10:56   ` [tip: locking/core] " tip-bot2 for Bart Van Assche
2026-02-25 18:32 ` [PATCH v2 4/4] Revert "lockdep: Annotate lockdep assertions for context analysis" Bart Van Assche
2026-02-25 18:40   ` Marco Elver
2026-02-25 19:22     ` Marco Elver
2026-02-25 19:27     ` Bart Van Assche
2026-02-25 18:44 ` [PATCH v2 0/4] Lock context annotation fixes Marco Elver

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®