Skip to contentSkip to conversation

ACPICA: Merge auto-serialization support to reduce source code differences between Linux and ACPICA upstream.

PATCH New Lv Zheng 1 participant 6 messages Mar 24, 2014

Subsystems (3)
lore
Share & tools
lore

Lv Zheng

author
#0 lore raw

cover ACPICA: Merge auto-serialization support to reduce source code differences between Linux and ACPICA upstream.

The auto-serialization feature is introduced in ACPICA 20140214 release, it is reverted due to the new bug reports.
The feature fixes a compliance issue between the ACPICA interpreter and the de-facto implementation. Users are encouraged to use this feature to provide the feedbacks.

This series re-orders the patches to implement the feature so that it can be marked out by reverting the last patch in this series when new problems are detected.
This series can also reduce the source code differences between Linux and ACPICA upstream.

Bob Moore (2):
ACPICA: Add auto-serialization support for ill-behaved control
methods.
ACPICA: Ignore sync_level for methods that have been auto-serialized.

Lv Zheng (3):
ACPICA: Remove global option to serialize all control methods.
ACPICA: Add additional named objects for the auto-serialize method
scan.
ACPICA: Enable auto-serialization as a default kernel behavior.

 Documentation/kernel-parameters.txt |   10 ++-
 drivers/acpi/acpica/acdispat.h      |   13 +--
 drivers/acpi/acpica/acglobal.h      |   11 +--
 drivers/acpi/acpica/acinterp.h      |    4 -
 drivers/acpi/acpica/acobject.h      |    3 +-
 drivers/acpi/acpica/acstruct.h      |    3 +
 drivers/acpi/acpica/dsinit.c        |   59 ++++++++++---
 drivers/acpi/acpica/dsmethod.c      |  156 +++++++++++++++++++++++++++++++++--
 drivers/acpi/acpica/dswload.c       |   16 ++++
 drivers/acpi/acpica/exsystem.c      |   12 +--
 drivers/acpi/acpica/exutils.c       |   80 +++---------------
 drivers/acpi/acpica/nsinit.c        |    5 +-
 drivers/acpi/acpica/nsload.c        |    4 +-
 drivers/acpi/acpica/psloop.c        |    4 +
 drivers/acpi/acpica/psobject.c      |    7 +-
 drivers/acpi/osl.c                  |   16 ++--
 include/acpi/acpixf.h               |    2 +-
 17 files changed, 281 insertions(+), 124 deletions(-)
Signature · 1 line
1.7.10
author
#2 lore raw

PATCH 2/5 ACPICA: Add auto-serialization support for ill-behaved control methods.

From: Bob Moore <[email protected]>

This change adds support to automatically mark a control method as "serialized" if the method creates any named objects. This will positively prevent the method from being entered by more than one thread and thus preventing a possible abort when an attempt is made to create an object twice.

Implemented by parsing all non-serialize control methods at table load time.

This feature is disabled by default and this patch also adds a new Linux kernel parameter "acpi_auto_serialize" to allow this feature to be turned on for a specific boot.

---
 Documentation/kernel-parameters.txt |    8 +++
 drivers/acpi/acpica/acdispat.h      |   13 ++--
 drivers/acpi/acpica/acglobal.h      |    9 +++
 drivers/acpi/acpica/acstruct.h      |    3 +
 drivers/acpi/acpica/dsinit.c        |   59 ++++++++++++----
 drivers/acpi/acpica/dsmethod.c      |  132 ++++++++++++++++++++++++++++++++++-
 drivers/acpi/acpica/dswload.c       |   16 +++++
 drivers/acpi/acpica/nsinit.c        |    5 +-
 drivers/acpi/acpica/nsload.c        |    4 +-
 drivers/acpi/acpica/psloop.c        |    4 ++
 drivers/acpi/acpica/psobject.c      |    7 +-
 drivers/acpi/osl.c                  |   16 +++++
 include/acpi/acpixf.h               |    1 +
 13 files changed, 252 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +8 -0
index 3eae32f..a159537 100644
@@ -229,6 +229,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			use by PCI
 			Format: <irq>,<irq>...
 
+	acpi_auto_serialize	[HW,ACPI]
+			Enable auto-serialization of AML methods
+			AML control methods that contain the opcodes to create
+			named objects will be marked as "Serialized" by the
+			auto-serialization feature.
+			This feature is disabled by default.
+			This option allows to turn on the feature.
+
 	acpi_no_auto_ssdt	[HW,ACPI] Disable automatic loading of SSDT
 
 	acpica_no_return_repair [HW, ACPI]
