aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLv Zheng <zetalog@gmail.com>2016-10-26 03:40:12 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-10-28 19:57:43 -0400
commit25ccd2429fd0af5b9c2c136c8c593491aeabf162 (patch)
tree6e42efd5429fddba4bdaf301708c7e2b9870e8f6 /drivers/acpi
parent07d9a380680d1c0eb51ef87ff2eab5c994949e69 (diff)
ACPICA: Dispatcher: Fix order issue of method termination
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: 74f51b80a0c4 (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>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpica/dsmethod.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
index 32e9ddc0cf2b..c4028a8dacd5 100644
--- a/drivers/acpi/acpica/dsmethod.c
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -731,26 +731,6 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
731 acpi_ds_method_data_delete_all(walk_state); 731 acpi_ds_method_data_delete_all(walk_state);
732 732
733 /* 733 /*
734 * If method is serialized, release the mutex and restore the
735 * current sync level for this thread
736 */
737 if (method_desc->method.mutex) {
738
739 /* Acquisition Depth handles recursive calls */
740
741 method_desc->method.mutex->mutex.acquisition_depth--;
742 if (!method_desc->method.mutex->mutex.acquisition_depth) {
743 walk_state->thread->current_sync_level =
744 method_desc->method.mutex->mutex.
745 original_sync_level;
746
747 acpi_os_release_mutex(method_desc->method.
748 mutex->mutex.os_mutex);
749 method_desc->method.mutex->mutex.thread_id = 0;
750 }
751 }
752
753 /*
754 * Delete any namespace objects created anywhere within the 734 * Delete any namespace objects created anywhere within the
755 * namespace by the execution of this method. Unless: 735 * namespace by the execution of this method. Unless:
756 * 1) This method is a module-level executable code method, in which 736 * 1) This method is a module-level executable code method, in which
@@ -786,6 +766,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
786 ~ACPI_METHOD_MODIFIED_NAMESPACE; 766 ~ACPI_METHOD_MODIFIED_NAMESPACE;
787 } 767 }
788 } 768 }
769
770 /*
771 * If method is serialized, release the mutex and restore the
772 * current sync level for this thread
773 */
774 if (method_desc->method.mutex) {
775
776 /* Acquisition Depth handles recursive calls */
777
778 method_desc->method.mutex->mutex.acquisition_depth--;
779 if (!method_desc->method.mutex->mutex.acquisition_depth) {
780 walk_state->thread->current_sync_level =
781 method_desc->method.mutex->mutex.
782 original_sync_level;
783
784 acpi_os_release_mutex(method_desc->method.
785 mutex->mutex.os_mutex);
786 method_desc->method.mutex->mutex.thread_id = 0;
787 }
788 }
789 } 789 }
790 790
791 /* Decrement the thread count on the method */ 791 /* Decrement the thread count on the method */