LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - utmutex.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 47 68 69.1 %
Date: 2022-04-01 14:58:12 Functions: 4 6 66.7 %
Branches: 15 30 50.0 %

           Branch data     Line data    Source code
       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                 :          3 : acpi_status acpi_ut_mutex_initialize(void)
      33                 :            : {
      34                 :          3 :         u32 i;
      35                 :          3 :         acpi_status status;
      36                 :            : 
      37                 :          3 :         ACPI_FUNCTION_TRACE(ut_mutex_initialize);
      38                 :            : 
      39                 :            :         /* Create each of the predefined mutex objects */
      40                 :            : 
      41         [ +  + ]:         21 :         for (i = 0; i < ACPI_NUM_MUTEX; i++) {
      42                 :         18 :                 status = acpi_ut_create_mutex(i);
      43         [ -  + ]:         18 :                 if (ACPI_FAILURE(status)) {
      44                 :          0 :                         return_ACPI_STATUS(status);
      45                 :            :                 }
      46                 :            :         }
      47                 :            : 
      48                 :            :         /* Create the spinlocks for use at interrupt level or for speed */
      49                 :            : 
      50   [ +  -  +  - ]:          3 :         status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
      51                 :          3 :         if (ACPI_FAILURE (status)) {
      52                 :            :                 return_ACPI_STATUS (status);
      53                 :            :         }
      54                 :            : 
      55   [ +  -  +  - ]:          3 :         status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
      56                 :          3 :         if (ACPI_FAILURE (status)) {
      57                 :            :                 return_ACPI_STATUS (status);
      58                 :            :         }
      59                 :            : 
      60   [ +  -  +  - ]:          3 :         status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
      61                 :          3 :         if (ACPI_FAILURE(status)) {
      62                 :            :                 return_ACPI_STATUS(status);
      63                 :            :         }
      64                 :            : 
      65                 :            :         /* Mutex for _OSI support */
      66                 :            : 
      67                 :          3 :         status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
      68         [ +  - ]:          3 :         if (ACPI_FAILURE(status)) {
      69                 :            :                 return_ACPI_STATUS(status);
      70                 :            :         }
      71                 :            : 
      72                 :            :         /* Create the reader/writer lock for namespace access */
      73                 :            : 
      74                 :          3 :         status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
      75                 :          3 :         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                 :          0 : void acpi_ut_mutex_terminate(void)
      96                 :            : {
      97                 :          0 :         u32 i;
      98                 :            : 
      99                 :          0 :         ACPI_FUNCTION_TRACE(ut_mutex_terminate);
     100                 :            : 
     101                 :            :         /* Delete each predefined mutex object */
     102                 :            : 
     103         [ #  # ]:          0 :         for (i = 0; i < ACPI_NUM_MUTEX; i++) {
     104                 :          0 :                 acpi_ut_delete_mutex(i);
     105                 :            :         }
     106                 :            : 
     107                 :          0 :         acpi_os_delete_mutex(acpi_gbl_osi_mutex);
     108                 :            : 
     109                 :            :         /* Delete the spinlocks */
     110                 :            : 
     111                 :          0 :         acpi_os_delete_lock(acpi_gbl_gpe_lock);
     112                 :          0 :         acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
     113                 :          0 :         acpi_os_delete_lock(acpi_gbl_reference_count_lock);
     114                 :            : 
     115                 :            :         /* Delete the reader/writer lock */
     116                 :            : 
     117                 :          0 :         acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
     118                 :          0 :         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                 :         18 : static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
     134                 :            : {
     135                 :         18 :         acpi_status status = AE_OK;
     136                 :            : 
     137                 :         18 :         ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
     138                 :            : 
     139         [ +  - ]:         18 :         if (!acpi_gbl_mutex_info[mutex_id].mutex) {
     140                 :         18 :                 status =
     141                 :         18 :                     acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
     142                 :         18 :                 acpi_gbl_mutex_info[mutex_id].thread_id =
     143                 :            :                     ACPI_MUTEX_NOT_ACQUIRED;
     144                 :         18 :                 acpi_gbl_mutex_info[mutex_id].use_count = 0;
     145                 :            :         }
     146                 :            : 
     147                 :         18 :         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                 :          0 : static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
     163                 :            : {
     164                 :            : 
     165                 :          0 :         ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
     166                 :            : 
     167                 :          0 :         acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
     168                 :            : 
     169                 :          0 :         acpi_gbl_mutex_info[mutex_id].mutex = NULL;
     170                 :          0 :         acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
     171                 :            : 
     172                 :          0 :         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                 :      36126 : acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
     188                 :            : {
     189                 :      36126 :         acpi_status status;
     190                 :      36126 :         acpi_thread_id this_thread_id;
     191                 :            : 
     192                 :      36126 :         ACPI_FUNCTION_NAME(ut_acquire_mutex);
     193                 :            : 
     194         [ +  - ]:      36126 :         if (mutex_id > ACPI_MAX_MUTEX) {
     195                 :            :                 return (AE_BAD_PARAMETER);
     196                 :            :         }
     197                 :            : 
     198                 :      36126 :         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                 :      36126 :                           acpi_ut_get_mutex_name(mutex_id)));
     239                 :            : 
     240                 :      36126 :         status =
     241                 :      36126 :             acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
     242                 :            :                                   ACPI_WAIT_FOREVER);
     243         [ +  - ]:      36126 :         if (ACPI_SUCCESS(status)) {
     244                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
     245                 :            :                                   "Thread %u acquired Mutex [%s]\n",
     246                 :            :                                   (u32)this_thread_id,
     247                 :      36126 :                                   acpi_ut_get_mutex_name(mutex_id)));
     248                 :            : 
     249                 :      36126 :                 acpi_gbl_mutex_info[mutex_id].use_count++;
     250                 :      36126 :                 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
     251                 :            :         } else {
     252                 :          0 :                 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                 :      36126 : acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
     274                 :            : {
     275                 :      36126 :         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                 :      36126 :                           acpi_ut_get_mutex_name(mutex_id)));
     280                 :            : 
     281         [ +  - ]:      36126 :         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         [ -  + ]:      36126 :         if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
     289                 :          0 :                 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                 :          0 :                 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                 :      36126 :         acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
     327                 :            : 
     328                 :      36126 :         acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
     329                 :      36126 :         return (AE_OK);
     330                 :            : }

Generated by: LCOV version 1.14