Skip to content

Commit

Permalink
ACPICA: Dispatcher: Fix order issue of method termination
Browse files Browse the repository at this point in the history
The last step of the method termination should be the end of the method
serialization. Otherwise, the steps happening after it will face the race
issues that cannot be protected by the method serialization mechanism.

This patch fixes this issue by moving the per-method-object deletion code
prior than the end of the method serialization. Otherwise, the possible
race issues may result in AE_ALREADY_EXISTS error in a parallel
environment.

Fixes: 74f51b8 (ACPICA: Namespace: Fix dynamic table loading issues)
Reported-and-tested-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
zetalog authored and rafaeljw committed Oct 28, 2016
1 parent 07d9a38 commit 25ccd24
Showing 1 changed file with 20 additions and 20 deletions.
40 changes: 20 additions & 20 deletions drivers/acpi/acpica/dsmethod.c
Expand Up @@ -730,26 +730,6 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,

acpi_ds_method_data_delete_all(walk_state);

/*
* If method is serialized, release the mutex and restore the
* current sync level for this thread
*/
if (method_desc->method.mutex) {

/* Acquisition Depth handles recursive calls */

method_desc->method.mutex->mutex.acquisition_depth--;
if (!method_desc->method.mutex->mutex.acquisition_depth) {
walk_state->thread->current_sync_level =
method_desc->method.mutex->mutex.
original_sync_level;

acpi_os_release_mutex(method_desc->method.
mutex->mutex.os_mutex);
method_desc->method.mutex->mutex.thread_id = 0;
}
}

/*
* Delete any namespace objects created anywhere within the
* namespace by the execution of this method. Unless:
Expand Down Expand Up @@ -786,6 +766,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
~ACPI_METHOD_MODIFIED_NAMESPACE;
}
}

/*
* If method is serialized, release the mutex and restore the
* current sync level for this thread
*/
if (method_desc->method.mutex) {

/* Acquisition Depth handles recursive calls */

method_desc->method.mutex->mutex.acquisition_depth--;
if (!method_desc->method.mutex->mutex.acquisition_depth) {
walk_state->thread->current_sync_level =
method_desc->method.mutex->mutex.
original_sync_level;

acpi_os_release_mutex(method_desc->method.
mutex->mutex.os_mutex);
method_desc->method.mutex->mutex.thread_id = 0;
}
}
}

/* Decrement the thread count on the method */
Expand Down

0 comments on commit 25ccd24

Please sign in to comment.