summaryrefslogtreecommitdiff
path: root/drivers/acpi/acpica/dscontrol.c
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2017-11-17 15:40:18 -0800
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-11-27 01:20:29 +0100
commit164a08cee1358e360c47fcb26a7720461d5853a5 (patch)
treeda44cdbbbe77db422208e3271e123dbf8468f28a /drivers/acpi/acpica/dscontrol.c
parent29ad1f88ab7dd6c220ff9f5b9faed718b443f4a4 (diff)
ACPICA: Dispatcher: Introduce timeout mechanism for infinite loop detection
ACPICA commit 9605023e7e6d1f05581502766c8cf2905bcc03d9 This patch implements a new infinite loop detection mechanism to replace the old one, it uses acpi_os_get_timer() to limit loop execution into a determined time slice. This is useful in case some hardware/firmware operations really require the AML interpreter to wait while the old mechanism could expire too fast on recent machines. The new mechanism converts old acpi_gbl_max_loop_iterations to store the user configurable value for the new mechanism in order to allow users to be still able to configure this value for acpiexec via command line. This patch also removes wrong initilization code of acpi_gbl_max_loop_iterations accordingly (it should have been initialized by ACPI_INIT_GLOBAL, and the default value is also properly tuned for acpiexec). Reported by M. Foronda, fixed by Lv Zheng. Link: https://github.com/acpica/acpica/commit/9605023e Link: https://bugzilla.kernel.org/show_bug.cgi?id=156501 Reported-by: M. Foronda <josemauricioforonda@gmail.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Erik Schmauss <erik.schmauss@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/dscontrol.c')
-rw-r--r--drivers/acpi/acpica/dscontrol.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c
index f470e81b0499..244075dbc03a 100644
--- a/drivers/acpi/acpica/dscontrol.c
+++ b/drivers/acpi/acpica/dscontrol.c
@@ -118,6 +118,8 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
control_state->control.package_end =
walk_state->parser_state.pkg_end;
control_state->control.opcode = op->common.aml_opcode;
+ control_state->control.loop_timeout = acpi_os_get_timer() +
+ (u64)(acpi_gbl_max_loop_iterations * ACPI_100NSEC_PER_SEC);
/* Push the control state on this walk's control stack */
@@ -206,14 +208,14 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
/* Predicate was true, the body of the loop was just executed */
/*
- * This loop counter mechanism allows the interpreter to escape
- * possibly infinite loops. This can occur in poorly written AML
- * when the hardware does not respond within a while loop and the
- * loop does not implement a timeout.
+ * This infinite loop detection mechanism allows the interpreter
+ * to escape possibly infinite loops. This can occur in poorly
+ * written AML when the hardware does not respond within a while
+ * loop and the loop does not implement a timeout.
*/
- control_state->control.loop_count++;
- if (control_state->control.loop_count >
- acpi_gbl_max_loop_iterations) {
+ if (ACPI_TIME_AFTER(acpi_os_get_timer(),
+ control_state->control.
+ loop_timeout)) {
status = AE_AML_INFINITE_LOOP;
break;
}