Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

time: Add mechanism to recognize clocksource in time_get_snapshot

System time snapshots are not conveying information about the current
clocksource which was used, but callers like the PTP KVM guest
implementation have the requirement to evaluate the clocksource type to
select the appropriate mechanism.

Introduce a clocksource id field in struct clocksource which is by default
set to CSID_GENERIC (0). Clocksource implementations can set that field to
a value which allows to identify the clocksource.

Store the clocksource id of the current clocksource in the
system_time_snapshot so callers can evaluate which clocksource was used to
take the snapshot and act accordingly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20201209060932.212364-5-jianyong.wu@arm.com

authored by

Thomas Gleixner and committed by
Marc Zyngier
b2c67cbe a8cf291b

+27 -5
+6
include/linux/clocksource.h
··· 17 17 #include <linux/timer.h> 18 18 #include <linux/init.h> 19 19 #include <linux/of.h> 20 + #include <linux/clocksource_ids.h> 20 21 #include <asm/div64.h> 21 22 #include <asm/io.h> 22 23 ··· 63 62 * 400-499: Perfect 64 63 * The ideal clocksource. A must-use where 65 64 * available. 65 + * @id: Defaults to CSID_GENERIC. The id value is captured 66 + * in certain snapshot functions to allow callers to 67 + * validate the clocksource from which the snapshot was 68 + * taken. 66 69 * @flags: Flags describing special properties 67 70 * @enable: Optional function to enable the clocksource 68 71 * @disable: Optional function to disable the clocksource ··· 105 100 const char *name; 106 101 struct list_head list; 107 102 int rating; 103 + enum clocksource_ids id; 108 104 enum vdso_clock_mode vdso_clock_mode; 109 105 unsigned long flags; 110 106
+11
include/linux/clocksource_ids.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_CLOCKSOURCE_IDS_H 3 + #define _LINUX_CLOCKSOURCE_IDS_H 4 + 5 + /* Enum to give clocksources a unique identifier */ 6 + enum clocksource_ids { 7 + CSID_GENERIC = 0, 8 + CSID_MAX, 9 + }; 10 + 11 + #endif
+7 -5
include/linux/timekeeping.h
··· 3 3 #define _LINUX_TIMEKEEPING_H 4 4 5 5 #include <linux/errno.h> 6 + #include <linux/clocksource_ids.h> 6 7 7 8 /* Included from linux/ktime.h */ 8 9 ··· 244 243 * @cs_was_changed_seq: The sequence number of clocksource change events 245 244 */ 246 245 struct system_time_snapshot { 247 - u64 cycles; 248 - ktime_t real; 249 - ktime_t raw; 250 - unsigned int clock_was_set_seq; 251 - u8 cs_was_changed_seq; 246 + u64 cycles; 247 + ktime_t real; 248 + ktime_t raw; 249 + enum clocksource_ids cs_id; 250 + unsigned int clock_was_set_seq; 251 + u8 cs_was_changed_seq; 252 252 }; 253 253 254 254 /**
+2
kernel/time/clocksource.c
··· 920 920 921 921 clocksource_arch_init(cs); 922 922 923 + if (WARN_ON_ONCE((unsigned int)cs->id >= CSID_MAX)) 924 + cs->id = CSID_GENERIC; 923 925 if (cs->vdso_clock_mode < 0 || 924 926 cs->vdso_clock_mode >= VDSO_CLOCKMODE_MAX) { 925 927 pr_warn("clocksource %s registered with invalid VDSO mode %d. Disabling VDSO support.\n",
+1
kernel/time/timekeeping.c
··· 1048 1048 do { 1049 1049 seq = read_seqcount_begin(&tk_core.seq); 1050 1050 now = tk_clock_read(&tk->tkr_mono); 1051 + systime_snapshot->cs_id = tk->tkr_mono.clock->id; 1051 1052 systime_snapshot->cs_was_changed_seq = tk->cs_was_changed_seq; 1052 1053 systime_snapshot->clock_was_set_seq = tk->clock_was_set_seq; 1053 1054 base_real = ktime_add(tk->tkr_mono.base,