LCOV - code coverage report
Current view: top level - kernel/locking - mutex-debug.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 41 41 100.0 %
Date: 2021-04-22 12:43:58 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  * kernel/mutex-debug.c
       3             :  *
       4             :  * Debugging code for mutexes
       5             :  *
       6             :  * Started by Ingo Molnar:
       7             :  *
       8             :  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
       9             :  *
      10             :  * lock debugging, locking tree, deadlock detection started by:
      11             :  *
      12             :  *  Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey
      13             :  *  Released under the General Public License (GPL).
      14             :  */
      15             : #include <linux/mutex.h>
      16             : #include <linux/delay.h>
      17             : #include <linux/export.h>
      18             : #include <linux/poison.h>
      19             : #include <linux/sched.h>
      20             : #include <linux/spinlock.h>
      21             : #include <linux/kallsyms.h>
      22             : #include <linux/interrupt.h>
      23             : #include <linux/debug_locks.h>
      24             : 
      25             : #include "mutex-debug.h"
      26             : 
      27             : /*
      28             :  * Must be called with lock->wait_lock held.
      29             :  */
      30          23 : void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter)
      31             : {
      32          23 :         memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter));
      33          23 :         waiter->magic = waiter;
      34          23 :         INIT_LIST_HEAD(&waiter->list);
      35          23 : }
      36             : 
      37         154 : void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter)
      38             : {
      39         308 :         lockdep_assert_held(&lock->wait_lock);
      40         154 :         DEBUG_LOCKS_WARN_ON(list_empty(&lock->wait_list));
      41         154 :         DEBUG_LOCKS_WARN_ON(waiter->magic != waiter);
      42         154 :         DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
      43         154 : }
      44             : 
      45          23 : void debug_mutex_free_waiter(struct mutex_waiter *waiter)
      46             : {
      47          23 :         DEBUG_LOCKS_WARN_ON(!list_empty(&waiter->list));
      48          23 :         memset(waiter, MUTEX_DEBUG_FREE, sizeof(*waiter));
      49          23 : }
      50             : 
      51          23 : void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
      52             :                             struct task_struct *task)
      53             : {
      54          46 :         lockdep_assert_held(&lock->wait_lock);
      55             : 
      56             :         /* Mark the current thread as blocked on the lock: */
      57          23 :         task->blocked_on = waiter;
      58          23 : }
      59             : 
      60          23 : void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
      61             :                          struct task_struct *task)
      62             : {
      63          23 :         DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
      64          23 :         DEBUG_LOCKS_WARN_ON(waiter->task != task);
      65          23 :         DEBUG_LOCKS_WARN_ON(task->blocked_on != waiter);
      66          23 :         task->blocked_on = NULL;
      67             : 
      68          23 :         list_del_init(&waiter->list);
      69          23 :         waiter->task = NULL;
      70          23 : }
      71             : 
      72         154 : void debug_mutex_unlock(struct mutex *lock)
      73             : {
      74         154 :         if (likely(debug_locks)) {
      75         154 :                 DEBUG_LOCKS_WARN_ON(lock->magic != lock);
      76         154 :                 DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
      77             :         }
      78         154 : }
      79             : 
      80       75540 : void debug_mutex_init(struct mutex *lock, const char *name,
      81             :                       struct lock_class_key *key)
      82             : {
      83             : #ifdef CONFIG_DEBUG_LOCK_ALLOC
      84             :         /*
      85             :          * Make sure we are not reinitializing a held lock:
      86             :          */
      87       75540 :         debug_check_no_locks_freed((void *)lock, sizeof(*lock));
      88       75541 :         lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP);
      89             : #endif
      90       75542 :         lock->magic = lock;
      91       75542 : }
      92             : 
      93             : /***
      94             :  * mutex_destroy - mark a mutex unusable
      95             :  * @lock: the mutex to be destroyed
      96             :  *
      97             :  * This function marks the mutex uninitialized, and any subsequent
      98             :  * use of the mutex is forbidden. The mutex must not be locked when
      99             :  * this function is called.
     100             :  */
     101          68 : void mutex_destroy(struct mutex *lock)
     102             : {
     103          68 :         DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock));
     104          68 :         lock->magic = NULL;
     105          68 : }
     106             : 
     107             : EXPORT_SYMBOL_GPL(mutex_destroy);

Generated by: LCOV version 1.14