void __sched mutex_unlock(struct mutex *lock) { #ifndef CONFIG_DEBUG_MUTEXES mutex_clear_owner(lock); #endif __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath); }
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); mutex_clear_owner(lock); debug_mutex_init(lock, name, key); }
void debug_mutex_unlock(struct mutex *lock) { if (unlikely(!debug_locks)) return; DEBUG_LOCKS_WARN_ON(lock->magic != lock); DEBUG_LOCKS_WARN_ON(lock->owner != current_thread_info()); DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); mutex_clear_owner(lock); }
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); mutex_clear_owner(lock); #ifdef CONFIG_MUTEX_SPIN_ON_OWNER lock->spin_mlock = NULL; #endif debug_mutex_init(lock, name, key); }
/** * mutex_unlock - release the mutex * @lock: the mutex to be released * * Unlock a mutex that has been locked by this task previously. * * This function must not be used in interrupt context. Unlocking * of a not locked mutex is not allowed. * * This function is similar to (but not equivalent to) up(). */ void __sched mutex_unlock(struct mutex *lock) { /* * The unlocking fastpath is the 0->1 transition from 'locked' * into 'unlocked' state: */ #ifndef CONFIG_DEBUG_MUTEXES /* * When debugging is enabled we must not clear the owner before time, * the slow path will always be taken, and that clears the owner field * after verifying that it was indeed current. */ mutex_clear_owner(lock); #endif __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath); }
void debug_mutex_unlock(struct mutex *lock) { // if (unlikely(!debug_locks)) // return; if(DEBUG_LOCKS_WARN_ON(lock->magic != lock)){ printk("[MUTEX WARN!!] bad lock magic:%p\n", lock->magic); } if(DEBUG_LOCKS_WARN_ON(lock->owner != current)){ if(lock->owner != NULL){ printk("[MUTEX WARN!!] releasing mutex which is hold by another process, %p\n", lock->owner); printk("[MUTEX WARN!!] current process[%d:%s] is trying to release lock\n But it should be released by lock owner-process[%d:%s]\n", current->pid, current->comm, lock->owner->pid, lock->owner->comm); }else printk("\n[MUTEX WARN!!] imbalanced unlock\n"); } if(DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next)){ printk("[MUTEX WARN!!] wait_list both empty in prev and next \n"); } mutex_clear_owner(lock); }
void debug_mutex_unlock(struct mutex *lock) { if (likely(debug_locks)) { DEBUG_LOCKS_WARN_ON(lock->magic != lock); if (!lock->owner) DEBUG_LOCKS_WARN_ON(!lock->owner); else DEBUG_LOCKS_WARN_ON(lock->owner != current); DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); } /* * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug * mutexes so that we can do it here after we've verified state. */ mutex_clear_owner(lock); atomic_set(&lock->count, 1); }