blob: 2e465e6a0ab65a30f462a8aedff78a54d9e6df99 [file] [log] [blame]
Erik Schmauss95857632018-03-14 16:13:07 -07001// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
Robert Moore73459f72005-06-24 00:00:00 -04002/*******************************************************************************
3 *
4 * Module Name: utmutex - local mutex support
5 *
6 ******************************************************************************/
7
Robert Moore73459f72005-06-24 00:00:00 -04008#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -05009#include "accommon.h"
Robert Moore73459f72005-06-24 00:00:00 -040010
11#define _COMPONENT ACPI_UTILITIES
Len Brown4be44fc2005-08-05 00:44:28 -040012ACPI_MODULE_NAME("utmutex")
Robert Moore73459f72005-06-24 00:00:00 -040013
14/* Local prototypes */
Len Brown4be44fc2005-08-05 00:44:28 -040015static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
Robert Moore73459f72005-06-24 00:00:00 -040016
Bob Moore2147d3f2010-01-21 09:08:31 +080017static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
Robert Moore73459f72005-06-24 00:00:00 -040018
19/*******************************************************************************
20 *
21 * FUNCTION: acpi_ut_mutex_initialize
22 *
23 * PARAMETERS: None.
24 *
25 * RETURN: Status
26 *
Bob Moore8a335a232009-03-09 16:31:04 +080027 * DESCRIPTION: Create the system mutex objects. This includes mutexes,
28 * spin locks, and reader/writer locks.
Robert Moore73459f72005-06-24 00:00:00 -040029 *
30 ******************************************************************************/
31
Len Brown4be44fc2005-08-05 00:44:28 -040032acpi_status acpi_ut_mutex_initialize(void)
Robert Moore73459f72005-06-24 00:00:00 -040033{
Len Brown4be44fc2005-08-05 00:44:28 -040034 u32 i;
35 acpi_status status;
Robert Moore73459f72005-06-24 00:00:00 -040036
Bob Mooreb229cf92006-04-21 17:15:00 -040037 ACPI_FUNCTION_TRACE(ut_mutex_initialize);
Robert Moore73459f72005-06-24 00:00:00 -040038
Bob Moore8a335a232009-03-09 16:31:04 +080039 /* Create each of the predefined mutex objects */
40
Bob Moore4c90ece2006-06-08 16:29:00 -040041 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -040042 status = acpi_ut_create_mutex(i);
43 if (ACPI_FAILURE(status)) {
44 return_ACPI_STATUS(status);
Robert Moore73459f72005-06-24 00:00:00 -040045 }
46 }
47
Bob Moore58892c92013-04-12 00:25:41 +000048 /* Create the spinlocks for use at interrupt level or for speed */
Bob Moore4c90ece2006-06-08 16:29:00 -040049
Lin Ming3854c8e2011-03-23 17:26:35 +080050 status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
51 if (ACPI_FAILURE (status)) {
52 return_ACPI_STATUS (status);
53 }
54
Steven Rostedtc57c0ad2018-04-25 16:28:27 +020055 status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
Lin Ming3854c8e2011-03-23 17:26:35 +080056 if (ACPI_FAILURE (status)) {
57 return_ACPI_STATUS (status);
58 }
59
Bob Moore58892c92013-04-12 00:25:41 +000060 status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
61 if (ACPI_FAILURE(status)) {
62 return_ACPI_STATUS(status);
63 }
64
Lin Mingb0ed7a92010-08-06 09:35:51 +080065 /* Mutex for _OSI support */
Bob Moore58892c92013-04-12 00:25:41 +000066
Lin Mingb0ed7a92010-08-06 09:35:51 +080067 status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
68 if (ACPI_FAILURE(status)) {
69 return_ACPI_STATUS(status);
70 }
71
Bob Moore8a335a232009-03-09 16:31:04 +080072 /* Create the reader/writer lock for namespace access */
73
74 status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
Bob Moorecd64bbf2015-10-19 10:24:45 +080075 if (ACPI_FAILURE(status)) {
76 return_ACPI_STATUS(status);
77 }
Bob Moorecd64bbf2015-10-19 10:24:45 +080078
Len Brown4be44fc2005-08-05 00:44:28 -040079 return_ACPI_STATUS(status);
Robert Moore73459f72005-06-24 00:00:00 -040080}
81
Robert Moore73459f72005-06-24 00:00:00 -040082/*******************************************************************************
83 *
84 * FUNCTION: acpi_ut_mutex_terminate
85 *
86 * PARAMETERS: None.
87 *
88 * RETURN: None.
89 *
Bob Moore8a335a232009-03-09 16:31:04 +080090 * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
91 * spin locks, and reader/writer locks.
Robert Moore73459f72005-06-24 00:00:00 -040092 *
93 ******************************************************************************/
94
Len Brown4be44fc2005-08-05 00:44:28 -040095void acpi_ut_mutex_terminate(void)
Robert Moore73459f72005-06-24 00:00:00 -040096{
Len Brown4be44fc2005-08-05 00:44:28 -040097 u32 i;
Robert Moore73459f72005-06-24 00:00:00 -040098
Bob Mooreb229cf92006-04-21 17:15:00 -040099 ACPI_FUNCTION_TRACE(ut_mutex_terminate);
Robert Moore73459f72005-06-24 00:00:00 -0400100
Bob Moore8a335a232009-03-09 16:31:04 +0800101 /* Delete each predefined mutex object */
102
Bob Moore4c90ece2006-06-08 16:29:00 -0400103 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
Bob Moore2147d3f2010-01-21 09:08:31 +0800104 acpi_ut_delete_mutex(i);
Robert Moore73459f72005-06-24 00:00:00 -0400105 }
106
Lin Mingb0ed7a92010-08-06 09:35:51 +0800107 acpi_os_delete_mutex(acpi_gbl_osi_mutex);
108
Bob Moore4c90ece2006-06-08 16:29:00 -0400109 /* Delete the spinlocks */
110
Len Brown4be44fc2005-08-05 00:44:28 -0400111 acpi_os_delete_lock(acpi_gbl_gpe_lock);
Steven Rostedtc57c0ad2018-04-25 16:28:27 +0200112 acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
Bob Moore58892c92013-04-12 00:25:41 +0000113 acpi_os_delete_lock(acpi_gbl_reference_count_lock);
Bob Moore8a335a232009-03-09 16:31:04 +0800114
115 /* Delete the reader/writer lock */
116
117 acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
Robert Moore73459f72005-06-24 00:00:00 -0400118 return_VOID;
119}
120
Robert Moore73459f72005-06-24 00:00:00 -0400121/*******************************************************************************
122 *
123 * FUNCTION: acpi_ut_create_mutex
124 *
Bob Mooreba494be2012-07-12 09:40:10 +0800125 * PARAMETERS: mutex_ID - ID of the mutex to be created
Robert Moore73459f72005-06-24 00:00:00 -0400126 *
127 * RETURN: Status
128 *
129 * DESCRIPTION: Create a mutex object.
130 *
131 ******************************************************************************/
132
Len Brown4be44fc2005-08-05 00:44:28 -0400133static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
Robert Moore73459f72005-06-24 00:00:00 -0400134{
Len Brown4be44fc2005-08-05 00:44:28 -0400135 acpi_status status = AE_OK;
Robert Moore73459f72005-06-24 00:00:00 -0400136
Bob Mooreb229cf92006-04-21 17:15:00 -0400137 ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
Robert Moore73459f72005-06-24 00:00:00 -0400138
Robert Moore73459f72005-06-24 00:00:00 -0400139 if (!acpi_gbl_mutex_info[mutex_id].mutex) {
Bob Moore967440e32006-06-23 17:04:00 -0400140 status =
141 acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
Len Brown4be44fc2005-08-05 00:44:28 -0400142 acpi_gbl_mutex_info[mutex_id].thread_id =
143 ACPI_MUTEX_NOT_ACQUIRED;
Robert Moore73459f72005-06-24 00:00:00 -0400144 acpi_gbl_mutex_info[mutex_id].use_count = 0;
145 }
146
Len Brown4be44fc2005-08-05 00:44:28 -0400147 return_ACPI_STATUS(status);
Robert Moore73459f72005-06-24 00:00:00 -0400148}
149
Robert Moore73459f72005-06-24 00:00:00 -0400150/*******************************************************************************
151 *
152 * FUNCTION: acpi_ut_delete_mutex
153 *
Bob Mooreba494be2012-07-12 09:40:10 +0800154 * PARAMETERS: mutex_ID - ID of the mutex to be deleted
Robert Moore73459f72005-06-24 00:00:00 -0400155 *
156 * RETURN: Status
157 *
158 * DESCRIPTION: Delete a mutex object.
159 *
160 ******************************************************************************/
161
Bob Moore2147d3f2010-01-21 09:08:31 +0800162static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
Robert Moore73459f72005-06-24 00:00:00 -0400163{
Robert Moore73459f72005-06-24 00:00:00 -0400164
Bob Mooreb229cf92006-04-21 17:15:00 -0400165 ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
Robert Moore73459f72005-06-24 00:00:00 -0400166
Bob Moore967440e32006-06-23 17:04:00 -0400167 acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
Robert Moore73459f72005-06-24 00:00:00 -0400168
169 acpi_gbl_mutex_info[mutex_id].mutex = NULL;
Robert Mooref9f46012005-07-08 00:00:00 -0400170 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
Bob Moore68aafc32012-10-31 02:26:01 +0000171
172 return_VOID;
Robert Moore73459f72005-06-24 00:00:00 -0400173}
174
Robert Moore73459f72005-06-24 00:00:00 -0400175/*******************************************************************************
176 *
177 * FUNCTION: acpi_ut_acquire_mutex
178 *
Bob Mooreba494be2012-07-12 09:40:10 +0800179 * PARAMETERS: mutex_ID - ID of the mutex to be acquired
Robert Moore73459f72005-06-24 00:00:00 -0400180 *
181 * RETURN: Status
182 *
183 * DESCRIPTION: Acquire a mutex object.
184 *
185 ******************************************************************************/
186
Len Brown4be44fc2005-08-05 00:44:28 -0400187acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
Robert Moore73459f72005-06-24 00:00:00 -0400188{
Len Brown4be44fc2005-08-05 00:44:28 -0400189 acpi_status status;
Bob Moore83135242006-10-03 00:00:00 -0400190 acpi_thread_id this_thread_id;
Robert Moore73459f72005-06-24 00:00:00 -0400191
Bob Mooreb229cf92006-04-21 17:15:00 -0400192 ACPI_FUNCTION_NAME(ut_acquire_mutex);
Robert Moore73459f72005-06-24 00:00:00 -0400193
Bob Moore4c90ece2006-06-08 16:29:00 -0400194 if (mutex_id > ACPI_MAX_MUTEX) {
Robert Moore73459f72005-06-24 00:00:00 -0400195 return (AE_BAD_PARAMETER);
196 }
197
Len Brown4be44fc2005-08-05 00:44:28 -0400198 this_thread_id = acpi_os_get_thread_id();
Robert Moore73459f72005-06-24 00:00:00 -0400199
200#ifdef ACPI_MUTEX_DEBUG
201 {
Len Brown4be44fc2005-08-05 00:44:28 -0400202 u32 i;
Robert Moore73459f72005-06-24 00:00:00 -0400203 /*
204 * Mutex debug code, for internal debugging only.
205 *
Bob Moore73a30902012-10-31 02:26:55 +0000206 * Deadlock prevention. Check if this thread owns any mutexes of value
207 * greater than or equal to this one. If so, the thread has violated
208 * the mutex ordering rule. This indicates a coding error somewhere in
Robert Moore73459f72005-06-24 00:00:00 -0400209 * the ACPI subsystem code.
210 */
Bob Mooreb53ce3f2008-06-10 14:30:04 +0800211 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
Robert Moorebda663d2005-09-16 16:51:15 -0400212 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
Robert Moore73459f72005-06-24 00:00:00 -0400213 if (i == mutex_id) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500214 ACPI_ERROR((AE_INFO,
Lin Ming28eb3fc2010-09-15 13:55:13 +0800215 "Mutex [%s] already acquired by this thread [%u]",
Bob Mooreb8e4d892006-01-27 16:43:00 -0500216 acpi_ut_get_mutex_name
217 (mutex_id),
Lin Ming28eb3fc2010-09-15 13:55:13 +0800218 (u32)this_thread_id));
Robert Moore73459f72005-06-24 00:00:00 -0400219
220 return (AE_ALREADY_ACQUIRED);
221 }
222
Bob Mooreb8e4d892006-01-27 16:43:00 -0500223 ACPI_ERROR((AE_INFO,
Lin Ming28eb3fc2010-09-15 13:55:13 +0800224 "Invalid acquire order: Thread %u owns [%s], wants [%s]",
225 (u32)this_thread_id,
Bob Mooreb8e4d892006-01-27 16:43:00 -0500226 acpi_ut_get_mutex_name(i),
227 acpi_ut_get_mutex_name(mutex_id)));
Robert Moore73459f72005-06-24 00:00:00 -0400228
229 return (AE_ACQUIRE_DEADLOCK);
230 }
231 }
232 }
233#endif
234
Len Brown4be44fc2005-08-05 00:44:28 -0400235 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
Lin Ming28eb3fc2010-09-15 13:55:13 +0800236 "Thread %u attempting to acquire Mutex [%s]\n",
237 (u32)this_thread_id,
Martin Bligh965a3d42006-10-20 14:30:26 -0700238 acpi_ut_get_mutex_name(mutex_id)));
Robert Moore73459f72005-06-24 00:00:00 -0400239
Bob Moore1fad8732015-12-29 13:54:36 +0800240 status =
241 acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
242 ACPI_WAIT_FOREVER);
Len Brown4be44fc2005-08-05 00:44:28 -0400243 if (ACPI_SUCCESS(status)) {
244 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
Lin Ming28eb3fc2010-09-15 13:55:13 +0800245 "Thread %u acquired Mutex [%s]\n",
246 (u32)this_thread_id,
Len Brown4be44fc2005-08-05 00:44:28 -0400247 acpi_ut_get_mutex_name(mutex_id)));
Robert Moore73459f72005-06-24 00:00:00 -0400248
249 acpi_gbl_mutex_info[mutex_id].use_count++;
Robert Mooref9f46012005-07-08 00:00:00 -0400250 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
Len Brown4be44fc2005-08-05 00:44:28 -0400251 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500252 ACPI_EXCEPTION((AE_INFO, status,
Bob Moore692aa0c2017-11-17 15:42:27 -0800253 "Thread %u could not acquire Mutex [%s] (0x%X)",
254 (u32)this_thread_id,
255 acpi_ut_get_mutex_name(mutex_id), mutex_id));
Robert Moore73459f72005-06-24 00:00:00 -0400256 }
257
258 return (status);
259}
260
Robert Moore73459f72005-06-24 00:00:00 -0400261/*******************************************************************************
262 *
263 * FUNCTION: acpi_ut_release_mutex
264 *
Bob Mooreba494be2012-07-12 09:40:10 +0800265 * PARAMETERS: mutex_ID - ID of the mutex to be released
Robert Moore73459f72005-06-24 00:00:00 -0400266 *
267 * RETURN: Status
268 *
269 * DESCRIPTION: Release a mutex object.
270 *
271 ******************************************************************************/
272
Len Brown4be44fc2005-08-05 00:44:28 -0400273acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
Robert Moore73459f72005-06-24 00:00:00 -0400274{
Bob Mooreb229cf92006-04-21 17:15:00 -0400275 ACPI_FUNCTION_NAME(ut_release_mutex);
Robert Moore73459f72005-06-24 00:00:00 -0400276
Lin Ming28eb3fc2010-09-15 13:55:13 +0800277 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
Bob Moore42f52842011-11-28 09:43:52 +0800278 (u32)acpi_os_get_thread_id(),
Len Brown4be44fc2005-08-05 00:44:28 -0400279 acpi_ut_get_mutex_name(mutex_id)));
Robert Moore73459f72005-06-24 00:00:00 -0400280
Bob Moore4c90ece2006-06-08 16:29:00 -0400281 if (mutex_id > ACPI_MAX_MUTEX) {
Robert Moore73459f72005-06-24 00:00:00 -0400282 return (AE_BAD_PARAMETER);
283 }
284
285 /*
286 * Mutex must be acquired in order to release it!
287 */
Robert Mooref9f46012005-07-08 00:00:00 -0400288 if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500289 ACPI_ERROR((AE_INFO,
Bob Moore692aa0c2017-11-17 15:42:27 -0800290 "Mutex [%s] (0x%X) is not acquired, cannot release",
291 acpi_ut_get_mutex_name(mutex_id), mutex_id));
Robert Moore73459f72005-06-24 00:00:00 -0400292
293 return (AE_NOT_ACQUIRED);
294 }
Robert Moore73459f72005-06-24 00:00:00 -0400295#ifdef ACPI_MUTEX_DEBUG
296 {
Len Brown4be44fc2005-08-05 00:44:28 -0400297 u32 i;
Robert Moore73459f72005-06-24 00:00:00 -0400298 /*
299 * Mutex debug code, for internal debugging only.
300 *
Bob Moore73a30902012-10-31 02:26:55 +0000301 * Deadlock prevention. Check if this thread owns any mutexes of value
302 * greater than this one. If so, the thread has violated the mutex
303 * ordering rule. This indicates a coding error somewhere in
Robert Moore73459f72005-06-24 00:00:00 -0400304 * the ACPI subsystem code.
305 */
Bob Mooreb53ce3f2008-06-10 14:30:04 +0800306 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
Bob Moore42f52842011-11-28 09:43:52 +0800307 if (acpi_gbl_mutex_info[i].thread_id ==
308 acpi_os_get_thread_id()) {
Robert Moore73459f72005-06-24 00:00:00 -0400309 if (i == mutex_id) {
310 continue;
311 }
312
Bob Mooreb8e4d892006-01-27 16:43:00 -0500313 ACPI_ERROR((AE_INFO,
314 "Invalid release order: owns [%s], releasing [%s]",
315 acpi_ut_get_mutex_name(i),
316 acpi_ut_get_mutex_name(mutex_id)));
Robert Moore73459f72005-06-24 00:00:00 -0400317
318 return (AE_RELEASE_DEADLOCK);
319 }
320 }
321 }
322#endif
323
324 /* Mark unlocked FIRST */
325
Robert Mooref9f46012005-07-08 00:00:00 -0400326 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
Robert Moore73459f72005-06-24 00:00:00 -0400327
Bob Moore967440e32006-06-23 17:04:00 -0400328 acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
329 return (AE_OK);
Robert Moore73459f72005-06-24 00:00:00 -0400330}