Blob Blame History Raw
From: Bart Van Assche <bvanassche@acm.org>
Date: Wed, 17 Oct 2018 13:24:56 -0700
Subject: ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer()
Patch-mainline: v4.20-rc1
Git-commit: 83b2348e2755db48fa8f40fdb791f366fabc0ba0
References: bsc#1117419

Since acpi_os_get_timer() may be called after the timer subsystem has
been suspended, use the jiffies counter instead of ktime_get(). This
patch avoids that the following warning is reported during hibernation:

WARNING: CPU: 0 PID: 612 at kernel/time/timekeeping.c:751 ktime_get+0x116/0x120
RIP: 0010:ktime_get+0x116/0x120
Call Trace:
 acpi_os_get_timer+0xe/0x30
 acpi_ds_exec_begin_control_op+0x175/0x1de
 acpi_ds_exec_begin_op+0x2c7/0x39a
 acpi_ps_create_op+0x573/0x5e4
 acpi_ps_parse_loop+0x349/0x1220
 acpi_ps_parse_aml+0x25b/0x6da
 acpi_ps_execute_method+0x327/0x41b
 acpi_ns_evaluate+0x4e9/0x6f5
 acpi_ut_evaluate_object+0xd9/0x2f2
 acpi_rs_get_method_data+0x8f/0x114
 acpi_walk_resources+0x122/0x1b6
 acpi_pci_link_get_current.isra.2+0x157/0x280
 acpi_pci_link_set+0x32f/0x4a0
 irqrouter_resume+0x58/0x80
 syscore_resume+0x84/0x380
 hibernation_snapshot+0x20c/0x4f0
 hibernate+0x22d/0x3a6
 state_store+0x99/0xa0
 kobj_attr_store+0x37/0x50
 sysfs_kf_write+0x87/0xa0
 kernfs_fop_write+0x1a5/0x240
 __vfs_write+0xd2/0x410
 vfs_write+0x101/0x250
 ksys_write+0xab/0x120
 __x64_sys_write+0x43/0x50
 do_syscall_64+0x71/0x220
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

Fixes: 164a08cee135 (ACPICA: Dispatcher: Introduce timeout mechanism for infinite loop detection)
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: 4.16+ <stable@vger.kernel.org> # 4.16+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Lee, Chun-Yi <jlee@suse.com>
---
 drivers/acpi/osl.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -614,15 +614,18 @@ void acpi_os_stall(u32 us)
 }
 
 /*
- * Support ACPI 3.0 AML Timer operand
- * Returns 64-bit free-running, monotonically increasing timer
- * with 100ns granularity
+ * Support ACPI 3.0 AML Timer operand. Returns a 64-bit free-running,
+ * monotonically increasing timer with 100ns granularity. Do not use
+ * ktime_get() to implement this function because this function may get
+ * called after timekeeping has been suspended. Note: calling this function
+ * after timekeeping has been suspended may lead to unexpected results
+ * because when timekeeping is suspended the jiffies counter is not
+ * incremented. See also timekeeping_suspend().
  */
 u64 acpi_os_get_timer(void)
 {
-	u64 time_ns = ktime_to_ns(ktime_get());
-	do_div(time_ns, 100);
-	return time_ns;
+	return (get_jiffies_64() - INITIAL_JIFFIES) *
+		(ACPI_100NSEC_PER_SEC / HZ);
 }
 
 acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)