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

Showing the changes to kernel (2 of 3 files). Show all

Unified · Split

2 files
  1. kernel/locking/rtmutex.c +4 −0
  2. kernel/locking/rtmutex_api.c +28 −3
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
484 484
485static __always_inline void485static __always_inline void
486rt_mutex_enqueue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter)486rt_mutex_enqueue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter)
487 __must_hold(&lock->wait_lock)
487{488{
488 lockdep_assert_held(&lock->wait_lock);489 lockdep_assert_held(&lock->wait_lock);
489 490
@@ -492,6 +493,7 @@ rt_mutex_enqueue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter) · 2 unmodified lines
492 493
493static __always_inline void494static __always_inline void
494rt_mutex_dequeue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter)495rt_mutex_dequeue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter)
496 __must_hold(&lock->wait_lock)
495{497{
496 lockdep_assert_held(&lock->wait_lock);498 lockdep_assert_held(&lock->wait_lock);
497 499
@@ -1092,6 +1094,7 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, · 594 unmodified lines
1092static int __sched1094static int __sched
1093try_to_take_rt_mutex(struct rt_mutex_base *lock, struct task_struct *task,1095try_to_take_rt_mutex(struct rt_mutex_base *lock, struct task_struct *task,
1094 struct rt_mutex_waiter *waiter)1096 struct rt_mutex_waiter *waiter)
1097 __must_hold(&lock->wait_lock)
1095{1098{
1096 lockdep_assert_held(&lock->wait_lock);1099 lockdep_assert_held(&lock->wait_lock);
1097 1100
@@ -1319,6 +1322,7 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock, · 221 unmodified lines
1319 */1322 */
1320static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh,1323static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh,
1321 struct rt_mutex_base *lock)1324 struct rt_mutex_base *lock)
1325 __must_hold(&lock->wait_lock)
1322{1326{
1323 struct rt_mutex_waiter *waiter;1327 struct rt_mutex_waiter *waiter;
1324 1328
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
41 unsigned int state,41 unsigned int state,
42 struct lockdep_map *nest_lock,42 struct lockdep_map *nest_lock,
43 unsigned int subclass)43 unsigned int subclass)
44 __cond_acquires(0, lock)
44{45{
45 int ret;46 int ret;
46 47
@@ -67,13 +68,27 @@ EXPORT_SYMBOL(rt_mutex_base_init); · 20 unmodified lines
67 */68 */
68void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass)69void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass)
69{70{
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);
71}79}
72EXPORT_SYMBOL_GPL(rt_mutex_lock_nested);80EXPORT_SYMBOL_GPL(rt_mutex_lock_nested);
73 81
74void __sched _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock)82void __sched _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock)
75{83{
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);
77}92}
78EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock);93EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock);
79 94
@@ -86,7 +101,14 @@ EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock); · 6 unmodified lines
86 */101 */
87void __sched rt_mutex_lock(struct rt_mutex *lock)102void __sched rt_mutex_lock(struct rt_mutex *lock)
88{103{
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);
90}112}
91EXPORT_SYMBOL_GPL(rt_mutex_lock);113EXPORT_SYMBOL_GPL(rt_mutex_lock);
92#endif114#endif
@@ -157,6 +179,7 @@ void __sched rt_mutex_unlock(struct rt_mutex *lock) · 64 unmodified lines
157{179{
158 mutex_release(&lock->dep_map, _RET_IP_);180 mutex_release(&lock->dep_map, _RET_IP_);
159 __rt_mutex_unlock(&lock->rtmutex);181 __rt_mutex_unlock(&lock->rtmutex);
182 __release(lock);
160}183}
161EXPORT_SYMBOL_GPL(rt_mutex_unlock);184EXPORT_SYMBOL_GPL(rt_mutex_unlock);
162 185
@@ -182,6 +205,7 @@ int __sched __rt_mutex_futex_trylock(struct rt_mutex_base *lock) · 19 unmodified lines
182 */205 */
183bool __sched __rt_mutex_futex_unlock(struct rt_mutex_base *lock,206bool __sched __rt_mutex_futex_unlock(struct rt_mutex_base *lock,
184 struct rt_wake_q_head *wqh)207 struct rt_wake_q_head *wqh)
208 __must_hold(&lock->wait_lock)
185{209{
186 lockdep_assert_held(&lock->wait_lock);210 lockdep_assert_held(&lock->wait_lock);
187 211
@@ -312,6 +336,7 @@ int __sched __rt_mutex_start_proxy_lock(struct rt_mutex_base *lock, · 124 unmodified lines
312 struct rt_mutex_waiter *waiter,336 struct rt_mutex_waiter *waiter,
313 struct task_struct *task,337 struct task_struct *task,
314 struct wake_q_head *wake_q)338 struct wake_q_head *wake_q)
339 __must_hold(&lock->wait_lock)
315{340{
316 int ret;341 int ret;
317 342