aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_output.c
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2016-06-23 12:45:36 -0400
committerSteven Rostedt <rostedt@goodmis.org>2016-09-02 12:47:51 -0400
commite7c15cd8a113335cf7154f027c9c8da1a92238ee (patch)
treeb6f7c3ac217af4203489e874c359c409d63f7c27 /kernel/trace/trace_output.c
parent8861dd303cba879bae9a9dcee74042fb642bf03b (diff)
tracing: Added hardware latency tracer
The hardware latency tracer has been in the PREEMPT_RT patch for some time. It is used to detect possible SMIs or any other hardware interruptions that the kernel is unaware of. Note, NMIs may also be detected, but that may be good to note as well. The logic is pretty simple. It simply creates a thread that spins on a single CPU for a specified amount of time (width) within a periodic window (window). These numbers may be adjusted by their cooresponding names in /sys/kernel/tracing/hwlat_detector/ The defaults are window = 1000000 us (1 second) width = 500000 us (1/2 second) The loop consists of: t1 = trace_clock_local(); t2 = trace_clock_local(); Where trace_clock_local() is a variant of sched_clock(). The difference of t2 - t1 is recorded as the "inner" timestamp and also the timestamp t1 - prev_t2 is recorded as the "outer" timestamp. If either of these differences are greater than the time denoted in /sys/kernel/tracing/tracing_thresh then it records the event. When this tracer is started, and tracing_thresh is zero, it changes to the default threshold of 10 us. The hwlat tracer in the PREEMPT_RT patch was originally written by Jon Masters. I have modified it quite a bit and turned it into a tracer. Based-on-code-by: Jon Masters <jcm@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_output.c')
-rw-r--r--kernel/trace/trace_output.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 0bb9cf2d53e6..d67a562df259 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -1098,6 +1098,57 @@ static struct trace_event trace_user_stack_event = {
1098 .funcs = &trace_user_stack_funcs, 1098 .funcs = &trace_user_stack_funcs,
1099}; 1099};
1100 1100
1101/* TRACE_HWLAT */
1102static enum print_line_t
1103trace_hwlat_print(struct trace_iterator *iter, int flags,
1104 struct trace_event *event)
1105{
1106 struct trace_entry *entry = iter->ent;
1107 struct trace_seq *s = &iter->seq;
1108 struct hwlat_entry *field;
1109
1110 trace_assign_type(field, entry);
1111
1112 trace_seq_printf(s, "#%-5u inner/outer(us): %4llu/%-5llu ts:%ld.%09ld\n",
1113 field->seqnum,
1114 field->duration,
1115 field->outer_duration,
1116 field->timestamp.tv_sec,
1117 field->timestamp.tv_nsec);
1118
1119 return trace_handle_return(s);
1120}
1121
1122
1123static enum print_line_t
1124trace_hwlat_raw(struct trace_iterator *iter, int flags,
1125 struct trace_event *event)
1126{
1127 struct hwlat_entry *field;
1128 struct trace_seq *s = &iter->seq;
1129
1130 trace_assign_type(field, iter->ent);
1131
1132 trace_seq_printf(s, "%llu %lld %ld %09ld %u\n",
1133 field->duration,
1134 field->outer_duration,
1135 field->timestamp.tv_sec,
1136 field->timestamp.tv_nsec,
1137 field->seqnum);
1138
1139 return trace_handle_return(s);
1140}
1141
1142static struct trace_event_functions trace_hwlat_funcs = {
1143 .trace = trace_hwlat_print,
1144 .raw = trace_hwlat_raw,
1145};
1146
1147static struct trace_event trace_hwlat_event = {
1148 .type = TRACE_HWLAT,
1149 .funcs = &trace_hwlat_funcs,
1150};
1151
1101/* TRACE_BPUTS */ 1152/* TRACE_BPUTS */
1102static enum print_line_t 1153static enum print_line_t
1103trace_bputs_print(struct trace_iterator *iter, int flags, 1154trace_bputs_print(struct trace_iterator *iter, int flags,
@@ -1233,6 +1284,7 @@ static struct trace_event *events[] __initdata = {
1233 &trace_bputs_event, 1284 &trace_bputs_event,
1234 &trace_bprint_event, 1285 &trace_bprint_event,
1235 &trace_print_event, 1286 &trace_print_event,
1287 &trace_hwlat_event,
1236 NULL 1288 NULL
1237}; 1289};
1238 1290