drivers/acpi/acpica/acdispat.h +8 -5
index 5b472c4..d3e2cc3 100644
@@ -139,20 +139,21 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
 			   struct acpi_walk_state *walk_state);
 
 /*
- * dsload - Parser/Interpreter interface, pass 1 namespace load callbacks
+ * dsload - Parser/Interpreter interface
  */
 acpi_status
 acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
 
+/* dsload - pass 1 namespace load callbacks */
+
 acpi_status
 acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
 		       union acpi_parse_object **out_op);
 
 acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state);
 
-/*
- * dsload - Parser/Interpreter interface, pass 2 namespace load callbacks
- */
+/* dsload - pass 2 namespace load callbacks */
+
 acpi_status
 acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
 		       union acpi_parse_object **out_op);
@@ -200,7 +201,9 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state);
 /*
  * dsmethod - Parser/Interpreter interface - control method parsing
  */
-acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node);
+acpi_status
+acpi_ds_auto_serialize_method(struct acpi_namespace_node *node,
+			      union acpi_operand_object *obj_desc);
 
 acpi_status
 acpi_ds_call_control_method(struct acpi_thread_state *thread,
drivers/acpi/acpica/acglobal.h +9 -0
index 767556c..ea0f838 100644
@@ -93,6 +93,15 @@
 ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE);
 
 /*
+ * Automatically serialize all methods that create named objects? Default
+ * is TRUE, meaning that all non_serialized methods are scanned once at
+ * table load time to determine those that create named objects. Methods
+ * that create named objects are marked Serialized in order to prevent
+ * possible run-time problems if they are entered by more than one thread.
+ */
+ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, FALSE);
+
+/*
  * Create the predefined _OSI method in the namespace? Default is TRUE
  * because ACPI CA is fully compatible with other ACPI implementations.
  * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
drivers/acpi/acpica/acstruct.h +3 -0
index 5d2989a..cf73461 100644
@@ -133,6 +133,9 @@ struct acpi_init_walk_info {
 	u32 table_index;
 	u32 object_count;
 	u32 method_count;
+	u32 serial_method_count;
+	u32 non_serial_method_count;
+	u32 serialized_method_count;
 	u32 device_count;
 	u32 op_region_count;
 	u32 field_count;
drivers/acpi/acpica/dsinit.c +47 -12

93 lines not on this page · raw message

drivers/acpi/acpica/dsmethod.c +131 -1

154 lines not on this page · raw message

drivers/acpi/acpica/dswload.c +16 -0
index bd7811c..15623da 100644
@@ -73,8 +73,20 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
 {
 
 	switch (pass_number) {
+	case 0:
+
+		/* Parse only - caller will setup callbacks */
+
+		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
+		    ACPI_PARSE_DELETE_TREE | ACPI_PARSE_DISASSEMBLE;
+		walk_state->descending_callback = NULL;
+		walk_state->ascending_callback = NULL;
+		break;
+
 	case 1:
 
+		/* Load pass 1 */
+
 		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
 		    ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_load1_begin_op;
@@ -83,6 +95,8 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
 
 	case 2:
 
+		/* Load pass 2 */
+
 		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
 		    ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_load2_begin_op;
@@ -91,6 +105,8 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
 
 	case 3:
 
+		/* Execution pass */
+
 #ifndef ACPI_NO_METHOD_EXECUTION
 		walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
 		    ACPI_PARSE_DELETE_TREE;
drivers/acpi/acpica/nsinit.c +2 -3
index 5b74677..a3fb7e4 100644
@@ -111,9 +111,8 @@ acpi_status acpi_ns_initialize_objects(void)
 			      info.object_count));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "%u Control Methods found\n", info.method_count));
-	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "%u Op Regions found\n", info.op_region_count));
+			  "%u Control Methods found\n%u Op Regions found\n",
+			  info.method_count, info.op_region_count));
 
 	return_ACPI_STATUS(AE_OK);
 }
drivers/acpi/acpica/nsload.c +2 -2
index 7ae521c..7c9d018 100644
@@ -128,12 +128,12 @@ unlock:
 	 * parse trees.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Begin Table Method Parsing and Object Initialization\n"));
+			  "**** Begin Table Object Initialization\n"));
 
 	status = acpi_ds_initialize_objects(table_index, node);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Completed Table Method Parsing and Object Initialization\n"));
