utmutex.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /*******************************************************************************
  3. *
  4. * Module Name: utmutex - local mutex support
  5. *
  6. ******************************************************************************/
  7. #include <acpi/acpi.h>
  8. #include "accommon.h"
  9. #define _COMPONENT ACPI_UTILITIES
  10. ACPI_MODULE_NAME("utmutex")
  11. /* Local prototypes */
  12. static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
  13. static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
  14. /*******************************************************************************
  15. *
  16. * FUNCTION: acpi_ut_mutex_initialize
  17. *
  18. * PARAMETERS: None.
  19. *
  20. * RETURN: Status
  21. *
  22. * DESCRIPTION: Create the system mutex objects. This includes mutexes,
  23. * spin locks, and reader/writer locks.
  24. *
  25. ******************************************************************************/
  26. acpi_status acpi_ut_mutex_initialize(void)
  27. {
  28. u32 i;
  29. acpi_status status;
  30. ACPI_FUNCTION_TRACE(ut_mutex_initialize);
  31. /* Create each of the predefined mutex objects */
  32. for (i = 0; i < ACPI_NUM_MUTEX; i++) {
  33. status = acpi_ut_create_mutex(i);
  34. if (ACPI_FAILURE(status)) {
  35. return_ACPI_STATUS(status);
  36. }
  37. }
  38. /* Create the spinlocks for use at interrupt level or for speed */
  39. status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
  40. if (ACPI_FAILURE (status)) {
  41. return_ACPI_STATUS (status);
  42. }
  43. status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
  44. if (ACPI_FAILURE (status)) {
  45. return_ACPI_STATUS (status);
  46. }
  47. status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
  48. if (ACPI_FAILURE(status)) {
  49. return_ACPI_STATUS(status);
  50. }
  51. /* Mutex for _OSI support */
  52. status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
  53. if (ACPI_FAILURE(status)) {
  54. return_ACPI_STATUS(status);
  55. }
  56. /* Create the reader/writer lock for namespace access */
  57. status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
  58. if (ACPI_FAILURE(status)) {
  59. return_ACPI_STATUS(status);
  60. }
  61. return_ACPI_STATUS(status);
  62. }
  63. /*******************************************************************************
  64. *
  65. * FUNCTION: acpi_ut_mutex_terminate
  66. *
  67. * PARAMETERS: None.
  68. *
  69. * RETURN: None.
  70. *
  71. * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
  72. * spin locks, and reader/writer locks.
  73. *
  74. ******************************************************************************/
  75. void acpi_ut_mutex_terminate(void)
  76. {
  77. u32 i;
  78. ACPI_FUNCTION_TRACE(ut_mutex_terminate);
  79. /* Delete each predefined mutex object */
  80. for (i = 0; i < ACPI_NUM_MUTEX; i++) {
  81. acpi_ut_delete_mutex(i);
  82. }
  83. acpi_os_delete_mutex(acpi_gbl_osi_mutex);
  84. /* Delete the spinlocks */
  85. acpi_os_delete_lock(acpi_gbl_gpe_lock);
  86. acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
  87. acpi_os_delete_lock(acpi_gbl_reference_count_lock);
  88. /* Delete the reader/writer lock */
  89. acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
  90. return_VOID;
  91. }
  92. /*******************************************************************************
  93. *
  94. * FUNCTION: acpi_ut_create_mutex
  95. *
  96. * PARAMETERS: mutex_ID - ID of the mutex to be created
  97. *
  98. * RETURN: Status
  99. *
  100. * DESCRIPTION: Create a mutex object.
  101. *
  102. ******************************************************************************/
  103. static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
  104. {
  105. acpi_status status = AE_OK;
  106. ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
  107. if (!acpi_gbl_mutex_info[mutex_id].mutex) {
  108. status =
  109. acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
  110. acpi_gbl_mutex_info[mutex_id].thread_id =
  111. ACPI_MUTEX_NOT_ACQUIRED;
  112. acpi_gbl_mutex_info[mutex_id].use_count = 0;
  113. }
  114. return_ACPI_STATUS(status);
  115. }
  116. /*******************************************************************************
  117. *
  118. * FUNCTION: acpi_ut_delete_mutex
  119. *
  120. * PARAMETERS: mutex_ID - ID of the mutex to be deleted
  121. *
  122. * RETURN: Status
  123. *
  124. * DESCRIPTION: Delete a mutex object.
  125. *
  126. ******************************************************************************/
  127. static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
  128. {
  129. ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
  130. acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
  131. acpi_gbl_mutex_info[mutex_id].mutex = NULL;
  132. acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
  133. return_VOID;
  134. }
  135. /*******************************************************************************
  136. *
  137. * FUNCTION: acpi_ut_acquire_mutex
  138. *
  139. * PARAMETERS: mutex_ID - ID of the mutex to be acquired
  140. *
  141. * RETURN: Status
  142. *
  143. * DESCRIPTION: Acquire a mutex object.
  144. *
  145. ******************************************************************************/
  146. acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
  147. {
  148. acpi_status status;
  149. acpi_thread_id this_thread_id;
  150. ACPI_FUNCTION_NAME(ut_acquire_mutex);
  151. if (mutex_id > ACPI_MAX_MUTEX) {
  152. return (AE_BAD_PARAMETER);
  153. }
  154. this_thread_id = acpi_os_get_thread_id();
  155. #ifdef ACPI_MUTEX_DEBUG
  156. {
  157. u32 i;
  158. /*
  159. * Mutex debug code, for internal debugging only.
  160. *
  161. * Deadlock prevention. Check if this thread owns any mutexes of value
  162. * greater than or equal to this one. If so, the thread has violated
  163. * the mutex ordering rule. This indicates a coding error somewhere in
  164. * the ACPI subsystem code.
  165. */
  166. for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
  167. if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
  168. if (i == mutex_id) {
  169. ACPI_ERROR((AE_INFO,
  170. "Mutex [%s] already acquired by this thread [%u]",
  171. acpi_ut_get_mutex_name
  172. (mutex_id),
  173. (u32)this_thread_id));
  174. return (AE_ALREADY_ACQUIRED);
  175. }
  176. ACPI_ERROR((AE_INFO,
  177. "Invalid acquire order: Thread %u owns [%s], wants [%s]",
  178. (u32)this_thread_id,
  179. acpi_ut_get_mutex_name(i),
  180. acpi_ut_get_mutex_name(mutex_id)));
  181. return (AE_ACQUIRE_DEADLOCK);
  182. }
  183. }
  184. }
  185. #endif
  186. ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
  187. "Thread %u attempting to acquire Mutex [%s]\n",
  188. (u32)this_thread_id,
  189. acpi_ut_get_mutex_name(mutex_id)));
  190. status =
  191. acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
  192. ACPI_WAIT_FOREVER);
  193. if (ACPI_SUCCESS(status)) {
  194. ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
  195. "Thread %u acquired Mutex [%s]\n",
  196. (u32)this_thread_id,
  197. acpi_ut_get_mutex_name(mutex_id)));
  198. acpi_gbl_mutex_info[mutex_id].use_count++;
  199. acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
  200. } else {
  201. ACPI_EXCEPTION((AE_INFO, status,
  202. "Thread %u could not acquire Mutex [%s] (0x%X)",
  203. (u32)this_thread_id,
  204. acpi_ut_get_mutex_name(mutex_id), mutex_id));
  205. }
  206. return (status);
  207. }
  208. /*******************************************************************************
  209. *
  210. * FUNCTION: acpi_ut_release_mutex
  211. *
  212. * PARAMETERS: mutex_ID - ID of the mutex to be released
  213. *
  214. * RETURN: Status
  215. *
  216. * DESCRIPTION: Release a mutex object.
  217. *
  218. ******************************************************************************/
  219. acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
  220. {
  221. ACPI_FUNCTION_NAME(ut_release_mutex);
  222. ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
  223. (u32)acpi_os_get_thread_id(),
  224. acpi_ut_get_mutex_name(mutex_id)));
  225. if (mutex_id > ACPI_MAX_MUTEX) {
  226. return (AE_BAD_PARAMETER);
  227. }
  228. /*
  229. * Mutex must be acquired in order to release it!
  230. */
  231. if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
  232. ACPI_ERROR((AE_INFO,
  233. "Mutex [%s] (0x%X) is not acquired, cannot release",
  234. acpi_ut_get_mutex_name(mutex_id), mutex_id));
  235. return (AE_NOT_ACQUIRED);
  236. }
  237. #ifdef ACPI_MUTEX_DEBUG
  238. {
  239. u32 i;
  240. /*
  241. * Mutex debug code, for internal debugging only.
  242. *
  243. * Deadlock prevention. Check if this thread owns any mutexes of value
  244. * greater than this one. If so, the thread has violated the mutex
  245. * ordering rule. This indicates a coding error somewhere in
  246. * the ACPI subsystem code.
  247. */
  248. for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
  249. if (acpi_gbl_mutex_info[i].thread_id ==
  250. acpi_os_get_thread_id()) {
  251. if (i == mutex_id) {
  252. continue;
  253. }
  254. ACPI_ERROR((AE_INFO,
  255. "Invalid release order: owns [%s], releasing [%s]",
  256. acpi_ut_get_mutex_name(i),
  257. acpi_ut_get_mutex_name(mutex_id)));
  258. return (AE_RELEASE_DEADLOCK);
  259. }
  260. }
  261. }
  262. #endif
  263. /* Mark unlocked FIRST */
  264. acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
  265. acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
  266. return (AE_OK);
  267. }