public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] Added "Preserve Boot Time Support"
@ 2017-05-19 10:16 Bogdan Mirea
  2017-05-21 21:36 ` Thomas Gleixner
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Bogdan Mirea @ 2017-05-19 10:16 UTC (permalink / raw)
  To: linux-kernel, john.stultz, tglx, ore, kernel; +Cc: Bogdan Mirea

This option enables Boot Time Preservation between Bootloader and
Linux Kernel. It is based on the idea that the Bootloader (or any
other early firmware) will start the HW Timer and Linux Kernel will
count the time starting with the cycles elapsed since timer start.

The sched_clock part is preserving boottime for kmsg which should be in
sync with system uptime. The system uptime part is driver specific and I
updated the arm_arch_timer with an arch_timer_setsystime() function
which will call do_settimeofday64() with the values read from arch timer
counter.

This way both kmsg and uptime will be in sync, otherwise inconsistencies
will appear between the two.

The "preserve_boot_time" parameter should be appended to kernel cmdline
from bootloader for kernel acknowledgment that the timer is running in
bootloader.

Signed-off-by: Bogdan Mirea <Bogdan-Stefan_mirea@mentor.com>
---
 drivers/clocksource/arm_arch_timer.c | 33 +++++++++++++++++++++++++++++++++
 kernel/time/Kconfig                  | 12 ++++++++++++
 kernel/time/sched_clock.c            | 14 ++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5152b38..95699cd 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -475,6 +475,35 @@ struct timecounter *arch_timer_get_timecounter(void)
 	return &timecounter;
 }
 
+#ifdef CONFIG_BOOT_TIME_PRESERVE
+/*
+ * Set the real system time(including the time spent in bootloader)
+ * based on the timer counter.
+ */
+
+#ifndef BOOT_TIME_PRESERVE_CMDLINE
+	#define BOOT_TIME_PRESERVE_CMDLINE "preserve_boot_time"
+#endif
+void arch_timer_setsystime(void)
+{
+	static struct timespec64 boot_ts;
+	static cycles_t cycles;
+	unsigned long long nsecs;
+
+	if (!strstr(boot_command_line, BOOT_TIME_PRESERVE_CMDLINE))
+		return;
+
+	cycles = arch_timer_read_counter() ? arch_timer_read_counter() : 0;
+
+	nsecs = clocksource_cyc2ns(cycles, clocksource_counter.mult,
+				   clocksource_counter.shift);
+	timespec64_add_ns(&boot_ts, nsecs);
+
+	if (do_settimeofday64(&boot_ts))
+		pr_warn("arch_timer: unable to set systime\n");
+}
+#endif /* CONFIG_BOOT_TIME_PRESERVE */
+
 static void __init arch_counter_register(unsigned type)
 {
 	u64 start_count;
@@ -504,6 +533,10 @@ static void __init arch_counter_register(unsigned type)
 
 	/* 56 bits minimum, so we assume worst case rollover */
 	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
+#ifdef CONFIG_BOOT_TIME_PRESERVE
+	/* Set systime */
+	arch_timer_setsystime();
+#endif /* CONFIG_BOOT_TIME_PRESERVE */
 }
 
 static void arch_timer_stop(struct clock_event_device *clk)
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index 4008d9f..1edd518 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -193,5 +193,17 @@ config HIGH_RES_TIMERS
 	  hardware is not capable then this option only increases
 	  the size of the kernel image.
 
+config BOOT_TIME_PRESERVE
+	bool "Preserve Boot Time Support"
+	default n
+	help
+	  This option enables Boot Time Preservation between Bootloader and
+	  Linux Kernel. It is based on the idea that the Bootloader (or any
+	  other early firmware) will start the HW Timer and Linux Kernel will
+	  count the time starting with the cycles elapsed since timer start.
+
+	  The "preserve_boot_time" parameter should be appended to kernel cmdline
+	  from bootloader for kernel acknowledgment that the timer is running in
+	  bootloader.
 endmenu
 endif
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index a26036d..efd66bf 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -193,6 +193,20 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
 	/* Update epoch for new counter and update 'epoch_ns' from old counter*/
 	new_epoch = read();
 	cyc = cd.actual_read_sched_clock();
+
+#ifdef CONFIG_BOOT_TIME_PRESERVE
+
+#ifndef BOOT_TIME_PRESERVE_CMDLINE
+	#define BOOT_TIME_PRESERVE_CMDLINE "preserve_boot_time"
+#endif
+	if (strstr(boot_command_line, BOOT_TIME_PRESERVE_CMDLINE)) {
+		cyc = new_epoch;
+		rd.sched_clock_mask = new_mask;
+		rd.mult			= new_mult;
+		rd.shift		= new_shift;
+	}
+#endif /* CONFIG_BOOT_TIME_PRESERVE */
+
 	ns = rd.epoch_ns + cyc_to_ns((cyc - rd.epoch_cyc) & rd.sched_clock_mask, rd.mult, rd.shift);
 	cd.actual_read_sched_clock = read;
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-05-30 10:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-19 10:16 [PATCH v3] Added "Preserve Boot Time Support" Bogdan Mirea
2017-05-21 21:36 ` Thomas Gleixner
2017-05-23 15:50   ` Mirea, Bogdan-Stefan
2017-05-23 16:39     ` Thomas Gleixner
2017-05-24  9:35       ` Mirea, Bogdan-Stefan
2017-05-26 10:04         ` Thomas Gleixner
2017-05-30 10:07           ` Mirea, Bogdan-Stefan
2017-05-25 17:05 ` Pavel Machek
2017-05-26 11:09 ` Mark Rutland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox