Re: [PATCH v2] locking/rtmutex: Annotate API and implementation
From: Sebastian Andrzej Siewior
Date: Tue May 05 2026 - 12:19:56 EST
On 2026-05-05 04:26:44 [+0200], Bart Van Assche wrote:
> --- a/include/linux/rtmutex.h
> +++ b/include/linux/rtmutex.h
> @@ -56,6 +56,8 @@ static inline struct task_struct *rt_mutex_owner(struct rt_mutex_base *lock)
> #endif
> extern void rt_mutex_base_init(struct rt_mutex_base *rtb);
>
> +context_lock_struct(rt_mutex);
What does this do? Shouldn't this define the struct?
> /**
> * The rt_mutex structure
> *
> @@ -108,8 +110,10 @@ do { \
> extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
>
> #ifdef CONFIG_DEBUG_LOCK_ALLOC
> -extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass);
> -extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock);
> +extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass)
> + __acquires(lock);
> +extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock)
> + __acquires(lock);
> #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0)
> #define rt_mutex_lock_nest_lock(lock, nest_lock) \
> do { \
> @@ -118,15 +122,19 @@ extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *
> } while (0)
>
> #else
> -extern void rt_mutex_lock(struct rt_mutex *lock);
> +extern void rt_mutex_lock(struct rt_mutex *lock) __acquires(lock);
So this is "one" thing where you add annotation to the rt_mutex*() API
for external users. Then you add the wait_lock annotation. Different
scope but okay.
…
> --- a/kernel/locking/rtmutex_api.c
> +++ b/kernel/locking/rtmutex_api.c
> @@ -66,12 +67,14 @@ EXPORT_SYMBOL(rt_mutex_base_init);
> * @subclass: the lockdep subclass
> */
> void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass)
> + __no_context_analysis /* ignoring the return value below is fine in this case */
> {
> __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, subclass);
> }
> EXPORT_SYMBOL_GPL(rt_mutex_lock_nested);
>
> void __sched _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock)
> + __no_context_analysis /* ignoring the return value below is fine in this case */
> {
> __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, nest_lock, 0);
> }
*Why* is it okay? Because the void always acquire the lock and only the
conditional locking (which can be interrupted by signal/ timeout) return
an error if they failed to acquire the lock. Something like that would
be nice for the comment.
Not sure if "__no_context_analysis" is the right thing to do here.
__acquires(lock) __no_context_analysis
might be better if just __acquires leads to trouble.
Sebastian