diff options
Diffstat (limited to 'kernel/mutex.c')
| -rw-r--r-- | kernel/mutex.c | 28 | 
1 files changed, 22 insertions, 6 deletions
diff --git a/kernel/mutex.c b/kernel/mutex.c index 43a50c18701..8c71cf72a49 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -39,13 +39,14 @@   *   * It is not allowed to initialize an already locked mutex.   */ -__always_inline void fastcall __mutex_init(struct mutex *lock, const char *name) +void +__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)  {  	atomic_set(&lock->count, 1);  	spin_lock_init(&lock->wait_lock);  	INIT_LIST_HEAD(&lock->wait_list); -	debug_mutex_init(lock, name); +	debug_mutex_init(lock, name, key);  }  EXPORT_SYMBOL(__mutex_init); @@ -131,6 +132,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass)  	spin_lock_mutex(&lock->wait_lock, flags);  	debug_mutex_lock_common(lock, &waiter); +	mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_);  	debug_mutex_add_waiter(lock, &waiter, task->thread_info);  	/* add waiting tasks to the end of the waitqueue (FIFO): */ @@ -158,6 +160,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass)  		if (unlikely(state == TASK_INTERRUPTIBLE &&  						signal_pending(task))) {  			mutex_remove_waiter(lock, &waiter, task->thread_info); +			mutex_release(&lock->dep_map, 1, _RET_IP_);  			spin_unlock_mutex(&lock->wait_lock, flags);  			debug_mutex_free_waiter(&waiter); @@ -194,16 +197,28 @@ __mutex_lock_slowpath(atomic_t *lock_count)  	__mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0);  } +#ifdef CONFIG_DEBUG_LOCK_ALLOC +void __sched +mutex_lock_nested(struct mutex *lock, unsigned int subclass) +{ +	might_sleep(); +	__mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass); +} + +EXPORT_SYMBOL_GPL(mutex_lock_nested); +#endif +  /*   * Release the lock, slowpath:   */  static fastcall inline void -__mutex_unlock_common_slowpath(atomic_t *lock_count) +__mutex_unlock_common_slowpath(atomic_t *lock_count, int nested)  {  	struct mutex *lock = container_of(lock_count, struct mutex, count);  	unsigned long flags;  	spin_lock_mutex(&lock->wait_lock, flags); +	mutex_release(&lock->dep_map, nested, _RET_IP_);  	debug_mutex_unlock(lock);  	/* @@ -236,7 +251,7 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count)  static fastcall noinline void  __mutex_unlock_slowpath(atomic_t *lock_count)  { -	__mutex_unlock_common_slowpath(lock_count); +	__mutex_unlock_common_slowpath(lock_count, 1);  }  /* @@ -287,9 +302,10 @@ static inline int __mutex_trylock_slowpath(atomic_t *lock_count)  	spin_lock_mutex(&lock->wait_lock, flags);  	prev = atomic_xchg(&lock->count, -1); -	if (likely(prev == 1)) +	if (likely(prev == 1)) {  		debug_mutex_set_owner(lock, current_thread_info()); - +		mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); +	}  	/* Set it back to 0 if there are no waiters: */  	if (likely(list_empty(&lock->wait_list)))  		atomic_set(&lock->count, 0);  |