root/drivers/acpi/acpica/utmutex.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ut_mutex_terminate
  3. acpi_ut_create_mutex
  4. acpi_ut_delete_mutex
  5. acpi_ut_acquire_mutex
  6. acpi_ut_release_mutex

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

/* [<][>][^][v][top][bottom][index][help] */