mutex-debug.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Mutexes: blocking mutual exclusion locks
  3. *
  4. * started by Ingo Molnar:
  5. *
  6. * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  7. *
  8. * This file contains mutex debugging related internal declarations,
  9. * prototypes and inline functions, for the CONFIG_DEBUG_MUTEXES case.
  10. * More details are in kernel/mutex-debug.c.
  11. */
  12. extern spinlock_t debug_mutex_lock;
  13. extern struct list_head debug_mutex_held_locks;
  14. extern int debug_mutex_on;
  15. /*
  16. * In the debug case we carry the caller's instruction pointer into
  17. * other functions, but we dont want the function argument overhead
  18. * in the nondebug case - hence these macros:
  19. */
  20. #define __IP_DECL__ , unsigned long ip
  21. #define __IP__ , ip
  22. #define __RET_IP__ , (unsigned long)__builtin_return_address(0)
  23. /*
  24. * This must be called with lock->wait_lock held.
  25. */
  26. extern void debug_mutex_set_owner(struct mutex *lock,
  27. struct thread_info *new_owner __IP_DECL__);
  28. static inline void debug_mutex_clear_owner(struct mutex *lock)
  29. {
  30. lock->owner = NULL;
  31. }
  32. extern void debug_mutex_init_waiter(struct mutex_waiter *waiter);
  33. extern void debug_mutex_wake_waiter(struct mutex *lock,
  34. struct mutex_waiter *waiter);
  35. extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);
  36. extern void debug_mutex_add_waiter(struct mutex *lock,
  37. struct mutex_waiter *waiter,
  38. struct thread_info *ti __IP_DECL__);
  39. extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
  40. struct thread_info *ti);
  41. extern void debug_mutex_unlock(struct mutex *lock);
  42. extern void debug_mutex_init(struct mutex *lock, const char *name);
  43. #define debug_spin_lock(lock) \
  44. do { \
  45. local_irq_disable(); \
  46. if (debug_mutex_on) \
  47. spin_lock(lock); \
  48. } while (0)
  49. #define debug_spin_unlock(lock) \
  50. do { \
  51. if (debug_mutex_on) \
  52. spin_unlock(lock); \
  53. local_irq_enable(); \
  54. preempt_check_resched(); \
  55. } while (0)
  56. #define debug_spin_lock_save(lock, flags) \
  57. do { \
  58. local_irq_save(flags); \
  59. if (debug_mutex_on) \
  60. spin_lock(lock); \
  61. } while (0)
  62. #define debug_spin_lock_restore(lock, flags) \
  63. do { \
  64. if (debug_mutex_on) \
  65. spin_unlock(lock); \
  66. local_irq_restore(flags); \
  67. preempt_check_resched(); \
  68. } while (0)
  69. #define spin_lock_mutex(lock) \
  70. do { \
  71. struct mutex *l = container_of(lock, struct mutex, wait_lock); \
  72. \
  73. DEBUG_WARN_ON(in_interrupt()); \
  74. debug_spin_lock(&debug_mutex_lock); \
  75. spin_lock(lock); \
  76. DEBUG_WARN_ON(l->magic != l); \
  77. } while (0)
  78. #define spin_unlock_mutex(lock) \
  79. do { \
  80. spin_unlock(lock); \
  81. debug_spin_unlock(&debug_mutex_lock); \
  82. } while (0)
  83. #define DEBUG_OFF() \
  84. do { \
  85. if (debug_mutex_on) { \
  86. debug_mutex_on = 0; \
  87. console_verbose(); \
  88. if (spin_is_locked(&debug_mutex_lock)) \
  89. spin_unlock(&debug_mutex_lock); \
  90. } \
  91. } while (0)
  92. #define DEBUG_BUG() \
  93. do { \
  94. if (debug_mutex_on) { \
  95. DEBUG_OFF(); \
  96. BUG(); \
  97. } \
  98. } while (0)
  99. #define DEBUG_WARN_ON(c) \
  100. do { \
  101. if (unlikely(c && debug_mutex_on)) { \
  102. DEBUG_OFF(); \
  103. WARN_ON(1); \
  104. } \
  105. } while (0)
  106. # define DEBUG_BUG_ON(c) \
  107. do { \
  108. if (unlikely(c)) \
  109. DEBUG_BUG(); \
  110. } while (0)
  111. #ifdef CONFIG_SMP
  112. # define SMP_DEBUG_WARN_ON(c) DEBUG_WARN_ON(c)
  113. # define SMP_DEBUG_BUG_ON(c) DEBUG_BUG_ON(c)
  114. #else
  115. # define SMP_DEBUG_WARN_ON(c) do { } while (0)
  116. # define SMP_DEBUG_BUG_ON(c) do { } while (0)
  117. #endif