+			  "**** Completed Table Object Initialization\n"));
 
 	return_ACPI_STATUS(status);
 }
drivers/acpi/acpica/psloop.c +4 -0
index 646d1a3..b058e23 100644
@@ -480,6 +480,10 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
 					status = AE_OK;
 				}
 
+				if (status == AE_CTRL_TERMINATE) {
+					return_ACPI_STATUS(status);
+				}
+
 				status =
 				    acpi_ps_complete_op(walk_state, &op,
 							status);
drivers/acpi/acpica/psobject.c +5 -2
index af1f46c..a688507 100644
@@ -219,7 +219,10 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
 
 	status = walk_state->descending_callback(walk_state, op);
 	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
+		if (status != AE_CTRL_TERMINATE) {
+			ACPI_EXCEPTION((AE_INFO, status,
+					"During name lookup/catalog"));
+		}
 		return_ACPI_STATUS(status);
 	}
 
@@ -230,7 +233,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
 	status = acpi_ps_next_parse_state(walk_state, *op, status);
 	if (ACPI_FAILURE(status)) {
 		if (status == AE_CTRL_PENDING) {
-			return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
+			status = AE_CTRL_PARSE_PENDING;
 		}
 		return_ACPI_STATUS(status);
 	}
drivers/acpi/osl.c +16 -0
index 5a16cc6..928f0c2 100644
@@ -1537,6 +1537,22 @@ static int __init osi_setup(char *str)
 
 __setup("acpi_osi=", osi_setup);
 
+/*
+ * Enable the auto-serialization of named objects creation methods.
+ *
+ * This feature is disabled by default.  It marks the AML control methods
+ * that contain the opcodes to create named objects as "Serialized".
+ */
+static int __init acpi_auto_serialize_setup(char *str)
+{
+	acpi_gbl_auto_serialize_methods = TRUE;
+	pr_info("ACPI: auto-serialization enabled\n");
+
+	return 1;
+}
+
+__setup("acpi_auto_serialize", acpi_auto_serialize_setup);
+
 /* Check of resource interference between native drivers and ACPI
  * OperationRegions (SystemIO and System Memory only).
  * IO ports and memory declared in ACPI might be used by the ACPI subsystem
include/acpi/acpixf.h +1 -0
index 5c2a82a..44f5e97 100644
@@ -71,6 +71,7 @@ extern u32 acpi_dbg_layer;
 
 /* ACPICA runtime options */
 
+extern u8 acpi_gbl_auto_serialize_methods;
 extern u8 acpi_gbl_copy_dsdt_locally;
 extern u8 acpi_gbl_create_osi_method;
 extern u8 acpi_gbl_disable_auto_repair;
Signature · 1 line
1.7.10
author
#3 lore raw

PATCH 3/5 ACPICA: Add additional named objects for the auto-serialize method scan.

In reply to Lv Zheng

This change adds some additional opcodes that are detected and will cause a method to be auto-serialized. These opcodes are the various CreateXField and the FieldUnit opcodes. Lv Zheng.

---
 drivers/acpi/acpica/dsmethod.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/acpi/acpica/dsmethod.c +4 -2
index 97ed86a..73764c7 100644
@@ -163,9 +163,11 @@ acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state,
 
 	ACPI_FUNCTION_NAME(acpi_ds_detect_named_opcodes);
 
-	/* We are only interested in opcodes that have an associated name */
+	/* We are only interested in opcodes that create a new name */
 
