ACPICA: Fix mutex errors when running _REG methods
authorBob Moore <robert.moore@intel.com>
Fri, 11 Dec 2009 07:16:38 +0000 (15:16 +0800)
committerLen Brown <len.brown@intel.com>
Tue, 15 Dec 2009 22:29:36 +0000 (17:29 -0500)
Fixes a problem where mutex errors can occur when running a _REG
method that is in the same scope as a method-defined operation
region or an operation region under a module-level IF block.
This is rare, so the problem has not been seen before.
ACPICA BZ 826.

http://www.acpica.org/bugzilla/show_bug.cgi?id=826

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/acpica/dswload.c

index 9cc2289..b40513d 100644 (file)
@@ -1052,9 +1052,22 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                        }
 
                        /*
-                        * If we are executing a method, initialize the region
+                        * The op_region is not fully parsed at this time. The only valid
+                        * argument is the space_id. (We must save the address of the
+                        * AML of the address and length operands)
+                        *
+                        * If we have a valid region, initialize it. The namespace is
+                        * unlocked at this point.
+                        *
+                        * Need to unlock interpreter if it is locked (if we are running
+                        * a control method), in order to allow _REG methods to be run
+                        * during acpi_ev_initialize_region.
                         */
                        if (walk_state->method_node) {
+                               /*
+                                * Executing a method: initialize the region and unlock
+                                * the interpreter
+                                */
                                status =
                                    acpi_ex_create_region(op->named.data,
                                                          op->named.length,
@@ -1063,21 +1076,17 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                                if (ACPI_FAILURE(status)) {
                                        return (status);
                                }
-                       }
 
-                       /*
-                        * The op_region is not fully parsed at this time. Only valid
-                        * argument is the space_id. (We must save the address of the
-                        * AML of the address and length operands)
-                        */
+                               acpi_ex_exit_interpreter();
+                       }
 
-                       /*
-                        * If we have a valid region, initialize it
-                        * Namespace is NOT locked at this point.
-                        */
                        status =
                            acpi_ev_initialize_region
                            (acpi_ns_get_attached_object(node), FALSE);
+                       if (walk_state->method_node) {
+                               acpi_ex_enter_interpreter();
+                       }
+
                        if (ACPI_FAILURE(status)) {
                                /*
                                 *  If AE_NOT_EXIST is returned, it is not fatal