diff options
author | Tzvetomir Stoyanov <tstoyanov@vmware.com> | 2019-08-05 16:43:13 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-08-31 21:19:28 -0400 |
commit | 38847db9740a984e8538ce2573cbc0fc7edf22b3 (patch) | |
tree | 8b117d61114c291c451a3bf7bdb2dd33771bdc00 | |
parent | 4cb3c6d546aa5493a960d05eb73bad8e69a58574 (diff) |
libtraceevent, perf tools: Changes in tep_print_event_* APIs
Libtraceevent APIs for printing various trace events information are
complicated, there are complex extra parameters. To control the way
event information is printed, the user should call a set of functions in
a specific sequence.
These APIs are reimplemented to provide a more simple interface for
printing event information.
Removed APIs:
tep_print_event_task()
tep_print_event_time()
tep_print_event_data()
tep_event_info()
tep_is_latency_format()
tep_set_latency_format()
tep_data_latency_format()
tep_set_print_raw()
A new API for printing event information is introduced:
void tep_print_event(struct tep_handle *tep, struct trace_seq *s,
struct tep_record *record, const char *fmt, ...);
where "fmt" is a printf-like format string, followed by the event
fields to be printed. Supported fields:
TEP_PRINT_PID, "%d" - event PID
TEP_PRINT_CPU, "%d" - event CPU
TEP_PRINT_COMM, "%s" - event command string
TEP_PRINT_NAME, "%s" - event name
TEP_PRINT_LATENCY, "%s" - event latency
TEP_PRINT_TIME, %d - event time stamp. A divisor and precision
can be specified as part of this format string:
"%precision.divisord". Example:
"%3.1000d" - divide the time by 1000 and print the first 3 digits
before the dot. Thus, the time stamp "123456000" will be printed as
"123.456"
TEP_PRINT_INFO, "%s" - event information.
TEP_PRINT_INFO_RAW, "%s" - event information, in raw format.
Example:
tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s",
TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU,
TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME, TEP_PRINT_INFO);
Output:
ls-11314 [005] d.h. 185207.366383 function __wake_up
Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: linux-trace-devel@vger.kernel.org
Cc: Patrick McLean <chutzpah@gentoo.org>
Link: http://lore.kernel.org/linux-trace-devel/20190801074959.22023-2-tz.stoyanov@gmail.com
Link: http://lore.kernel.org/lkml/20190805204355.041132030@goodmis.org
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/lib/traceevent/event-parse-api.c | 40 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse-local.h | 4 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 322 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 29 | ||||
-rw-r--r-- | tools/perf/builtin-kmem.c | 3 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 3 | ||||
-rw-r--r-- | tools/perf/util/trace-event-parse.c | 2 |
7 files changed, 203 insertions, 200 deletions
diff --git a/tools/lib/traceevent/event-parse-api.c b/tools/lib/traceevent/event-parse-api.c index 988587840c80..4faf52a65791 100644 --- a/tools/lib/traceevent/event-parse-api.c +++ b/tools/lib/traceevent/event-parse-api.c | |||
@@ -303,33 +303,6 @@ void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian) | |||
303 | } | 303 | } |
304 | 304 | ||
305 | /** | 305 | /** |
306 | * tep_is_latency_format - get if the latency output format is configured | ||
307 | * @tep: a handle to the tep_handle | ||
308 | * | ||
309 | * This returns true if the latency output format is configured | ||
310 | * If @tep is NULL, false is returned. | ||
311 | */ | ||
312 | bool tep_is_latency_format(struct tep_handle *tep) | ||
313 | { | ||
314 | if (tep) | ||
315 | return (tep->latency_format); | ||
316 | return false; | ||
317 | } | ||
318 | |||
319 | /** | ||
320 | * tep_set_latency_format - set the latency output format | ||
321 | * @tep: a handle to the tep_handle | ||
322 | * @lat: non zero for latency output format | ||
323 | * | ||
324 | * This sets the latency output format | ||
325 | */ | ||
326 | void tep_set_latency_format(struct tep_handle *tep, int lat) | ||
327 | { | ||
328 | if (tep) | ||
329 | tep->latency_format = lat; | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * tep_is_old_format - get if an old kernel is used | 306 | * tep_is_old_format - get if an old kernel is used |
334 | * @tep: a handle to the tep_handle | 307 | * @tep: a handle to the tep_handle |
335 | * | 308 | * |
@@ -345,19 +318,6 @@ bool tep_is_old_format(struct tep_handle *tep) | |||
345 | } | 318 | } |
346 | 319 | ||
347 | /** | 320 | /** |
348 | * tep_set_print_raw - set a flag to force print in raw format | ||
349 | * @tep: a handle to the tep_handle | ||
350 | * @print_raw: the new value of the print_raw flag | ||
351 | * | ||
352 | * This sets a flag to force print in raw format | ||
353 | */ | ||
354 | void tep_set_print_raw(struct tep_handle *tep, int print_raw) | ||
355 | { | ||
356 | if (tep) | ||
357 | tep->print_raw = print_raw; | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * tep_set_test_filters - set a flag to test a filter string | 321 | * tep_set_test_filters - set a flag to test a filter string |
362 | * @tep: a handle to the tep_handle | 322 | * @tep: a handle to the tep_handle |
363 | * @test_filters: the new value of the test_filters flag | 323 | * @test_filters: the new value of the test_filters flag |
diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceevent/event-parse-local.h index 09aa142f7fdd..6e58ee1fe7c8 100644 --- a/tools/lib/traceevent/event-parse-local.h +++ b/tools/lib/traceevent/event-parse-local.h | |||
@@ -28,8 +28,6 @@ struct tep_handle { | |||
28 | enum tep_endian file_bigendian; | 28 | enum tep_endian file_bigendian; |
29 | enum tep_endian host_bigendian; | 29 | enum tep_endian host_bigendian; |
30 | 30 | ||
31 | int latency_format; | ||
32 | |||
33 | int old_format; | 31 | int old_format; |
34 | 32 | ||
35 | int cpus; | 33 | int cpus; |
@@ -70,8 +68,6 @@ struct tep_handle { | |||
70 | int ld_offset; | 68 | int ld_offset; |
71 | int ld_size; | 69 | int ld_size; |
72 | 70 | ||
73 | int print_raw; | ||
74 | |||
75 | int test_filters; | 71 | int test_filters; |
76 | 72 | ||
77 | int flags; | 73 | int flags; |
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 3e83636076b2..d1085aab9c43 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -5212,24 +5212,20 @@ out_failed: | |||
5212 | } | 5212 | } |
5213 | } | 5213 | } |
5214 | 5214 | ||
5215 | /** | 5215 | /* |
5216 | * tep_data_latency_format - parse the data for the latency format | ||
5217 | * @tep: a handle to the trace event parser context | ||
5218 | * @s: the trace_seq to write to | ||
5219 | * @record: the record to read from | ||
5220 | * | ||
5221 | * This parses out the Latency format (interrupts disabled, | 5216 | * This parses out the Latency format (interrupts disabled, |
5222 | * need rescheduling, in hard/soft interrupt, preempt count | 5217 | * need rescheduling, in hard/soft interrupt, preempt count |
5223 | * and lock depth) and places it into the trace_seq. | 5218 | * and lock depth) and places it into the trace_seq. |
5224 | */ | 5219 | */ |
5225 | void tep_data_latency_format(struct tep_handle *tep, | 5220 | static void data_latency_format(struct tep_handle *tep, struct trace_seq *s, |
5226 | struct trace_seq *s, struct tep_record *record) | 5221 | char *format, struct tep_record *record) |
5227 | { | 5222 | { |
5228 | static int check_lock_depth = 1; | 5223 | static int check_lock_depth = 1; |
5229 | static int check_migrate_disable = 1; | 5224 | static int check_migrate_disable = 1; |
5230 | static int lock_depth_exists; | 5225 | static int lock_depth_exists; |
5231 | static int migrate_disable_exists; | 5226 | static int migrate_disable_exists; |
5232 | unsigned int lat_flags; | 5227 | unsigned int lat_flags; |
5228 | struct trace_seq sq; | ||
5233 | unsigned int pc; | 5229 | unsigned int pc; |
5234 | int lock_depth = 0; | 5230 | int lock_depth = 0; |
5235 | int migrate_disable = 0; | 5231 | int migrate_disable = 0; |
@@ -5237,6 +5233,7 @@ void tep_data_latency_format(struct tep_handle *tep, | |||
5237 | int softirq; | 5233 | int softirq; |
5238 | void *data = record->data; | 5234 | void *data = record->data; |
5239 | 5235 | ||
5236 | trace_seq_init(&sq); | ||
5240 | lat_flags = parse_common_flags(tep, data); | 5237 | lat_flags = parse_common_flags(tep, data); |
5241 | pc = parse_common_pc(tep, data); | 5238 | pc = parse_common_pc(tep, data); |
5242 | /* lock_depth may not always exist */ | 5239 | /* lock_depth may not always exist */ |
@@ -5264,7 +5261,7 @@ void tep_data_latency_format(struct tep_handle *tep, | |||
5264 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; | 5261 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; |
5265 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; | 5262 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; |
5266 | 5263 | ||
5267 | trace_seq_printf(s, "%c%c%c", | 5264 | trace_seq_printf(&sq, "%c%c%c", |
5268 | (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : | 5265 | (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : |
5269 | (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? | 5266 | (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? |
5270 | 'X' : '.', | 5267 | 'X' : '.', |
@@ -5274,24 +5271,32 @@ void tep_data_latency_format(struct tep_handle *tep, | |||
5274 | hardirq ? 'h' : softirq ? 's' : '.'); | 5271 | hardirq ? 'h' : softirq ? 's' : '.'); |
5275 | 5272 | ||
5276 | if (pc) | 5273 | if (pc) |
5277 | trace_seq_printf(s, "%x", pc); | 5274 | trace_seq_printf(&sq, "%x", pc); |
5278 | else | 5275 | else |
5279 | trace_seq_putc(s, '.'); | 5276 | trace_seq_printf(&sq, "."); |
5280 | 5277 | ||
5281 | if (migrate_disable_exists) { | 5278 | if (migrate_disable_exists) { |
5282 | if (migrate_disable < 0) | 5279 | if (migrate_disable < 0) |
5283 | trace_seq_putc(s, '.'); | 5280 | trace_seq_printf(&sq, "."); |
5284 | else | 5281 | else |
5285 | trace_seq_printf(s, "%d", migrate_disable); | 5282 | trace_seq_printf(&sq, "%d", migrate_disable); |
5286 | } | 5283 | } |
5287 | 5284 | ||
5288 | if (lock_depth_exists) { | 5285 | if (lock_depth_exists) { |
5289 | if (lock_depth < 0) | 5286 | if (lock_depth < 0) |
5290 | trace_seq_putc(s, '.'); | 5287 | trace_seq_printf(&sq, "."); |
5291 | else | 5288 | else |
5292 | trace_seq_printf(s, "%d", lock_depth); | 5289 | trace_seq_printf(&sq, "%d", lock_depth); |
5293 | } | 5290 | } |
5294 | 5291 | ||
5292 | if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) { | ||
5293 | s->state = TRACE_SEQ__MEM_ALLOC_FAILED; | ||
5294 | return; | ||
5295 | } | ||
5296 | |||
5297 | trace_seq_terminate(&sq); | ||
5298 | trace_seq_puts(s, sq.buffer); | ||
5299 | trace_seq_destroy(&sq); | ||
5295 | trace_seq_terminate(s); | 5300 | trace_seq_terminate(s); |
5296 | } | 5301 | } |
5297 | 5302 | ||
@@ -5452,21 +5457,16 @@ int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline) | |||
5452 | return cmdline->pid; | 5457 | return cmdline->pid; |
5453 | } | 5458 | } |
5454 | 5459 | ||
5455 | /** | 5460 | /* |
5456 | * tep_event_info - parse the data into the print format | ||
5457 | * @s: the trace_seq to write to | ||
5458 | * @event: the handle to the event | ||
5459 | * @record: the record to read from | ||
5460 | * | ||
5461 | * This parses the raw @data using the given @event information and | 5461 | * This parses the raw @data using the given @event information and |
5462 | * writes the print format into the trace_seq. | 5462 | * writes the print format into the trace_seq. |
5463 | */ | 5463 | */ |
5464 | void tep_event_info(struct trace_seq *s, struct tep_event *event, | 5464 | static void print_event_info(struct trace_seq *s, char *format, bool raw, |
5465 | struct tep_record *record) | 5465 | struct tep_event *event, struct tep_record *record) |
5466 | { | 5466 | { |
5467 | int print_pretty = 1; | 5467 | int print_pretty = 1; |
5468 | 5468 | ||
5469 | if (event->tep->print_raw || (event->flags & TEP_EVENT_FL_PRINTRAW)) | 5469 | if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW)) |
5470 | tep_print_fields(s, record->data, record->size, event); | 5470 | tep_print_fields(s, record->data, record->size, event); |
5471 | else { | 5471 | else { |
5472 | 5472 | ||
@@ -5481,20 +5481,6 @@ void tep_event_info(struct trace_seq *s, struct tep_event *event, | |||
5481 | trace_seq_terminate(s); | 5481 | trace_seq_terminate(s); |
5482 | } | 5482 | } |
5483 | 5483 | ||
5484 | static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock) | ||
5485 | { | ||
5486 | if (!trace_clock || !use_trace_clock) | ||
5487 | return true; | ||
5488 | |||
5489 | if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global") | ||
5490 | || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf") | ||
5491 | || !strncmp(trace_clock, "mono", 4)) | ||
5492 | return true; | ||
5493 | |||
5494 | /* trace_clock is setting in tsc or counter mode */ | ||
5495 | return false; | ||
5496 | } | ||
5497 | |||
5498 | /** | 5484 | /** |
5499 | * tep_find_event_by_record - return the event from a given record | 5485 | * tep_find_event_by_record - return the event from a given record |
5500 | * @tep: a handle to the trace event parser context | 5486 | * @tep: a handle to the trace event parser context |
@@ -5518,129 +5504,195 @@ tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record) | |||
5518 | return tep_find_event(tep, type); | 5504 | return tep_find_event(tep, type); |
5519 | } | 5505 | } |
5520 | 5506 | ||
5521 | /** | 5507 | /* |
5522 | * tep_print_event_task - Write the event task comm, pid and CPU | 5508 | * Writes the timestamp of the record into @s. Time divisor and precision can be |
5523 | * @tep: a handle to the trace event parser context | 5509 | * specified as part of printf @format string. Example: |
5524 | * @s: the trace_seq to write to | 5510 | * "%3.1000d" - divide the time by 1000 and print the first 3 digits |
5525 | * @event: the handle to the record's event | 5511 | * before the dot. Thus, the timestamp "123456000" will be printed as |
5526 | * @record: The record to get the event from | 5512 | * "123.456" |
5527 | * | ||
5528 | * Writes the tasks comm, pid and CPU to @s. | ||
5529 | */ | 5513 | */ |
5530 | void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s, | 5514 | static void print_event_time(struct tep_handle *tep, struct trace_seq *s, |
5531 | struct tep_event *event, | 5515 | char *format, struct tep_event *event, |
5532 | struct tep_record *record) | 5516 | struct tep_record *record) |
5517 | { | ||
5518 | unsigned long long time; | ||
5519 | char *divstr; | ||
5520 | int prec = 0, pr; | ||
5521 | int div = 0; | ||
5522 | int p10 = 1; | ||
5523 | |||
5524 | if (isdigit(*(format + 1))) | ||
5525 | prec = atoi(format + 1); | ||
5526 | divstr = strchr(format, '.'); | ||
5527 | if (divstr && isdigit(*(divstr + 1))) | ||
5528 | div = atoi(divstr + 1); | ||
5529 | time = record->ts; | ||
5530 | if (div) | ||
5531 | time /= div; | ||
5532 | pr = prec; | ||
5533 | while (pr--) | ||
5534 | p10 *= 10; | ||
5535 | |||
5536 | if (p10 > 1 && p10 < time) | ||
5537 | trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10); | ||
5538 | else | ||
5539 | trace_seq_printf(s, "%12llu\n", time); | ||
5540 | } | ||
5541 | |||
5542 | struct print_event_type { | ||
5543 | enum { | ||
5544 | EVENT_TYPE_INT = 1, | ||
5545 | EVENT_TYPE_STRING, | ||
5546 | EVENT_TYPE_UNKNOWN, | ||
5547 | } type; | ||
5548 | char format[32]; | ||
5549 | }; | ||
5550 | |||
5551 | static void print_string(struct tep_handle *tep, struct trace_seq *s, | ||
5552 | struct tep_record *record, struct tep_event *event, | ||
5553 | const char *arg, struct print_event_type *type) | ||
5533 | { | 5554 | { |
5534 | void *data = record->data; | ||
5535 | const char *comm; | 5555 | const char *comm; |
5536 | int pid; | 5556 | int pid; |
5537 | 5557 | ||
5538 | pid = parse_common_pid(tep, data); | 5558 | if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) { |
5539 | comm = find_cmdline(tep, pid); | 5559 | data_latency_format(tep, s, type->format, record); |
5560 | } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) { | ||
5561 | pid = parse_common_pid(tep, record->data); | ||
5562 | comm = find_cmdline(tep, pid); | ||
5563 | trace_seq_printf(s, type->format, comm); | ||
5564 | } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) { | ||
5565 | print_event_info(s, type->format, true, event, record); | ||
5566 | } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) { | ||
5567 | print_event_info(s, type->format, false, event, record); | ||
5568 | } else if (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) { | ||
5569 | trace_seq_printf(s, type->format, event->name); | ||
5570 | } else { | ||
5571 | trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg); | ||
5572 | } | ||
5540 | 5573 | ||
5541 | if (tep->latency_format) | ||
5542 | trace_seq_printf(s, "%8.8s-%-5d %3d", comm, pid, record->cpu); | ||
5543 | else | ||
5544 | trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); | ||
5545 | } | 5574 | } |
5546 | 5575 | ||
5547 | /** | 5576 | static void print_int(struct tep_handle *tep, struct trace_seq *s, |
5548 | * tep_print_event_time - Write the event timestamp | 5577 | struct tep_record *record, struct tep_event *event, |
5549 | * @tep: a handle to the trace event parser context | 5578 | int arg, struct print_event_type *type) |
5550 | * @s: the trace_seq to write to | ||
5551 | * @event: the handle to the record's event | ||
5552 | * @record: The record to get the event from | ||
5553 | * @use_trace_clock: Set to parse according to the @tep->trace_clock | ||
5554 | * | ||
5555 | * Writes the timestamp of the record into @s. | ||
5556 | */ | ||
5557 | void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s, | ||
5558 | struct tep_event *event, | ||
5559 | struct tep_record *record, | ||
5560 | bool use_trace_clock) | ||
5561 | { | 5579 | { |
5562 | unsigned long secs; | 5580 | int param; |
5563 | unsigned long usecs; | ||
5564 | unsigned long nsecs; | ||
5565 | int p; | ||
5566 | bool use_usec_format; | ||
5567 | 5581 | ||
5568 | use_usec_format = is_timestamp_in_us(tep->trace_clock, use_trace_clock); | 5582 | switch (arg) { |
5569 | if (use_usec_format) { | 5583 | case TEP_PRINT_CPU: |
5570 | secs = record->ts / NSEC_PER_SEC; | 5584 | param = record->cpu; |
5571 | nsecs = record->ts - secs * NSEC_PER_SEC; | 5585 | break; |
5586 | case TEP_PRINT_PID: | ||
5587 | param = parse_common_pid(tep, record->data); | ||
5588 | break; | ||
5589 | case TEP_PRINT_TIME: | ||
5590 | return print_event_time(tep, s, type->format, event, record); | ||
5591 | default: | ||
5592 | return; | ||
5572 | } | 5593 | } |
5594 | trace_seq_printf(s, type->format, param); | ||
5595 | } | ||
5573 | 5596 | ||
5574 | if (tep->latency_format) { | 5597 | static int tep_print_event_param_type(char *format, |
5575 | tep_data_latency_format(tep, s, record); | 5598 | struct print_event_type *type) |
5576 | } | 5599 | { |
5600 | char *str = format + 1; | ||
5601 | int i = 1; | ||
5577 | 5602 | ||
5578 | if (use_usec_format) { | 5603 | type->type = EVENT_TYPE_UNKNOWN; |
5579 | if (tep->flags & TEP_NSEC_OUTPUT) { | 5604 | while (*str) { |
5580 | usecs = nsecs; | 5605 | switch (*str) { |
5581 | p = 9; | 5606 | case 'd': |
5582 | } else { | 5607 | case 'u': |
5583 | usecs = (nsecs + 500) / NSEC_PER_USEC; | 5608 | case 'i': |
5584 | /* To avoid usecs larger than 1 sec */ | 5609 | case 'x': |
5585 | if (usecs >= USEC_PER_SEC) { | 5610 | case 'X': |
5586 | usecs -= USEC_PER_SEC; | 5611 | case 'o': |
5587 | secs++; | 5612 | type->type = EVENT_TYPE_INT; |
5588 | } | 5613 | break; |
5589 | p = 6; | 5614 | case 's': |
5615 | type->type = EVENT_TYPE_STRING; | ||
5616 | break; | ||
5590 | } | 5617 | } |
5591 | 5618 | str++; | |
5592 | trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs); | 5619 | i++; |
5593 | } else | 5620 | if (type->type != EVENT_TYPE_UNKNOWN) |
5594 | trace_seq_printf(s, " %12llu:", record->ts); | 5621 | break; |
5622 | } | ||
5623 | memset(type->format, 0, 32); | ||
5624 | memcpy(type->format, format, i < 32 ? i : 31); | ||
5625 | return i; | ||
5595 | } | 5626 | } |
5596 | 5627 | ||
5597 | /** | 5628 | /** |
5598 | * tep_print_event_data - Write the event data section | 5629 | * tep_print_event - Write various event information |
5599 | * @tep: a handle to the trace event parser context | 5630 | * @tep: a handle to the trace event parser context |
5600 | * @s: the trace_seq to write to | 5631 | * @s: the trace_seq to write to |
5601 | * @event: the handle to the record's event | ||
5602 | * @record: The record to get the event from | 5632 | * @record: The record to get the event from |
5603 | * | 5633 | * @format: a printf format string. Supported event fileds: |
5604 | * Writes the parsing of the record's data to @s. | 5634 | * TEP_PRINT_PID, "%d" - event PID |
5635 | * TEP_PRINT_CPU, "%d" - event CPU | ||
5636 | * TEP_PRINT_COMM, "%s" - event command string | ||
5637 | * TEP_PRINT_NAME, "%s" - event name | ||
5638 | * TEP_PRINT_LATENCY, "%s" - event latency | ||
5639 | * TEP_PRINT_TIME, %d - event time stamp. A divisor and precision | ||
5640 | * can be specified as part of this format string: | ||
5641 | * "%precision.divisord". Example: | ||
5642 | * "%3.1000d" - divide the time by 1000 and print the first | ||
5643 | * 3 digits before the dot. Thus, the time stamp | ||
5644 | * "123456000" will be printed as "123.456" | ||
5645 | * TEP_PRINT_INFO, "%s" - event information. If any width is specified in | ||
5646 | * the format string, the event information will be printed | ||
5647 | * in raw format. | ||
5648 | * Writes the specified event information into @s. | ||
5605 | */ | 5649 | */ |
5606 | void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s, | ||
5607 | struct tep_event *event, | ||
5608 | struct tep_record *record) | ||
5609 | { | ||
5610 | static const char *spaces = " "; /* 20 spaces */ | ||
5611 | int len; | ||
5612 | |||
5613 | trace_seq_printf(s, " %s: ", event->name); | ||
5614 | |||
5615 | /* Space out the event names evenly. */ | ||
5616 | len = strlen(event->name); | ||
5617 | if (len < 20) | ||
5618 | trace_seq_printf(s, "%.*s", 20 - len, spaces); | ||
5619 | |||
5620 | tep_event_info(s, event, record); | ||
5621 | } | ||
5622 | |||
5623 | void tep_print_event(struct tep_handle *tep, struct trace_seq *s, | 5650 | void tep_print_event(struct tep_handle *tep, struct trace_seq *s, |
5624 | struct tep_record *record, bool use_trace_clock) | 5651 | struct tep_record *record, const char *fmt, ...) |
5625 | { | 5652 | { |
5653 | struct print_event_type type; | ||
5654 | char *format = strdup(fmt); | ||
5655 | char *current = format; | ||
5656 | char *str = format; | ||
5657 | int offset; | ||
5658 | va_list args; | ||
5626 | struct tep_event *event; | 5659 | struct tep_event *event; |
5627 | 5660 | ||
5628 | event = tep_find_event_by_record(tep, record); | 5661 | if (!format) |
5629 | if (!event) { | ||
5630 | int i; | ||
5631 | int type = trace_parse_common_type(tep, record->data); | ||
5632 | |||
5633 | do_warning("ug! no event found for type %d", type); | ||
5634 | trace_seq_printf(s, "[UNKNOWN TYPE %d]", type); | ||
5635 | for (i = 0; i < record->size; i++) | ||
5636 | trace_seq_printf(s, " %02x", | ||
5637 | ((unsigned char *)record->data)[i]); | ||
5638 | return; | 5662 | return; |
5639 | } | ||
5640 | 5663 | ||
5641 | tep_print_event_task(tep, s, event, record); | 5664 | event = tep_find_event_by_record(tep, record); |
5642 | tep_print_event_time(tep, s, event, record, use_trace_clock); | 5665 | va_start(args, fmt); |
5643 | tep_print_event_data(tep, s, event, record); | 5666 | while (*current) { |
5667 | current = strchr(str, '%'); | ||
5668 | if (!current) { | ||
5669 | trace_seq_puts(s, str); | ||
5670 | break; | ||
5671 | } | ||
5672 | memset(&type, 0, sizeof(type)); | ||
5673 | offset = tep_print_event_param_type(current, &type); | ||
5674 | *current = '\0'; | ||
5675 | trace_seq_puts(s, str); | ||
5676 | current += offset; | ||
5677 | switch (type.type) { | ||
5678 | case EVENT_TYPE_STRING: | ||
5679 | print_string(tep, s, record, event, | ||
5680 | va_arg(args, char*), &type); | ||
5681 | break; | ||
5682 | case EVENT_TYPE_INT: | ||
5683 | print_int(tep, s, record, event, | ||
5684 | va_arg(args, int), &type); | ||
5685 | break; | ||
5686 | case EVENT_TYPE_UNKNOWN: | ||
5687 | default: | ||
5688 | trace_seq_printf(s, "[UNKNOWN TYPE]"); | ||
5689 | break; | ||
5690 | } | ||
5691 | str = current; | ||
5692 | |||
5693 | } | ||
5694 | va_end(args); | ||
5695 | free(format); | ||
5644 | } | 5696 | } |
5645 | 5697 | ||
5646 | static int events_id_cmp(const void *a, const void *b) | 5698 | static int events_id_cmp(const void *a, const void *b) |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 642f68ab5fb2..cf7f302eb44a 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -442,18 +442,18 @@ int tep_register_print_string(struct tep_handle *tep, const char *fmt, | |||
442 | unsigned long long addr); | 442 | unsigned long long addr); |
443 | bool tep_is_pid_registered(struct tep_handle *tep, int pid); | 443 | bool tep_is_pid_registered(struct tep_handle *tep, int pid); |
444 | 444 | ||
445 | void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s, | 445 | #define TEP_PRINT_INFO "INFO" |
446 | struct tep_event *event, | 446 | #define TEP_PRINT_INFO_RAW "INFO_RAW" |
447 | struct tep_record *record); | 447 | #define TEP_PRINT_COMM "COMM" |
448 | void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s, | 448 | #define TEP_PRINT_LATENCY "LATENCY" |
449 | struct tep_event *event, | 449 | #define TEP_PRINT_NAME "NAME" |
450 | struct tep_record *record, | 450 | #define TEP_PRINT_PID 1U |
451 | bool use_trace_clock); | 451 | #define TEP_PRINT_TIME 2U |
452 | void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s, | 452 | #define TEP_PRINT_CPU 3U |
453 | struct tep_event *event, | 453 | |
454 | struct tep_record *record); | ||
455 | void tep_print_event(struct tep_handle *tep, struct trace_seq *s, | 454 | void tep_print_event(struct tep_handle *tep, struct trace_seq *s, |
456 | struct tep_record *record, bool use_trace_clock); | 455 | struct tep_record *record, const char *fmt, ...) |
456 | __attribute__ ((format (printf, 4, 5))); | ||
457 | 457 | ||
458 | int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, | 458 | int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, |
459 | int long_size); | 459 | int long_size); |
@@ -525,8 +525,6 @@ tep_find_event_by_name(struct tep_handle *tep, const char *sys, const char *name | |||
525 | struct tep_event * | 525 | struct tep_event * |
526 | tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record); | 526 | tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record); |
527 | 527 | ||
528 | void tep_data_latency_format(struct tep_handle *tep, | ||
529 | struct trace_seq *s, struct tep_record *record); | ||
530 | int tep_data_type(struct tep_handle *tep, struct tep_record *rec); | 528 | int tep_data_type(struct tep_handle *tep, struct tep_record *rec); |
531 | int tep_data_pid(struct tep_handle *tep, struct tep_record *rec); | 529 | int tep_data_pid(struct tep_handle *tep, struct tep_record *rec); |
532 | int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec); | 530 | int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec); |
@@ -541,8 +539,6 @@ void tep_print_field(struct trace_seq *s, void *data, | |||
541 | struct tep_format_field *field); | 539 | struct tep_format_field *field); |
542 | void tep_print_fields(struct trace_seq *s, void *data, | 540 | void tep_print_fields(struct trace_seq *s, void *data, |
543 | int size __maybe_unused, struct tep_event *event); | 541 | int size __maybe_unused, struct tep_event *event); |
544 | void tep_event_info(struct trace_seq *s, struct tep_event *event, | ||
545 | struct tep_record *record); | ||
546 | int tep_strerror(struct tep_handle *tep, enum tep_errno errnum, | 542 | int tep_strerror(struct tep_handle *tep, enum tep_errno errnum, |
547 | char *buf, size_t buflen); | 543 | char *buf, size_t buflen); |
548 | 544 | ||
@@ -566,12 +562,9 @@ bool tep_is_file_bigendian(struct tep_handle *tep); | |||
566 | void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian); | 562 | void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian); |
567 | bool tep_is_local_bigendian(struct tep_handle *tep); | 563 | bool tep_is_local_bigendian(struct tep_handle *tep); |
568 | void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian); | 564 | void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian); |
569 | bool tep_is_latency_format(struct tep_handle *tep); | ||
570 | void tep_set_latency_format(struct tep_handle *tep, int lat); | ||
571 | int tep_get_header_page_size(struct tep_handle *tep); | 565 | int tep_get_header_page_size(struct tep_handle *tep); |
572 | int tep_get_header_timestamp_size(struct tep_handle *tep); | 566 | int tep_get_header_timestamp_size(struct tep_handle *tep); |
573 | bool tep_is_old_format(struct tep_handle *tep); | 567 | bool tep_is_old_format(struct tep_handle *tep); |
574 | void tep_set_print_raw(struct tep_handle *tep, int print_raw); | ||
575 | void tep_set_test_filters(struct tep_handle *tep, int test_filters); | 568 | void tep_set_test_filters(struct tep_handle *tep, int test_filters); |
576 | 569 | ||
577 | struct tep_handle *tep_alloc(void); | 570 | struct tep_handle *tep_alloc(void); |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 7eec0da64c46..378b09c910a8 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -750,7 +750,8 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample, | |||
750 | } | 750 | } |
751 | 751 | ||
752 | trace_seq_init(&seq); | 752 | trace_seq_init(&seq); |
753 | tep_event_info(&seq, evsel->tp_format, &record); | 753 | tep_print_event(evsel->tp_format->tep, |
754 | &seq, &record, "%s", TEP_PRINT_INFO); | ||
754 | 755 | ||
755 | str = strtok_r(seq.buffer, " ", &pos); | 756 | str = strtok_r(seq.buffer, " ", &pos); |
756 | while (str) { | 757 | while (str) { |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 035355a9945e..4650704540c9 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -709,7 +709,8 @@ static char *get_trace_output(struct hist_entry *he) | |||
709 | tep_print_fields(&seq, he->raw_data, he->raw_size, | 709 | tep_print_fields(&seq, he->raw_data, he->raw_size, |
710 | evsel->tp_format); | 710 | evsel->tp_format); |
711 | } else { | 711 | } else { |
712 | tep_event_info(&seq, evsel->tp_format, &rec); | 712 | tep_print_event(evsel->tp_format->tep, |
713 | &seq, &rec, "%s", TEP_PRINT_INFO); | ||
713 | } | 714 | } |
714 | /* | 715 | /* |
715 | * Trim the buffer, it starts at 4KB and we're not going to | 716 | * Trim the buffer, it starts at 4KB and we're not going to |
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 8e31a63045c3..5d6bfc70b210 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -109,7 +109,7 @@ void event_format__fprintf(struct tep_event *event, | |||
109 | record.data = data; | 109 | record.data = data; |
110 | 110 | ||
111 | trace_seq_init(&s); | 111 | trace_seq_init(&s); |
112 | tep_event_info(&s, event, &record); | 112 | tep_print_event(event->tep, &s, &record, "%s", TEP_PRINT_INFO); |
113 | trace_seq_do_fprintf(&s, fp); | 113 | trace_seq_do_fprintf(&s, fp); |
114 | trace_seq_destroy(&s); | 114 | trace_seq_destroy(&s); |
115 | } | 115 | } |