-	if (!(walk_state->op_info->flags & AML_NAMED)) {
+	if (!
+	    (walk_state->op_info->
+	     flags & (AML_NAMED | AML_CREATE | AML_FIELD))) {
 		return (AE_OK);
 	}
 
Signature · 1 line
1.7.10
author
#1 lore raw

PATCH 1/5 ACPICA: Remove global option to serialize all control methods.

In reply to Lv Zheng

According to the reports, the "acpi_serialize" mechanism is broken as:
A. The parallel method calls can still happen when the interpreter lock is
released under the following conditions:
1. External callbacks are invoked, for example, by the region handlers,

      the exception handlers, etc.;

2. Module level execution is performed when Load/LoadTable opcodes are executed, and
3. The _REG control methods are invoked to complete the region registrations.
B. For the following situations, the interpreter lock need to be released
even for a serialized method while currently, the lock-releasing operation is marked as a no-op by acpi_ex_relinquish/reacquire_interpreter() when this mechanism is enabled:
1. Wait opcode is executed,
2. Acquire opcode is executed, and
3. Sleep opcode is executed.

This patch removes this mechanism and the internal acpi_ex_relinquish/reacquire_interpreter() APIs. Lv Zheng.

Signed-off: Lv Zheng <[email protected]>

---
 Documentation/kernel-parameters.txt |    2 -
 drivers/acpi/acpica/acglobal.h      |    8 ----
 drivers/acpi/acpica/acinterp.h      |    4 --
 drivers/acpi/acpica/exsystem.c      |   12 +++---
 drivers/acpi/acpica/exutils.c       |   80 +++++------------------------------
 drivers/acpi/osl.c                  |   12 ------
 include/acpi/acpixf.h               |    1 -
 7 files changed, 16 insertions(+), 103 deletions(-)
Documentation/kernel-parameters.txt +0 -2
index bf0fda0..3eae32f 100644
@@ -306,8 +306,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	acpi_sci=	[HW,ACPI] ACPI System Control Interrupt trigger mode
 			Format: { level | edge | high | low }
 
-	acpi_serialize	[HW,ACPI] force serialization of AML methods
-
 	acpi_skip_timer_override [HW,ACPI]
 			Recognize and ignore IRQ0/pin2 Interrupt Override.
 			For broken nForce2 BIOS resulting in XT-PIC timer.
drivers/acpi/acpica/acglobal.h +0 -8
index 8f40bb9..767556c 100644
@@ -93,14 +93,6 @@
 ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE);
 
 /*
- * Automatically serialize ALL control methods? Default is FALSE, meaning
- * to use the Serialized/not_serialized method flags on a per method basis.
- * Only change this if the ASL code is poorly written and cannot handle
- * reentrancy even though methods are marked "NotSerialized".
- */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_all_methods_serialized, FALSE);
-
-/*
  * Create the predefined _OSI method in the namespace? Default is TRUE
  * because ACPI CA is fully compatible with other ACPI implementations.
  * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
drivers/acpi/acpica/acinterp.h +0 -4
index c542677..b01f71c 100644
@@ -458,10 +458,6 @@ void acpi_ex_enter_interpreter(void);
 
 void acpi_ex_exit_interpreter(void);
 
-void acpi_ex_reacquire_interpreter(void);
-
-void acpi_ex_relinquish_interpreter(void);
-
 u8 acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
 
 void acpi_ex_acquire_global_lock(u32 rule);
drivers/acpi/acpica/exsystem.c +6 -6
index 841caed..f7da641 100644
@@ -77,7 +77,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
 		/* We must wait, so unlock the interpreter */
 
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 
 		status = acpi_os_wait_semaphore(semaphore, 1, timeout);
 
@@ -87,7 +87,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
 		/* Reacquire the interpreter */
 
-		acpi_ex_reacquire_interpreter();
+		acpi_ex_enter_interpreter();
 	}
 
 	return_ACPI_STATUS(status);
@@ -123,7 +123,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 
 		/* We must wait, so unlock the interpreter */
 
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 
 		status = acpi_os_acquire_mutex(mutex, timeout);
 
@@ -133,7 +133,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 
 		/* Reacquire the interpreter */
 
-		acpi_ex_reacquire_interpreter();
+		acpi_ex_enter_interpreter();
 	}
 
 	return_ACPI_STATUS(status);
@@ -198,7 +198,7 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long)
 
 	/* Since this thread will sleep, we must release the interpreter */
 
-	acpi_ex_relinquish_interpreter();
+	acpi_ex_exit_interpreter();
 
 	/*
 	 * For compatibility with other ACPI implementations and to prevent
@@ -212,7 +212,7 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long)
 
 	/* And now we must get the interpreter again */
 
-	acpi_ex_reacquire_interpreter();
+	acpi_ex_enter_interpreter();
 	return (AE_OK);
 }
 
drivers/acpi/acpica/exutils.c +10 -70

98 lines not on this page · raw message

drivers/acpi/osl.c +0 -12
index 821134b..5a16cc6 100644
@@ -1537,18 +1537,6 @@ static int __init osi_setup(char *str)
 
 __setup("acpi_osi=", osi_setup);
 
