Introduce a fast boot clock and add it as trace clock
Subsystems (2)
cover Introduce a fast boot clock and add it as trace clock
Currently no trace clock can account for suspend time, using monotonic during tracing in the suspend path means the trace times wont be advaced. Using the boot clock with ktime_get_with_offset is not an option due to live locking concerns in NMI context as suggested by Thomas [1].
These patches add a fast boot clock based on fast monotonic clock and adds a trace clock based on it which solves both these issues.
Changes since RFC:
- Moved the ktime_t offsets to the end of tk_fast
- use unlikely to optimize for the monotonic case
[1] https://lkml.org/lkml/2016/11/20/75
Joel Fernandes (2):
timekeeping: Introduce a fast boot clock derived from fast monotonic
clock
trace: Add an option for boot clock as trace clock
kernel/time/timekeeping.c | 36 ++++++++++++++++++++++++++++++------ kernel/trace/trace.c | 1 + 2 files changed, 31 insertions(+), 6 deletions(-)
Signature · 1 line
2.8.0.rc3.226.g39d4020
PATCH 1/2 timekeeping: Introduce a fast boot clock derived from fast monotonic clock
Introduce a fast boot clock. It accounts for suspend time and is based on the fast monotonic clock so that its safe to use for tracing. Next patch adds the clock to trace clock.
--- kernel/time/timekeeping.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-)
kernel/time/timekeeping.c +30 -6
@@ -56,6 +56,12 @@ static struct timekeeper shadow_timekeeper;struct tk_fast {seqcount_t seq;struct tk_read_base base[2 ]; + +/* +* first dimension is based on lower seq bit, +* second dimension is for offset type (real, boot, tai) +*/ +ktime_t offsets[2 ][3 ]; };static struct tk_fast tk_fast_mono____cacheline_aligned ;
@@ -350,14 +356,20 @@ static void update_fast_timekeeper(struct tk_read_base *tkr, struct tk_fast *tkf/* Force readers off to base[1] */ raw_write_seqcount_latch (&tkf->seq); -/* Update base[0] */ +/* Update base[0] and offsets*/ memcpy (base, tkr,sizeof (*base)); + tkf->offsets[0 ][TK_OFFS_REAL ] = tk_core.timekeeper.offs_real; + tkf->offsets[0 ][TK_OFFS_BOOT ] = tk_core.timekeeper.offs_boot; + tkf->offsets[0 ][TK_OFFS_TAI ] = tk_core.timekeeper.offs_tai;/* Force readers back to base[0] */ raw_write_seqcount_latch (&tkf->seq); -/* Update base[1] */ +/* Update base[1] and offsets*/ memcpy (base +1 , base,sizeof (*base)); + tkf->offsets[1 ][TK_OFFS_REAL ] = tk_core.timekeeper.offs_real; + tkf->offsets[1 ][TK_OFFS_BOOT ] = tk_core.timekeeper.offs_boot; + tkf->offsets[1 ][TK_OFFS_TAI ] = tk_core.timekeeper.offs_tai; }/**
@@ -392,16 +404,23 @@ static void update_fast_timekeeper(struct tk_read_base *tkr, struct tk_fast *tkf* of the following timestamps. Callers need to be aware of that and * deal with it. */ -static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) +static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf, int offset) { struct tk_read_base *tkr; unsigned int seq; u64 now; + ktime_t *off; do { seq = raw_read_seqcount_latch(&tkf->seq); tkr = tkf->base + (seq & 0x01); - now = ktime_to_ns(tkr->base); + + if (unlikely((offset >= 0))) { + off = tkf->offsets[seq & 0x01]; + now = ktime_to_ns(ktime_add(tkr->base, off[offset])); + } else { + now = ktime_to_ns(tkr->base); + } now += timekeeping_delta_to_ns(tkr, clocksource_delta(
@@ -415,16 +434,21 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf)u64 ktime_get_mono_fast_ns (void ) { -return __ktime_get_fast_ns (&tk_fast_mono); +return __ktime_get_fast_ns (&tk_fast_mono,-1 ); }EXPORT_SYMBOL_GPL (ktime_get_mono_fast_ns);u64 ktime_get_raw_fast_ns (void ) { -return __ktime_get_fast_ns (&tk_fast_raw); +return __ktime_get_fast_ns (&tk_fast_raw,-1 ); }EXPORT_SYMBOL_GPL (ktime_get_raw_fast_ns); +u64 ktime_get_boot_fast_ns (void ) +{ +return __ktime_get_fast_ns (&tk_fast_mono,TK_OFFS_BOOT ); +} +/* Suspend-time cycles value for halted fast timekeeper. */ static cycle_t cycles_at_suspend;
Signature · 1 line
2.8.0.rc3.226.g39d4020
PATCH 2/2 trace: Add an option for boot clock as trace clock
In reply to Joel FernandesUnlike monotonic clock, boot clock as a trace clock will account for time spent in suspend useful for tracing suspend/resume. This uses earlier introduced infrastructure for using the fast boot clock.
--- kernel/trace/trace.c | 1 + 1 file changed, 1 insertion(+)
kernel/trace/trace.c +1 -0
@@ -1125,6 +1125,7 @@ static struct { { trace_clock, "perf", 1 }, { ktime_get_mono_fast_ns, "mono", 1 }, { ktime_get_raw_fast_ns, "mono_raw", 1 }, + { ktime_get_boot_fast_ns, "boot", 1 },ARCH_TRACE_CLOCKS };
Signature · 1 line
2.8.0.rc3.226.g39d4020
kbuild test robot
build botRe: [PATCH 2/2] trace: Add an option for boot clock as trace clock
url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/timekeeping-Introduce-a-fast-boot-clock-derived-from-fast-monotonic-clock/20161122-063314 config: i386-randconfig-x004-201647 (attached…
Hi Joel,
[auto build test ERROR on tip/timers/core]
[also build test ERROR on v4.9-rc6 next-20161117]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/timekeeping-Introduce-a-fast-boot-clock-derived-from-fast-monotonic-clock/20161122-063314
config: i386-randconfig-x004-201647 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce:
# save the attached .config to linux build tree
make ARCH=i386 All errors (new ones prefixed by >>):
>> kernel/trace/trace.c:1128:4: error: 'ktime_get_boot_fast_ns' undeclared here (not in a function)
{ ktime_get_boot_fast_ns, "boot", 1 },
^~~~~~~~~~~~~~~~~~~~~~vim +/ktime_get_boot_fast_ns +1128 kernel/trace/trace.c
1122 { trace_clock_global, "global", 1 },
1123 { trace_clock_counter, "counter", 0 },
1124 { trace_clock_jiffies, "uptime", 0 },
1125 { trace_clock, "perf", 1 },
1126 { ktime_get_mono_fast_ns, "mono", 1 },
1127 { ktime_get_raw_fast_ns, "mono_raw", 1 },
> 1128 { ktime_get_boot_fast_ns, "boot", 1 }, 1129 ARCH_TRACE_CLOCKS
1130 };
1131
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH 2/2] trace: Add an option for boot clock as trace clock
Quoted 10 lines · kbuild test robot
Hi Joel,
[auto build test ERROR on tip/timers/core]
[also build test ERROR on v4.9-rc6 next-20161117]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/timekeeping-Introduce-a-fast-boot-clock-derived-from-fast-monotonic-clock/20161122-063314
config: i386-randconfig-x004-201647 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce:
Quoted 7 lines
# save the attached .config to linux build tree make ARCH=i386All errors (new ones prefixed by >>):
Quoted 1 line
Quoted 1 line
kernel/trace/trace.c:1128:4: error: 'ktime_get_boot_fast_ns' undeclared here (not in a function){ ktime_get_boot_fast_ns, "boot", 1 },
Looks like I didn't have enough coffee today. I did test the patches so this is rather strange, I must have missed the header export while respinning from another tree. I will fix this, respin and post another version later while waiting meanwhile for any other comments (and addressing Steven's documentation comment).
Thanks,
Joel
Quoted 18 lines
^~~~~~~~~~~~~~~~~~~~~~vim +/ktime_get_boot_fast_ns +1128
kernel/trace/trace.c1122 { trace_clock_global, "global", 1 }, 1123 { trace_clock_counter, "counter", 0 }, 1124 { trace_clock_jiffies, "uptime", 0 }, 1125 { trace_clock, "perf", 1 }, 1126 { ktime_get_mono_fast_ns, "mono", 1 }, 1127 { ktime_get_raw_fast_ns, "mono_raw", 1 }, > 1128 { ktime_get_boot_fast_ns, "boot", 1 }, 1129 ARCH_TRACE_CLOCKS1130 };
1131---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Quoted 11 lines · Joel Fernandes
Currently no trace clock can account for suspend time, using monotonic during tracing in the suspend path means the trace times wont be advaced. Using the boot clock with
ktime_get_with_offsetis not an option due to live locking concerns in NMI context as suggested by Thomas [1].
These patches add a fast boot clock based on fast monotonic clock and adds a trace clock based on it which solves both these issues.Changes since RFC:
- Moved thektime_toffsets to the end oftk_fast
- use unlikely to optimize for the monotonic case
Please scratch these patches, I didn't make a change I had to since the RFC. Sorry for the noise!
Quoted 18 lines
[1] https://lkml.org/lkml/2016/11/20/75
Joel Fernandes (2):
timekeeping: Introduce a fast boot clock derived from fast monotonic
clock
trace: Add an option for boot clock as trace clockkernel/time/timekeeping.c | 36 ++++++++++++++++++++++++++++++------ kernel/trace/trace.c | 1 + 2 files changed, 31 insertions(+), 6 deletions(-)Cc: Steven Rostedt <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Ingo Molnar <[email protected]>
--
2.8.0.rc3.226.g39d4020