Skip to content

Commit 860f9f6

Browse files
tzanussirostedt
authored andcommitted
tracing: Add usecs modifier for hist trigger timestamps
Appending .usecs onto a common_timestamp field will cause the timestamp value to be in microseconds instead of the default nanoseconds. A typical latency histogram using usecs would look like this: # echo 'hist:keys=pid,prio:ts0=common_timestamp.usecs ... # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0 ... This also adds an external trace_clock_in_ns() to trace.c for the timestamp conversion. Link: http://lkml.kernel.org/r/4e813705a170b3e13e97dc3135047362fb1a39f3.1516069914.git.tom.zanussi@linux.intel.com Signed-off-by: Tom Zanussi <[email protected]> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent b559d00 commit 860f9f6

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

Documentation/trace/histogram.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
.syscall display a syscall id as a system call name
7575
.execname display a common_pid as a program name
7676
.log2 display log2 value rather than raw number
77+
.usecs display a common_timestamp in microseconds
7778

7879
Note that in general the semantics of a given field aren't
7980
interpreted when applying a modifier to it, but there are some

kernel/trace/trace.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,14 @@ static struct {
11681168
ARCH_TRACE_CLOCKS
11691169
};
11701170

1171+
bool trace_clock_in_ns(struct trace_array *tr)
1172+
{
1173+
if (trace_clocks[tr->clock_id].in_ns)
1174+
return true;
1175+
1176+
return false;
1177+
}
1178+
11711179
/*
11721180
* trace_parser_get_init - gets the buffer for trace parser
11731181
*/
@@ -4694,8 +4702,9 @@ static const char readme_msg[] =
46944702
"\t .sym display an address as a symbol\n"
46954703
"\t .sym-offset display an address as a symbol and offset\n"
46964704
"\t .execname display a common_pid as a program name\n"
4697-
"\t .syscall display a syscall id as a syscall name\n\n"
4698-
"\t .log2 display log2 value rather than raw number\n\n"
4705+
"\t .syscall display a syscall id as a syscall name\n"
4706+
"\t .log2 display log2 value rather than raw number\n"
4707+
"\t .usecs display a common_timestamp in microseconds\n\n"
46994708
"\t The 'pause' parameter can be used to pause an existing hist\n"
47004709
"\t trigger or to start a hist trigger but not log any events\n"
47014710
"\t until told to do so. 'continue' can be used to start or\n"

kernel/trace/trace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ extern void trace_array_put(struct trace_array *tr);
289289

290290
extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);
291291

292+
extern bool trace_clock_in_ns(struct trace_array *tr);
293+
292294
/*
293295
* The global tracer (top) should be the first trace array added,
294296
* but we check the flag anyway.

kernel/trace/trace_events_hist.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,6 @@ static u64 hist_field_log2(struct hist_field *hist_field, void *event,
9090
return (u64) ilog2(roundup_pow_of_two(val));
9191
}
9292

93-
static u64 hist_field_timestamp(struct hist_field *hist_field, void *event,
94-
struct ring_buffer_event *rbe)
95-
{
96-
return ring_buffer_event_time_stamp(rbe);
97-
}
98-
9993
#define DEFINE_HIST_FIELD_FN(type) \
10094
static u64 hist_field_##type(struct hist_field *hist_field, \
10195
void *event, \
@@ -143,6 +137,7 @@ enum hist_field_flags {
143137
HIST_FIELD_FL_STACKTRACE = 1 << 8,
144138
HIST_FIELD_FL_LOG2 = 1 << 9,
145139
HIST_FIELD_FL_TIMESTAMP = 1 << 10,
140+
HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
146141
};
147142

148143
struct hist_trigger_attrs {
@@ -153,6 +148,7 @@ struct hist_trigger_attrs {
153148
bool pause;
154149
bool cont;
155150
bool clear;
151+
bool ts_in_usecs;
156152
unsigned int map_bits;
157153
};
158154

@@ -170,6 +166,20 @@ struct hist_trigger_data {
170166
bool enable_timestamps;
171167
};
172168

169+
static u64 hist_field_timestamp(struct hist_field *hist_field, void *event,
170+
struct ring_buffer_event *rbe)
171+
{
172+
struct hist_trigger_data *hist_data = hist_field->hist_data;
173+
struct trace_array *tr = hist_data->event_file->tr;
174+
175+
u64 ts = ring_buffer_event_time_stamp(rbe);
176+
177+
if (hist_data->attrs->ts_in_usecs && trace_clock_in_ns(tr))
178+
ts = ns2usecs(ts);
179+
180+
return ts;
181+
}
182+
173183
static const char *hist_field_name(struct hist_field *field,
174184
unsigned int level)
175185
{
@@ -634,6 +644,8 @@ static int create_key_field(struct hist_trigger_data *hist_data,
634644
flags |= HIST_FIELD_FL_SYSCALL;
635645
else if (strcmp(field_str, "log2") == 0)
636646
flags |= HIST_FIELD_FL_LOG2;
647+
else if (strcmp(field_str, "usecs") == 0)
648+
flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
637649
else {
638650
ret = -EINVAL;
639651
goto out;
@@ -643,6 +655,8 @@ static int create_key_field(struct hist_trigger_data *hist_data,
643655
if (strcmp(field_name, "common_timestamp") == 0) {
644656
flags |= HIST_FIELD_FL_TIMESTAMP;
645657
hist_data->enable_timestamps = true;
658+
if (flags & HIST_FIELD_FL_TIMESTAMP_USECS)
659+
hist_data->attrs->ts_in_usecs = true;
646660
key_size = sizeof(u64);
647661
} else {
648662
field = trace_find_event_field(file->event_call, field_name);
@@ -1241,6 +1255,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field)
12411255
flags_str = "syscall";
12421256
else if (hist_field->flags & HIST_FIELD_FL_LOG2)
12431257
flags_str = "log2";
1258+
else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
1259+
flags_str = "usecs";
12441260

12451261
return flags_str;
12461262
}

0 commit comments

Comments
 (0)