diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2007-10-11 16:11:12 -0400 |
|---|---|---|
| committer | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2007-10-11 16:11:12 -0400 |
| commit | e4564f79d4b6923da7360df4b24a48cc2d4160de (patch) | |
| tree | 393a5fcc5efe94ae669b8ff21f36db2726f5f51d /kernel | |
| parent | 3aa416b07f0adf01c090baab26fb70c35ec17623 (diff) | |
lockdep: fixup mutex annotations
The fancy mutex_lock fastpath has too many indirections to track the caller
hence all contentions are perceived to come from mutex_lock().
Avoid this by explicitly not using the fastpath code (it was disabled already
anyway).
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/mutex.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/kernel/mutex.c b/kernel/mutex.c index 691b86564d..d7fe50cc55 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c | |||
| @@ -51,6 +51,7 @@ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) | |||
| 51 | 51 | ||
| 52 | EXPORT_SYMBOL(__mutex_init); | 52 | EXPORT_SYMBOL(__mutex_init); |
| 53 | 53 | ||
| 54 | #ifndef CONFIG_DEBUG_LOCK_ALLOC | ||
| 54 | /* | 55 | /* |
| 55 | * We split the mutex lock/unlock logic into separate fastpath and | 56 | * We split the mutex lock/unlock logic into separate fastpath and |
| 56 | * slowpath functions, to reduce the register pressure on the fastpath. | 57 | * slowpath functions, to reduce the register pressure on the fastpath. |
| @@ -92,6 +93,7 @@ void inline fastcall __sched mutex_lock(struct mutex *lock) | |||
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | EXPORT_SYMBOL(mutex_lock); | 95 | EXPORT_SYMBOL(mutex_lock); |
| 96 | #endif | ||
| 95 | 97 | ||
| 96 | static void fastcall noinline __sched | 98 | static void fastcall noinline __sched |
| 97 | __mutex_unlock_slowpath(atomic_t *lock_count); | 99 | __mutex_unlock_slowpath(atomic_t *lock_count); |
| @@ -122,7 +124,8 @@ EXPORT_SYMBOL(mutex_unlock); | |||
| 122 | * Lock a mutex (possibly interruptible), slowpath: | 124 | * Lock a mutex (possibly interruptible), slowpath: |
| 123 | */ | 125 | */ |
| 124 | static inline int __sched | 126 | static inline int __sched |
| 125 | __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass) | 127 | __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, |
| 128 | unsigned long ip) | ||
| 126 | { | 129 | { |
| 127 | struct task_struct *task = current; | 130 | struct task_struct *task = current; |
| 128 | struct mutex_waiter waiter; | 131 | struct mutex_waiter waiter; |
| @@ -132,7 +135,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass) | |||
| 132 | spin_lock_mutex(&lock->wait_lock, flags); | 135 | spin_lock_mutex(&lock->wait_lock, flags); |
| 133 | 136 | ||
| 134 | debug_mutex_lock_common(lock, &waiter); | 137 | debug_mutex_lock_common(lock, &waiter); |
| 135 | mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_); | 138 | mutex_acquire(&lock->dep_map, subclass, 0, ip); |
| 136 | debug_mutex_add_waiter(lock, &waiter, task_thread_info(task)); | 139 | debug_mutex_add_waiter(lock, &waiter, task_thread_info(task)); |
| 137 | 140 | ||
| 138 | /* add waiting tasks to the end of the waitqueue (FIFO): */ | 141 | /* add waiting tasks to the end of the waitqueue (FIFO): */ |
| @@ -143,7 +146,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass) | |||
| 143 | if (old_val == 1) | 146 | if (old_val == 1) |
| 144 | goto done; | 147 | goto done; |
| 145 | 148 | ||
| 146 | lock_contended(&lock->dep_map, _RET_IP_); | 149 | lock_contended(&lock->dep_map, ip); |
| 147 | 150 | ||
| 148 | for (;;) { | 151 | for (;;) { |
| 149 | /* | 152 | /* |
| @@ -166,7 +169,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass) | |||
| 166 | if (unlikely(state == TASK_INTERRUPTIBLE && | 169 | if (unlikely(state == TASK_INTERRUPTIBLE && |
| 167 | signal_pending(task))) { | 170 | signal_pending(task))) { |
| 168 | mutex_remove_waiter(lock, &waiter, task_thread_info(task)); | 171 | mutex_remove_waiter(lock, &waiter, task_thread_info(task)); |
| 169 | mutex_release(&lock->dep_map, 1, _RET_IP_); | 172 | mutex_release(&lock->dep_map, 1, ip); |
| 170 | spin_unlock_mutex(&lock->wait_lock, flags); | 173 | spin_unlock_mutex(&lock->wait_lock, flags); |
| 171 | 174 | ||
| 172 | debug_mutex_free_waiter(&waiter); | 175 | debug_mutex_free_waiter(&waiter); |
| @@ -197,20 +200,12 @@ done: | |||
| 197 | return 0; | 200 | return 0; |
| 198 | } | 201 | } |
| 199 | 202 | ||
| 200 | static void fastcall noinline __sched | ||
| 201 | __mutex_lock_slowpath(atomic_t *lock_count) | ||
| 202 | { | ||
| 203 | struct mutex *lock = container_of(lock_count, struct mutex, count); | ||
| 204 | |||
| 205 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0); | ||
| 206 | } | ||
| 207 | |||
| 208 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 203 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 209 | void __sched | 204 | void __sched |
| 210 | mutex_lock_nested(struct mutex *lock, unsigned int subclass) | 205 | mutex_lock_nested(struct mutex *lock, unsigned int subclass) |
| 211 | { | 206 | { |
| 212 | might_sleep(); | 207 | might_sleep(); |
| 213 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass); | 208 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass, _RET_IP_); |
| 214 | } | 209 | } |
| 215 | 210 | ||
| 216 | EXPORT_SYMBOL_GPL(mutex_lock_nested); | 211 | EXPORT_SYMBOL_GPL(mutex_lock_nested); |
| @@ -219,7 +214,7 @@ int __sched | |||
| 219 | mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass) | 214 | mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass) |
| 220 | { | 215 | { |
| 221 | might_sleep(); | 216 | might_sleep(); |
| 222 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, subclass); | 217 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, subclass, _RET_IP_); |
| 223 | } | 218 | } |
| 224 | 219 | ||
| 225 | EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested); | 220 | EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested); |
| @@ -271,6 +266,7 @@ __mutex_unlock_slowpath(atomic_t *lock_count) | |||
| 271 | __mutex_unlock_common_slowpath(lock_count, 1); | 266 | __mutex_unlock_common_slowpath(lock_count, 1); |
| 272 | } | 267 | } |
| 273 | 268 | ||
| 269 | #ifndef CONFIG_DEBUG_LOCK_ALLOC | ||
| 274 | /* | 270 | /* |
| 275 | * Here come the less common (and hence less performance-critical) APIs: | 271 | * Here come the less common (and hence less performance-critical) APIs: |
| 276 | * mutex_lock_interruptible() and mutex_trylock(). | 272 | * mutex_lock_interruptible() and mutex_trylock(). |
| @@ -298,13 +294,22 @@ int fastcall __sched mutex_lock_interruptible(struct mutex *lock) | |||
| 298 | 294 | ||
| 299 | EXPORT_SYMBOL(mutex_lock_interruptible); | 295 | EXPORT_SYMBOL(mutex_lock_interruptible); |
| 300 | 296 | ||
| 297 | static void fastcall noinline __sched | ||
| 298 | __mutex_lock_slowpath(atomic_t *lock_count) | ||
| 299 | { | ||
| 300 | struct mutex *lock = container_of(lock_count, struct mutex, count); | ||
| 301 | |||
| 302 | __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, _RET_IP_); | ||
| 303 | } | ||
| 304 | |||
| 301 | static int fastcall noinline __sched | 305 | static int fastcall noinline __sched |
| 302 | __mutex_lock_interruptible_slowpath(atomic_t *lock_count) | 306 | __mutex_lock_interruptible_slowpath(atomic_t *lock_count) |
| 303 | { | 307 | { |
| 304 | struct mutex *lock = container_of(lock_count, struct mutex, count); | 308 | struct mutex *lock = container_of(lock_count, struct mutex, count); |
| 305 | 309 | ||
| 306 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0); | 310 | return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, _RET_IP_); |
| 307 | } | 311 | } |
| 312 | #endif | ||
| 308 | 313 | ||
| 309 | /* | 314 | /* |
| 310 | * Spinlock based trylock, we take the spinlock and check whether we | 315 | * Spinlock based trylock, we take the spinlock and check whether we |
