History

locking/rtmutex: Annotate API and implementation

Enable context analysis for struct rt_mutex and annotate all functions that accept a struct rt_mutex pointer. In the __rt_mutex_lock_common() callers, instead of adding the __no_context_analysis annotation, emit a runtime warning if the __rt_mutex_lock_common() return value is not zero and add an __acquire() statement.

Bart Van Assche committed 6 months ago

Commit a9e4e501 parent 03240f53 files · +47 −10Browse files

Unified · Split

3 files
  1. include/linux/rtmutex.h +15 −7
  2. kernel/locking/rtmutex.c +4 −0
  3. kernel/locking/rtmutex_api.c +28 −3
include/linux/rtmutex.h+15−7
@@ -56,6 +56,8 @@ static inline struct task_struct *rt_mutex_owner(struct rt_mutex_base *lock) · 55 unmodified lines
5656 #endif
5757 extern void rt_mutex_base_init(struct rt_mutex_base *rtb);
5858
59+context_lock_struct(rt_mutex);
60+
5961 /**
6062 * The rt_mutex structure
6163 *
@@ -108,8 +110,10 @@ do { \ · 46 unmodified lines
108110 extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
109111
110112 #ifdef CONFIG_DEBUG_LOCK_ALLOC
111−extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass);
112−extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock);
113+extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass)
114+ __acquires(lock);
115+extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock)
116+ __acquires(lock);
113117 #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0)
114118 #define rt_mutex_lock_nest_lock(lock, nest_lock) \
115119 do { \
@@ -118,15 +122,19 @@ extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map * · 2 unmodified lines
118122 } while (0)
119123
120124 #else
121−extern void rt_mutex_lock(struct rt_mutex *lock);
125+extern void rt_mutex_lock(struct rt_mutex *lock) __acquires(lock);
122126 #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock)
123127 #define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock)
124128 #endif
125129
126−extern int rt_mutex_lock_interruptible(struct rt_mutex *lock);
127−extern int rt_mutex_lock_killable(struct rt_mutex *lock);
128−extern int rt_mutex_trylock(struct rt_mutex *lock);
130+extern int rt_mutex_lock_interruptible(struct rt_mutex *lock)
131+ __cond_acquires(0, lock);
132+extern int rt_mutex_lock_killable(struct rt_mutex *lock)
133+ __cond_acquires(0, lock);
134+extern int rt_mutex_trylock(struct rt_mutex *lock)
135+ __cond_acquires(true, lock);
129136
130−extern void rt_mutex_unlock(struct rt_mutex *lock);
137+extern void rt_mutex_unlock(struct rt_mutex *lock)
138+ __releases(lock);
131139
132140 #endif
kernel/locking/rtmutex.c+4−0
@@ -484,6 +484,7 @@ static __always_inline bool __waiter_less(struct rb_node *a, const struct rb_nod · 483 unmodified lines
484484
485485 static __always_inline void
486486 rt_mutex_enqueue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter)
487+ __must_hold(&lock->wait_lock)
487488 {
488489 lockdep_assert_held(&lock->wait_lock);
489490
@@ -492,6 +493,7 @@ rt_mutex_enqueue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter) · 2 unmodified lines
492493
493494 static __always_inline void
494495 rt_mutex_dequeue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter)
496+ __must_hold(&lock->wait_lock)
495497 {
496498 lockdep_assert_held(&lock->wait_lock);
497499
@@ -1092,6 +1094,7 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, · 594 unmodified lines
10921094 static int __sched
10931095 try_to_take_rt_mutex(struct rt_mutex_base *lock, struct task_struct *task,
10941096 struct rt_mutex_waiter *waiter)
1097+ __must_hold(&lock->wait_lock)
10951098 {
10961099 lockdep_assert_held(&lock->wait_lock);
10971100
@@ -1319,6 +1322,7 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock, · 221 unmodified lines
13191322 */
13201323 static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh,
13211324 struct rt_mutex_base *lock)
1325+ __must_hold(&lock->wait_lock)
13221326 {
13231327 struct rt_mutex_waiter *waiter;
13241328
kernel/locking/rtmutex_api.c+28−3
@@ -41,6 +41,7 @@ static __always_inline int __rt_mutex_lock_common(struct rt_mutex *lock, · 40 unmodified lines
4141 unsigned int state,
4242 struct lockdep_map *nest_lock,
4343 unsigned int subclass)
44+ __cond_acquires(0, lock)
4445 {
4546 int ret;
4647
@@ -67,13 +68,27 @@ EXPORT_SYMBOL(rt_mutex_base_init); · 20 unmodified lines
6768 */
6869 void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass)
6970 {
70− __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, subclass);
71+ if (__rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, subclass) == 0)
72+ return;
73+ /*
74+ * The code below is never reached because __rt_mutex_lock_common() only
75+ * returns an error code if interrupted by a signal or upon a timeout.
76+ */
77+ WARN_ON_ONCE(true);
78+ __acquire(lock);
7179 }
7280 EXPORT_SYMBOL_GPL(rt_mutex_lock_nested);
7381
7482 void __sched _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock)
7583 {
76− __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, nest_lock, 0);
84+ if (__rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, nest_lock, 0) == 0)
85+ return;
86+ /*
87+ * The code below is never reached because __rt_mutex_lock_common() only
88+ * returns an error code if interrupted by a signal or upon a timeout.
89+ */
90+ WARN_ON_ONCE(true);
91+ __acquire(lock);
7792 }
7893 EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock);
7994
@@ -86,7 +101,14 @@ EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock); · 6 unmodified lines
86101 */
87102 void __sched rt_mutex_lock(struct rt_mutex *lock)
88103 {
89− __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, 0);
104+ if (__rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, 0) == 0)
105+ return;
106+ /*
107+ * The code below is never reached because __rt_mutex_lock_common() only
108+ * returns an error code if interrupted by a signal or upon a timeout.
109+ */
110+ WARN_ON_ONCE(true);
111+ __acquire(lock);
90112 }
91113 EXPORT_SYMBOL_GPL(rt_mutex_lock);
92114 #endif
@@ -157,6 +179,7 @@ void __sched rt_mutex_unlock(struct rt_mutex *lock) · 64 unmodified lines
157179 {
158180 mutex_release(&lock->dep_map, _RET_IP_);
159181 __rt_mutex_unlock(&lock->rtmutex);
182+ __release(lock);
160183 }
161184 EXPORT_SYMBOL_GPL(rt_mutex_unlock);
162185
@@ -182,6 +205,7 @@ int __sched __rt_mutex_futex_trylock(struct rt_mutex_base *lock) · 19 unmodified lines
182205 */
183206 bool __sched __rt_mutex_futex_unlock(struct rt_mutex_base *lock,
184207 struct rt_wake_q_head *wqh)
208+ __must_hold(&lock->wait_lock)
185209 {
186210 lockdep_assert_held(&lock->wait_lock);
187211
@@ -312,6 +336,7 @@ int __sched __rt_mutex_start_proxy_lock(struct rt_mutex_base *lock, · 124 unmodified lines
312336 struct rt_mutex_waiter *waiter,
313337 struct task_struct *task,
314338 struct wake_q_head *wake_q)
339+ __must_hold(&lock->wait_lock)
315340 {
316341 int ret;
317342