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.
Showing the changes to kernel (2 of 3 files). Show all
Unified · Split
| @@ -484,6 +484,7 @@ static __always_inline bool __waiter_less(struct rb_node *a, const struct rb_nod · 483 unmodified lines | |||
| 484 | 484 | ||
| 485 | static __always_inline void | 485 | static __always_inline void |
| 486 | rt_mutex_enqueue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter) | 486 | rt_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 | ||
| 493 | static __always_inline void | 494 | static __always_inline void |
| 494 | rt_mutex_dequeue(struct rt_mutex_base *lock, struct rt_mutex_waiter *waiter) | 495 | rt_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 | |||
| 1092 | static int __sched | 1094 | static int __sched |
| 1093 | try_to_take_rt_mutex(struct rt_mutex_base *lock, struct task_struct *task, | 1095 | try_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 | */ |
| 1320 | static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh, | 1323 | static 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 | ||
| @@ -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 | */ |
| 68 | void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass) | 69 | void __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 | } |
| 72 | EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); | 80 | EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); |
| 73 | 81 | ||
| 74 | void __sched _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock) | 82 | void __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 | } |
| 78 | EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock); | 93 | EXPORT_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 | */ |
| 87 | void __sched rt_mutex_lock(struct rt_mutex *lock) | 102 | void __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 | } |
| 91 | EXPORT_SYMBOL_GPL(rt_mutex_lock); | 113 | EXPORT_SYMBOL_GPL(rt_mutex_lock); |
| 92 | #endif | 114 | #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 | } |
| 161 | EXPORT_SYMBOL_GPL(rt_mutex_unlock); | 184 | EXPORT_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 | */ |
| 183 | bool __sched __rt_mutex_futex_unlock(struct rt_mutex_base *lock, | 206 | bool __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 | ||