diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 1683e5c5b94c5febc942d191489f0f30634cbe04..1cbe6190582494ed9f3557c58a17b659644f4979 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -231,8 +231,10 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, * Obtain the method mutex if necessary. Do not acquire mutex for a * recursive call. */ - if (acpi_os_get_thread_id() != - obj_desc->method.mutex->mutex.owner_thread_id) { + if (!walk_state || + !obj_desc->method.mutex->mutex.owner_thread || + (walk_state->thread != + obj_desc->method.mutex->mutex.owner_thread)) { /* * Acquire the method mutex. This releases the interpreter if we * block (and reacquires it before it returns) @@ -246,14 +248,14 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, } /* Update the mutex and walk info and save the original sync_level */ - obj_desc->method.mutex->mutex.owner_thread_id = - acpi_os_get_thread_id(); if (walk_state) { obj_desc->method.mutex->mutex. original_sync_level = walk_state->thread->current_sync_level; + obj_desc->method.mutex->mutex.owner_thread = + walk_state->thread; walk_state->thread->current_sync_level = obj_desc->method.sync_level; } else { @@ -567,7 +569,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, acpi_os_release_mutex(method_desc->method.mutex->mutex. os_mutex); - method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; + method_desc->method.mutex->mutex.owner_thread = NULL; } } diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 1a73c14df2c5aa7d7f7cdd1c195bb1e202747139..68d283fd60e7d254d936b0850a63950a948dbad3 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -134,7 +134,7 @@ static struct acpi_exdump_info acpi_ex_dump_method[8] = { static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), "Acquire Depth"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"} diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index 4eb883bda6ae7f23800decda4a549042c64c8a94..5101bad5baf8b3074d29156b8a47444b286e90f8 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c @@ -66,9 +66,10 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc, * ******************************************************************************/ -void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc, - struct acpi_thread_state *thread) +void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) { + struct acpi_thread_state *thread = obj_desc->mutex.owner_thread; + if (!thread) { return; } @@ -173,13 +174,16 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Support for multiple acquires by the owning thread */ - if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) { - /* - * The mutex is already owned by this thread, just increment the - * acquisition depth - */ - obj_desc->mutex.acquisition_depth++; - return_ACPI_STATUS(AE_OK); + if (obj_desc->mutex.owner_thread) { + if (obj_desc->mutex.owner_thread->thread_id == + walk_state->thread->thread_id) { + /* + * The mutex is already owned by this thread, just increment the + * acquisition depth + */ + obj_desc->mutex.acquisition_depth++; + return_ACPI_STATUS(AE_OK); + } } /* Acquire the mutex, wait if necessary. Special case for Global Lock */ @@ -202,7 +206,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Have the mutex: update mutex and walk info and save the sync_level */ - obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id(); + obj_desc->mutex.owner_thread = walk_state->thread; obj_desc->mutex.acquisition_depth = 1; obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level; @@ -242,7 +246,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* The mutex must have been previously acquired in order to release it */ - if (!obj_desc->mutex.owner_thread_id) { + if (!obj_desc->mutex.owner_thread) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], not acquired", acpi_ut_get_node_name(obj_desc->mutex.node))); @@ -262,14 +266,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, * The Mutex is owned, but this thread must be the owner. * Special case for Global Lock, any thread can release */ - if ((obj_desc->mutex.owner_thread_id != + if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { ACPI_ERROR((AE_INFO, "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", (unsigned long)walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), - (unsigned long)obj_desc->mutex.owner_thread_id)); + (unsigned long)obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS(AE_AML_NOT_OWNER); } @@ -296,7 +300,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* Unlink the mutex from the owner's list */ - acpi_ex_unlink_mutex(obj_desc, walk_state->thread); + acpi_ex_unlink_mutex(obj_desc); /* Release the mutex, special case for Global Lock */ @@ -308,7 +312,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, /* Update the mutex and restore sync_level */ - obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; + obj_desc->mutex.owner_thread = NULL; walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level; @@ -363,7 +367,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) /* Mark mutex unowned */ - obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED; + obj_desc->mutex.owner_thread = NULL; /* Update Thread sync_level (Last mutex is the important one) */ diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 673a0caa4073438f3f22af2dcad6a6e9f4bdc029..f777cebdc46dd85f8ec66b491096f9d2f20af1a3 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -170,6 +170,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) acpi_os_delete_mutex(object->mutex.os_mutex); acpi_gbl_global_lock_mutex = NULL; } else { + acpi_ex_unlink_mutex(object); acpi_os_delete_mutex(object->mutex.os_mutex); } break; diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index 73967c8152d325012db1f690f9cd6744caec2f76..ce7c9d653910598c29cce2baa2dcbb28b8cbb83b 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -253,8 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); -void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc, - struct acpi_thread_state *thread); +void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); /* * exprep - ACPI AML execution - prep utilities diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index 5206d61d74a6039eac0852145eb956b842554d6a..04e9735a674214fb49aab10f3b75d273e3f44e0d 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h @@ -155,7 +155,7 @@ struct acpi_object_event { struct acpi_object_mutex { ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ u16 acquisition_depth; /* Allow multiple Acquires, same thread */ - acpi_thread_id owner_thread_id; /* Current owner of the mutex */ + struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ acpi_mutex os_mutex; /* Actual OS synchronization object */ union acpi_operand_object *prev; /* Link for list of acquired mutexes */ union acpi_operand_object *next; /* Link for list of acquired mutexes */