-/* enable serialization to combat AE_ALREADY_EXISTS errors */
-static int __init acpi_serialize_setup(char *str)
-{
-	printk(KERN_INFO PREFIX "serialize enabled\n");
-
-	acpi_gbl_all_methods_serialized = TRUE;
-
-	return 1;
-}
-
-__setup("acpi_serialize", acpi_serialize_setup);
-
 /* Check of resource interference between native drivers and ACPI
  * OperationRegions (SystemIO and System Memory only).
  * IO ports and memory declared in ACPI might be used by the ACPI subsystem
include/acpi/acpixf.h +0 -1
index b0b01b1..5c2a82a 100644
@@ -71,7 +71,6 @@ extern u32 acpi_dbg_layer;
 
 /* ACPICA runtime options */
 
-extern u8 acpi_gbl_all_methods_serialized;
 extern u8 acpi_gbl_copy_dsdt_locally;
 extern u8 acpi_gbl_create_osi_method;
 extern u8 acpi_gbl_disable_auto_repair;
Signature · 1 line
1.7.10
author
#5 lore raw

PATCH 5/5 ACPICA: Enable auto-serialization as a default kernel behavior.

In reply to Lv Zheng

The following commit introduces the auto-serialization facility as a workaround that can be enabled by "acpi_auto_serialize":
Subject: ACPICA: Add auto-serialization support for ill-behaved control
methods.
This feature marks control methods that create named objects as "Serialized" to avoid unwanted AE_ALREADY_EXISTS control method evaluation failures.

The feature is extended or completed by the following commits:
1. An extension to fix a kernel bugzilla bug (Reference 1):
Subject: ACPICA: Add additional named objects for the auto-serialize
method scan.
2. A completion to fix a community reported bug (Reference 2):
Subject: ACPICA: Ignore sync_level for methods that have been
auto-serialized.

This patch enables auto-serialization as a default kernel behavior to encourage people to use it. The kernel parameter is also changed from "acpi_auto_serialize" to "acpi_no_auto_serialize" to allow it to be disabled at runtime.

For new issues are detected and fixed, please:
1. Before fixing it:
1.1. Revert only this commit to restore this feature as a workaround;
2. Afeter fixing it:
2.1. Merge new fixes;
2.2. Add Subjects/Reference URLs of the new fixes into the description

        of this commit;

2.3. Merge the description updated this commit to re-enable this feature
as a default kernel behavior.

Reference 1: https://bugzilla.kernel.org/show_bug.cgi?id=52191
Reference 2: http://www.spinics.net/lists/linux-acpi/msg49496.html

---
 Documentation/kernel-parameters.txt |    8 ++++----
 drivers/acpi/acpica/acglobal.h      |    2 +-
 drivers/acpi/osl.c                  |   12 ++++++------
 3 files changed, 11 insertions(+), 11 deletions(-)
Documentation/kernel-parameters.txt +4 -4
index a159537..91f0be8 100644
@@ -229,13 +229,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			use by PCI
 			Format: <irq>,<irq>...
 
-	acpi_auto_serialize	[HW,ACPI]
-			Enable auto-serialization of AML methods
+	acpi_no_auto_serialize	[HW,ACPI]
+			Disable auto-serialization of AML methods
 			AML control methods that contain the opcodes to create
 			named objects will be marked as "Serialized" by the
 			auto-serialization feature.
-			This feature is disabled by default.
-			This option allows to turn on the feature.
+			This feature is enabled by default.
+			This option allows to turn off the feature.
 
 	acpi_no_auto_ssdt	[HW,ACPI] Disable automatic loading of SSDT
 
drivers/acpi/acpica/acglobal.h +1 -1
index ea0f838..49bbc71 100644
@@ -99,7 +99,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE);
  * that create named objects are marked Serialized in order to prevent
  * possible run-time problems if they are entered by more than one thread.
  */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, FALSE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE);
 
 /*
  * Create the predefined _OSI method in the namespace? Default is TRUE
drivers/acpi/osl.c +6 -6
index 928f0c2..d40d6dc 100644
@@ -1538,20 +1538,20 @@ static int __init osi_setup(char *str)
 __setup("acpi_osi=", osi_setup);
 
 /*
- * Enable the auto-serialization of named objects creation methods.
+ * Disable the auto-serialization of named objects creation methods.
  *
- * This feature is disabled by default.  It marks the AML control methods
+ * This feature is enabled by default.  It marks the AML control methods
  * that contain the opcodes to create named objects as "Serialized".
  */
-static int __init acpi_auto_serialize_setup(char *str)
+static int __init acpi_no_auto_serialize_setup(char *str)
 {
-	acpi_gbl_auto_serialize_methods = TRUE;
-	pr_info("ACPI: auto-serialization enabled\n");
+	acpi_gbl_auto_serialize_methods = FALSE;
+	pr_info("ACPI: auto-serialization disabled\n");
 
 	return 1;
 }
 
