diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2019-02-06 05:39:47 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-02-06 09:20:32 -0500 |
commit | 16bd4321c2425d37031a902cdbf183e2cd099946 (patch) | |
tree | 4c8b88ab0a04d2d9e32470bb7781300342dad8a6 | |
parent | 26ee2bcdea33c60aa833cc32a1624ef5d49c9c6f (diff) |
perf auxtrace: Add timestamp to auxtrace errors
The timestamp can use useful to find part of a trace that has an error
without outputting all of the trace e.g. using the itrace 's' option to
skip initial number of events.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190206103947.15750-6-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/auxtrace.c | 22 | ||||
-rw-r--r-- | tools/perf/util/auxtrace.h | 2 | ||||
-rw-r--r-- | tools/perf/util/event.h | 3 | ||||
-rw-r--r-- | tools/perf/util/intel-bts.c | 4 | ||||
-rw-r--r-- | tools/perf/util/intel-pt.c | 23 | ||||
-rw-r--r-- | tools/perf/util/s390-cpumsf.c | 7 | ||||
-rw-r--r-- | tools/perf/util/session.c | 3 |
7 files changed, 48 insertions, 16 deletions
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index ad186d3255d1..267e54df511b 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
28 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/time64.h> | ||
30 | 31 | ||
31 | #include <sys/param.h> | 32 | #include <sys/param.h> |
32 | #include <stdlib.h> | 33 | #include <stdlib.h> |
@@ -858,7 +859,7 @@ void auxtrace_buffer__free(struct auxtrace_buffer *buffer) | |||
858 | 859 | ||
859 | void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, | 860 | void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, |
860 | int code, int cpu, pid_t pid, pid_t tid, u64 ip, | 861 | int code, int cpu, pid_t pid, pid_t tid, u64 ip, |
861 | const char *msg) | 862 | const char *msg, u64 timestamp) |
862 | { | 863 | { |
863 | size_t size; | 864 | size_t size; |
864 | 865 | ||
@@ -870,7 +871,9 @@ void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, | |||
870 | auxtrace_error->cpu = cpu; | 871 | auxtrace_error->cpu = cpu; |
871 | auxtrace_error->pid = pid; | 872 | auxtrace_error->pid = pid; |
872 | auxtrace_error->tid = tid; | 873 | auxtrace_error->tid = tid; |
874 | auxtrace_error->fmt = 1; | ||
873 | auxtrace_error->ip = ip; | 875 | auxtrace_error->ip = ip; |
876 | auxtrace_error->time = timestamp; | ||
874 | strlcpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG); | 877 | strlcpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG); |
875 | 878 | ||
876 | size = (void *)auxtrace_error->msg - (void *)auxtrace_error + | 879 | size = (void *)auxtrace_error->msg - (void *)auxtrace_error + |
@@ -1160,12 +1163,27 @@ static const char *auxtrace_error_name(int type) | |||
1160 | size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *fp) | 1163 | size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *fp) |
1161 | { | 1164 | { |
1162 | struct auxtrace_error_event *e = &event->auxtrace_error; | 1165 | struct auxtrace_error_event *e = &event->auxtrace_error; |
1166 | unsigned long long nsecs = e->time; | ||
1167 | const char *msg = e->msg; | ||
1163 | int ret; | 1168 | int ret; |
1164 | 1169 | ||
1165 | ret = fprintf(fp, " %s error type %u", | 1170 | ret = fprintf(fp, " %s error type %u", |
1166 | auxtrace_error_name(e->type), e->type); | 1171 | auxtrace_error_name(e->type), e->type); |
1172 | |||
1173 | if (e->fmt && nsecs) { | ||
1174 | unsigned long secs = nsecs / NSEC_PER_SEC; | ||
1175 | |||
1176 | nsecs -= secs * NSEC_PER_SEC; | ||
1177 | ret += fprintf(fp, " time %lu.%09llu", secs, nsecs); | ||
1178 | } else { | ||
1179 | ret += fprintf(fp, " time 0"); | ||
1180 | } | ||
1181 | |||
1182 | if (!e->fmt) | ||
1183 | msg = (const char *)&e->time; | ||
1184 | |||
1167 | ret += fprintf(fp, " cpu %d pid %d tid %d ip %#"PRIx64" code %u: %s\n", | 1185 | ret += fprintf(fp, " cpu %d pid %d tid %d ip %#"PRIx64" code %u: %s\n", |
1168 | e->cpu, e->pid, e->tid, e->ip, e->code, e->msg); | 1186 | e->cpu, e->pid, e->tid, e->ip, e->code, msg); |
1169 | return ret; | 1187 | return ret; |
1170 | } | 1188 | } |
1171 | 1189 | ||
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index fac32482db61..c69bcd9a3091 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h | |||
@@ -519,7 +519,7 @@ void auxtrace_index__free(struct list_head *head); | |||
519 | 519 | ||
520 | void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, | 520 | void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, |
521 | int code, int cpu, pid_t pid, pid_t tid, u64 ip, | 521 | int code, int cpu, pid_t pid, pid_t tid, u64 ip, |
522 | const char *msg); | 522 | const char *msg, u64 timestamp); |
523 | 523 | ||
524 | int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, | 524 | int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, |
525 | struct perf_tool *tool, | 525 | struct perf_tool *tool, |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index feba1aa819b4..36ae7e92dab1 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -532,8 +532,9 @@ struct auxtrace_error_event { | |||
532 | u32 cpu; | 532 | u32 cpu; |
533 | u32 pid; | 533 | u32 pid; |
534 | u32 tid; | 534 | u32 tid; |
535 | u32 reserved__; /* For alignment */ | 535 | u32 fmt; |
536 | u64 ip; | 536 | u64 ip; |
537 | u64 time; | ||
537 | char msg[MAX_AUXTRACE_ERROR_MSG]; | 538 | char msg[MAX_AUXTRACE_ERROR_MSG]; |
538 | }; | 539 | }; |
539 | 540 | ||
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index f99ac0cbe3ff..0c0180c67574 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c | |||
@@ -144,7 +144,7 @@ static int intel_bts_lost(struct intel_bts *bts, struct perf_sample *sample) | |||
144 | 144 | ||
145 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, | 145 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, |
146 | INTEL_BTS_ERR_LOST, sample->cpu, sample->pid, | 146 | INTEL_BTS_ERR_LOST, sample->cpu, sample->pid, |
147 | sample->tid, 0, "Lost trace data"); | 147 | sample->tid, 0, "Lost trace data", sample->time); |
148 | 148 | ||
149 | err = perf_session__deliver_synth_event(bts->session, &event, NULL); | 149 | err = perf_session__deliver_synth_event(bts->session, &event, NULL); |
150 | if (err) | 150 | if (err) |
@@ -374,7 +374,7 @@ static int intel_bts_synth_error(struct intel_bts *bts, int cpu, pid_t pid, | |||
374 | 374 | ||
375 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, | 375 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, |
376 | INTEL_BTS_ERR_NOINSN, cpu, pid, tid, ip, | 376 | INTEL_BTS_ERR_NOINSN, cpu, pid, tid, ip, |
377 | "Failed to get instruction"); | 377 | "Failed to get instruction", 0); |
378 | 378 | ||
379 | err = perf_session__deliver_synth_event(bts->session, &event, NULL); | 379 | err = perf_session__deliver_synth_event(bts->session, &event, NULL); |
380 | if (err) | 380 | if (err) |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 2e72373ec6df..3b497bab4324 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -1411,7 +1411,7 @@ static int intel_pt_synth_pwrx_sample(struct intel_pt_queue *ptq) | |||
1411 | } | 1411 | } |
1412 | 1412 | ||
1413 | static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu, | 1413 | static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu, |
1414 | pid_t pid, pid_t tid, u64 ip) | 1414 | pid_t pid, pid_t tid, u64 ip, u64 timestamp) |
1415 | { | 1415 | { |
1416 | union perf_event event; | 1416 | union perf_event event; |
1417 | char msg[MAX_AUXTRACE_ERROR_MSG]; | 1417 | char msg[MAX_AUXTRACE_ERROR_MSG]; |
@@ -1420,7 +1420,7 @@ static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu, | |||
1420 | intel_pt__strerror(code, msg, MAX_AUXTRACE_ERROR_MSG); | 1420 | intel_pt__strerror(code, msg, MAX_AUXTRACE_ERROR_MSG); |
1421 | 1421 | ||
1422 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, | 1422 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, |
1423 | code, cpu, pid, tid, ip, msg); | 1423 | code, cpu, pid, tid, ip, msg, timestamp); |
1424 | 1424 | ||
1425 | err = perf_session__deliver_synth_event(pt->session, &event, NULL); | 1425 | err = perf_session__deliver_synth_event(pt->session, &event, NULL); |
1426 | if (err) | 1426 | if (err) |
@@ -1430,6 +1430,18 @@ static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu, | |||
1430 | return err; | 1430 | return err; |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | static int intel_ptq_synth_error(struct intel_pt_queue *ptq, | ||
1434 | const struct intel_pt_state *state) | ||
1435 | { | ||
1436 | struct intel_pt *pt = ptq->pt; | ||
1437 | u64 tm = ptq->timestamp; | ||
1438 | |||
1439 | tm = pt->timeless_decoding ? 0 : tsc_to_perf_time(tm, &pt->tc); | ||
1440 | |||
1441 | return intel_pt_synth_error(pt, state->err, ptq->cpu, ptq->pid, | ||
1442 | ptq->tid, state->from_ip, tm); | ||
1443 | } | ||
1444 | |||
1433 | static int intel_pt_next_tid(struct intel_pt *pt, struct intel_pt_queue *ptq) | 1445 | static int intel_pt_next_tid(struct intel_pt *pt, struct intel_pt_queue *ptq) |
1434 | { | 1446 | { |
1435 | struct auxtrace_queue *queue; | 1447 | struct auxtrace_queue *queue; |
@@ -1676,10 +1688,7 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp) | |||
1676 | intel_pt_next_tid(pt, ptq); | 1688 | intel_pt_next_tid(pt, ptq); |
1677 | } | 1689 | } |
1678 | if (pt->synth_opts.errors) { | 1690 | if (pt->synth_opts.errors) { |
1679 | err = intel_pt_synth_error(pt, state->err, | 1691 | err = intel_ptq_synth_error(ptq, state); |
1680 | ptq->cpu, ptq->pid, | ||
1681 | ptq->tid, | ||
1682 | state->from_ip); | ||
1683 | if (err) | 1692 | if (err) |
1684 | return err; | 1693 | return err; |
1685 | } | 1694 | } |
@@ -1804,7 +1813,7 @@ static int intel_pt_process_timeless_queues(struct intel_pt *pt, pid_t tid, | |||
1804 | static int intel_pt_lost(struct intel_pt *pt, struct perf_sample *sample) | 1813 | static int intel_pt_lost(struct intel_pt *pt, struct perf_sample *sample) |
1805 | { | 1814 | { |
1806 | return intel_pt_synth_error(pt, INTEL_PT_ERR_LOST, sample->cpu, | 1815 | return intel_pt_synth_error(pt, INTEL_PT_ERR_LOST, sample->cpu, |
1807 | sample->pid, sample->tid, 0); | 1816 | sample->pid, sample->tid, 0, sample->time); |
1808 | } | 1817 | } |
1809 | 1818 | ||
1810 | static struct intel_pt_queue *intel_pt_cpu_to_ptq(struct intel_pt *pt, int cpu) | 1819 | static struct intel_pt_queue *intel_pt_cpu_to_ptq(struct intel_pt *pt, int cpu) |
diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 835249c77f56..d9525d220db1 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c | |||
@@ -819,7 +819,7 @@ static int s390_cpumsf_process_queues(struct s390_cpumsf *sf, u64 timestamp) | |||
819 | } | 819 | } |
820 | 820 | ||
821 | static int s390_cpumsf_synth_error(struct s390_cpumsf *sf, int code, int cpu, | 821 | static int s390_cpumsf_synth_error(struct s390_cpumsf *sf, int code, int cpu, |
822 | pid_t pid, pid_t tid, u64 ip) | 822 | pid_t pid, pid_t tid, u64 ip, u64 timestamp) |
823 | { | 823 | { |
824 | char msg[MAX_AUXTRACE_ERROR_MSG]; | 824 | char msg[MAX_AUXTRACE_ERROR_MSG]; |
825 | union perf_event event; | 825 | union perf_event event; |
@@ -827,7 +827,7 @@ static int s390_cpumsf_synth_error(struct s390_cpumsf *sf, int code, int cpu, | |||
827 | 827 | ||
828 | strncpy(msg, "Lost Auxiliary Trace Buffer", sizeof(msg) - 1); | 828 | strncpy(msg, "Lost Auxiliary Trace Buffer", sizeof(msg) - 1); |
829 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, | 829 | auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE, |
830 | code, cpu, pid, tid, ip, msg); | 830 | code, cpu, pid, tid, ip, msg, timestamp); |
831 | 831 | ||
832 | err = perf_session__deliver_synth_event(sf->session, &event, NULL); | 832 | err = perf_session__deliver_synth_event(sf->session, &event, NULL); |
833 | if (err) | 833 | if (err) |
@@ -839,7 +839,8 @@ static int s390_cpumsf_synth_error(struct s390_cpumsf *sf, int code, int cpu, | |||
839 | static int s390_cpumsf_lost(struct s390_cpumsf *sf, struct perf_sample *sample) | 839 | static int s390_cpumsf_lost(struct s390_cpumsf *sf, struct perf_sample *sample) |
840 | { | 840 | { |
841 | return s390_cpumsf_synth_error(sf, 1, sample->cpu, | 841 | return s390_cpumsf_synth_error(sf, 1, sample->cpu, |
842 | sample->pid, sample->tid, 0); | 842 | sample->pid, sample->tid, 0, |
843 | sample->time); | ||
843 | } | 844 | } |
844 | 845 | ||
845 | static int | 846 | static int |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2012396abb7c..18fb9c8cbf9c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -703,7 +703,10 @@ static void perf_event__auxtrace_error_swap(union perf_event *event, | |||
703 | event->auxtrace_error.cpu = bswap_32(event->auxtrace_error.cpu); | 703 | event->auxtrace_error.cpu = bswap_32(event->auxtrace_error.cpu); |
704 | event->auxtrace_error.pid = bswap_32(event->auxtrace_error.pid); | 704 | event->auxtrace_error.pid = bswap_32(event->auxtrace_error.pid); |
705 | event->auxtrace_error.tid = bswap_32(event->auxtrace_error.tid); | 705 | event->auxtrace_error.tid = bswap_32(event->auxtrace_error.tid); |
706 | event->auxtrace_error.fmt = bswap_32(event->auxtrace_error.fmt); | ||
706 | event->auxtrace_error.ip = bswap_64(event->auxtrace_error.ip); | 707 | event->auxtrace_error.ip = bswap_64(event->auxtrace_error.ip); |
708 | if (event->auxtrace_error.fmt) | ||
709 | event->auxtrace_error.time = bswap_64(event->auxtrace_error.time); | ||
707 | } | 710 | } |
708 | 711 | ||
709 | static void perf_event__thread_map_swap(union perf_event *event, | 712 | static void perf_event__thread_map_swap(union perf_event *event, |