ACPICA: fix AML mutex re-entrancy
ACPI AML supports "serialized" methods which are protected by an implicit mutex. The mutex is re-entrant for that AML thread to allow recursion. However, Linux implements notify() by creating a new AML thread. So for systems where notify() re-enters a serialized method, deadlock results. The fix is to use the Linux thread_id as the key to allowing re-entrancy, not the AML thread pointer. http://bugzilla.kernel.org/show_bug.cgi?id=5534 Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
committed by
Len Brown
parent
724339d76d
commit
c0d127b569
@@ -231,10 +231,8 @@ 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 (!walk_state ||
|
||||
!obj_desc->method.mutex->mutex.owner_thread ||
|
||||
(walk_state->thread !=
|
||||
obj_desc->method.mutex->mutex.owner_thread)) {
|
||||
if (acpi_os_get_thread_id() !=
|
||||
obj_desc->method.mutex->mutex.owner_thread_id) {
|
||||
/*
|
||||
* Acquire the method mutex. This releases the interpreter if we
|
||||
* block (and reacquires it before it returns)
|
||||
@@ -248,14 +246,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 {
|
||||
@@ -569,7 +567,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 = NULL;
|
||||
method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user