-__setup("acpi_auto_serialize", acpi_auto_serialize_setup);
+__setup("acpi_no_auto_serialize", acpi_no_auto_serialize_setup);
 
 /* Check of resource interference between native drivers and ACPI
  * OperationRegions (SystemIO and System Memory only).
Signature · 1 line
1.7.10
author
#4 lore raw

PATCH 4/5 ACPICA: Ignore sync_level for methods that have been auto-serialized.

In reply to Lv Zheng

From: Bob Moore <[email protected]>

Cannot use a sync_level for methods that have been serialized at load-time or runtime because this may interfere with any existing use of sync_levels within the ASL code. So, we simply ignore the sync_level for these methods, thus preserving any existing sync_level priorities. Note, the use of sync_levels is actually rather rare within BIOS ASL code.

References: http://www.spinics.net/lists/linux-acpi/msg49496.html

---
 drivers/acpi/acpica/acobject.h |    3 ++-
 drivers/acpi/acpica/dsmethod.c |   24 +++++++++++++++++++-----
 2 files changed, 21 insertions(+), 6 deletions(-)
drivers/acpi/acpica/acobject.h +2 -1
index 1a4d618..22fb644 100644
@@ -193,7 +193,8 @@ struct acpi_object_method {
 #define ACPI_METHOD_INTERNAL_ONLY       0x02	/* Method is implemented internally (_OSI) */
 #define ACPI_METHOD_SERIALIZED          0x04	/* Method is serialized */
 #define ACPI_METHOD_SERIALIZED_PENDING  0x08	/* Method is to be marked serialized */
-#define ACPI_METHOD_MODIFIED_NAMESPACE  0x10	/* Method modified the namespace */
+#define ACPI_METHOD_IGNORE_SYNC_LEVEL   0x10	/* Method was auto-serialized at table load time */
+#define ACPI_METHOD_MODIFIED_NAMESPACE  0x20	/* Method modified the namespace */
 
 /******************************************************************************
  *
drivers/acpi/acpica/dsmethod.c +19 -5
index 73764c7..3c7f737 100644
@@ -175,8 +175,15 @@ acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state,
 	 * At this point, we know we have a Named object opcode.
 	 * Mark the method as serialized. Later code will create a mutex for
 	 * this method to enforce serialization.
+	 *
+	 * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the
+	 * Sync Level mechanism for this method, even though it is now serialized.
+	 * Otherwise, there can be conflicts with existing ASL code that actually
+	 * uses sync levels.
 	 */
-	walk_state->method_desc->method.info_flags |= ACPI_METHOD_SERIALIZED;
+	walk_state->method_desc->method.sync_level = 0;
+	walk_state->method_desc->method.info_flags |=
+	    (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "Method serialized [%4.4s] %p - [%s] (%4.4X)\n",
@@ -349,13 +356,19 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
 		/*
 		 * The current_sync_level (per-thread) must be less than or equal to
 		 * the sync level of the method. This mechanism provides some
-		 * deadlock prevention
+		 * deadlock prevention.
+		 *
+		 * If the method was auto-serialized, we just ignore the sync level
+		 * mechanism, because auto-serialization of methods can interfere
+		 * with ASL code that actually uses sync levels.
 		 *
 		 * Top-level method invocation has no walk state at this point
 		 */
 		if (walk_state &&
-		    (walk_state->thread->current_sync_level >
-		     obj_desc->method.mutex->mutex.sync_level)) {
+		    (!(obj_desc->method.
+		       info_flags & ACPI_METHOD_IGNORE_SYNC_LEVEL))
+		    && (walk_state->thread->current_sync_level >
+			obj_desc->method.mutex->mutex.sync_level)) {
 			ACPI_ERROR((AE_INFO,
 				    "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
 				    acpi_ut_get_node_name(method_node),
@@ -800,7 +813,8 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
 			method_desc->method.info_flags &=
 			    ~ACPI_METHOD_SERIALIZED_PENDING;
 			method_desc->method.info_flags |=
-			    ACPI_METHOD_SERIALIZED;
+			    (ACPI_METHOD_SERIALIZED |
+			     ACPI_METHOD_IGNORE_SYNC_LEVEL);
 			method_desc->method.sync_level = 0;
 		}
 
Signature · 1 line
1.7.10