summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/debug.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2016-11-16 11:48:41 +0300
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-02-07 09:27:13 +0300
commitea417aa8a38bc7db929281d6dc4b671e75f51844 (patch)
tree61f70f0f578d9ce66d40bcec03f727b7df256d76 /arch/s390/kernel/debug.c
parent8676caa4fb7fc02b2c76842a0024919d0caa4b8d (diff)
downloadlinux-ea417aa8a38bc7db929281d6dc4b671e75f51844.tar.xz
s390/debug: make debug event time stamps relative to the boot TOD clock
The debug features currently uses absolute TOD time stamps for the debug events. Given that the TOD clock can jump forward and backward due to STP sync checks the order of debug events can get obfuscated. Replace the absolute TOD time stamps with a delta to the IPL time stamp. On a STP sync check the TOD clock correction is added to the IPL time stamp as well to make the deltas unaffected by STP sync check. The readout of the debug feature entries will convert the deltas back to absolute time stamps based on the Unix epoch. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/debug.c')
-rw-r--r--arch/s390/kernel/debug.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 79f8ae933520..20a5a4286368 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -866,7 +866,7 @@ static inline void
debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
int exception)
{
- active->id.stck = get_tod_clock_fast();
+ active->id.stck = get_tod_clock_fast() - sched_clock_base_cc;
active->id.fields.cpuid = smp_processor_id();
active->caller = __builtin_return_address(0);
active->id.fields.exception = exception;
@@ -1455,23 +1455,24 @@ int
debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
int area, debug_entry_t * entry, char *out_buf)
{
- struct timespec64 time_spec;
+ unsigned long sec, usec;
char *except_str;
unsigned long caller;
int rc = 0;
unsigned int level;
level = entry->id.fields.level;
- stck_to_timespec64(entry->id.stck, &time_spec);
+ sec = (entry->id.stck >> 12) + (sched_clock_base_cc >> 12);
+ sec = sec - (TOD_UNIX_EPOCH >> 12);
+ usec = do_div(sec, USEC_PER_SEC);
if (entry->id.fields.exception)
except_str = "*";
else
except_str = "-";
caller = (unsigned long) entry->caller;
- rc += sprintf(out_buf, "%02i %011lld:%06lu %1u %1s %02i %p ",
- area, (long long)time_spec.tv_sec,
- time_spec.tv_nsec / 1000, level, except_str,
+ rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %02i %p ",
+ area, sec, usec, level, except_str,
entry->id.fields.cpuid, (void *)caller);
return rc;
}