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.
Unified · Split
| @@ -56,6 +56,8 @@ static inline struct task_struct *rt_mutex_owner(struct rt_mutex_base *lock) · 55 unmodified lines | |||
| 56 | #endif | 56 | #endif |
| 57 | extern void rt_mutex_base_init(struct rt_mutex_base *rtb); | 57 | extern void rt_mutex_base_init(struct rt_mutex_base *rtb); |
| 58 | 58 | ||
| 59 | context_lock_struct(rt_mutex); | ||
| 60 | |||
| 59 | /** | 61 | /** |
| 60 | * The rt_mutex structure | 62 | * The rt_mutex structure |
| 61 | * | 63 | * |
| @@ -108,8 +110,10 @@ do { \ · 46 unmodified lines | |||
| 108 | extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key); | 110 | extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key); |
| 109 | 111 | ||
| 110 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 112 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 111 | extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass); | 113 | 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); | 114 | __acquires(lock); |
| 115 | extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock) | ||
| 116 | __acquires(lock); | ||
| 113 | #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0) | 117 | #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0) |
| 114 | #define rt_mutex_lock_nest_lock(lock, nest_lock) \ | 118 | #define rt_mutex_lock_nest_lock(lock, nest_lock) \ |
| 115 | do { \ | 119 | do { \ |
| @@ -118,15 +122,19 @@ extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map * · 2 unmodified lines | |||
| 118 | } while (0) | 122 | } while (0) |
| 119 | 123 | ||
| 120 | #else | 124 | #else |
| 121 | extern void rt_mutex_lock(struct rt_mutex *lock); | 125 | extern void rt_mutex_lock(struct rt_mutex *lock) __acquires(lock); |
| 122 | #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock) | 126 | #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock) |
| 123 | #define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock) | 127 | #define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock) |
| 124 | #endif | 128 | #endif |
| 125 | 129 | ||
| 126 | extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); | 130 | extern int rt_mutex_lock_interruptible(struct rt_mutex *lock) |
| 127 | extern int rt_mutex_lock_killable(struct rt_mutex *lock); | 131 | __cond_acquires(0, lock); |
| 128 | extern int rt_mutex_trylock(struct rt_mutex *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); | ||
| 129 | 136 | ||
| 130 | extern void rt_mutex_unlock(struct rt_mutex *lock); | 137 | extern void rt_mutex_unlock(struct rt_mutex *lock) |
| 138 | __releases(lock); | ||
| 131 | 139 | ||
| 132 | #endif | 140 | #endif |
| @@ -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 | ||