Messages in this thread |  | | Date | Tue, 5 May 2026 18:12:56 +0200 | | From | Sebastian Andrzej Siewior <> | | Subject | Re: [PATCH v2] locking/rtmutex: Annotate API and implementation |
| |
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
|  |