hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/tools/perf/util/auxtrace.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * auxtrace.c: AUX area trace support
34 * Copyright (c) 2013-2015, Intel Corporation.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
13
- *
145 */
156
167 #include <inttypes.h>
....@@ -27,20 +18,23 @@
2718 #include <linux/bitops.h>
2819 #include <linux/log2.h>
2920 #include <linux/string.h>
21
+#include <linux/time64.h>
3022
3123 #include <sys/param.h>
3224 #include <stdlib.h>
3325 #include <stdio.h>
3426 #include <linux/list.h>
27
+#include <linux/zalloc.h>
3528
36
-#include "../perf.h"
37
-#include "util.h"
3829 #include "evlist.h"
3930 #include "dso.h"
4031 #include "map.h"
4132 #include "pmu.h"
4233 #include "evsel.h"
43
-#include "cpumap.h"
34
+#include "evsel_config.h"
35
+#include "symbol.h"
36
+#include "util/perf_api_probe.h"
37
+#include "util/synthetic-events.h"
4438 #include "thread_map.h"
4539 #include "asm/bug.h"
4640 #include "auxtrace.h"
....@@ -48,6 +42,7 @@
4842 #include <linux/hash.h>
4943
5044 #include "event.h"
45
+#include "record.h"
5146 #include "session.h"
5247 #include "debug.h"
5348 #include <subcmd/parse-options.h>
....@@ -57,9 +52,58 @@
5752 #include "intel-bts.h"
5853 #include "arm-spe.h"
5954 #include "s390-cpumsf.h"
55
+#include "util/mmap.h"
6056
61
-#include "sane_ctype.h"
57
+#include <linux/ctype.h>
6258 #include "symbol/kallsyms.h"
59
+#include <internal/lib.h>
60
+
61
+/*
62
+ * Make a group from 'leader' to 'last', requiring that the events were not
63
+ * already grouped to a different leader.
64
+ */
65
+static int perf_evlist__regroup(struct evlist *evlist,
66
+ struct evsel *leader,
67
+ struct evsel *last)
68
+{
69
+ struct evsel *evsel;
70
+ bool grp;
71
+
72
+ if (!evsel__is_group_leader(leader))
73
+ return -EINVAL;
74
+
75
+ grp = false;
76
+ evlist__for_each_entry(evlist, evsel) {
77
+ if (grp) {
78
+ if (!(evsel->leader == leader ||
79
+ (evsel->leader == evsel &&
80
+ evsel->core.nr_members <= 1)))
81
+ return -EINVAL;
82
+ } else if (evsel == leader) {
83
+ grp = true;
84
+ }
85
+ if (evsel == last)
86
+ break;
87
+ }
88
+
89
+ grp = false;
90
+ evlist__for_each_entry(evlist, evsel) {
91
+ if (grp) {
92
+ if (evsel->leader != leader) {
93
+ evsel->leader = leader;
94
+ if (leader->core.nr_members < 1)
95
+ leader->core.nr_members = 1;
96
+ leader->core.nr_members += 1;
97
+ }
98
+ } else if (evsel == leader) {
99
+ grp = true;
100
+ }
101
+ if (evsel == last)
102
+ break;
103
+ }
104
+
105
+ return 0;
106
+}
63107
64108 static bool auxtrace__dont_decode(struct perf_session *session)
65109 {
....@@ -131,20 +175,20 @@
131175 }
132176
133177 void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp,
134
- struct perf_evlist *evlist, int idx,
178
+ struct evlist *evlist, int idx,
135179 bool per_cpu)
136180 {
137181 mp->idx = idx;
138182
139183 if (per_cpu) {
140
- mp->cpu = evlist->cpus->map[idx];
141
- if (evlist->threads)
142
- mp->tid = thread_map__pid(evlist->threads, 0);
184
+ mp->cpu = evlist->core.cpus->map[idx];
185
+ if (evlist->core.threads)
186
+ mp->tid = perf_thread_map__pid(evlist->core.threads, 0);
143187 else
144188 mp->tid = -1;
145189 } else {
146190 mp->cpu = -1;
147
- mp->tid = thread_map__pid(evlist->threads, idx);
191
+ mp->tid = perf_thread_map__pid(evlist->core.threads, idx);
148192 }
149193 }
150194
....@@ -388,7 +432,7 @@
388432 return err;
389433
390434 if (event->header.type == PERF_RECORD_AUXTRACE) {
391
- if (event->header.size < sizeof(struct auxtrace_event) ||
435
+ if (event->header.size < sizeof(struct perf_record_auxtrace) ||
392436 event->header.size != sz) {
393437 err = -EINVAL;
394438 goto out;
....@@ -411,7 +455,7 @@
411455
412456 buffer = list_entry(queues->queue_array[i].head.next,
413457 struct auxtrace_buffer, list);
414
- list_del(&buffer->list);
458
+ list_del_init(&buffer->list);
415459 auxtrace_buffer__free(buffer);
416460 }
417461 }
....@@ -506,7 +550,7 @@
506550 }
507551
508552 size_t auxtrace_record__info_priv_size(struct auxtrace_record *itr,
509
- struct perf_evlist *evlist)
553
+ struct evlist *evlist)
510554 {
511555 if (itr)
512556 return itr->info_priv_size(itr, evlist);
....@@ -521,7 +565,7 @@
521565
522566 int auxtrace_record__info_fill(struct auxtrace_record *itr,
523567 struct perf_session *session,
524
- struct auxtrace_info_event *auxtrace_info,
568
+ struct perf_record_auxtrace_info *auxtrace_info,
525569 size_t priv_size)
526570 {
527571 if (itr)
....@@ -542,9 +586,9 @@
542586 return 0;
543587 }
544588
545
-int auxtrace_record__snapshot_finish(struct auxtrace_record *itr)
589
+int auxtrace_record__snapshot_finish(struct auxtrace_record *itr, bool on_exit)
546590 {
547
- if (itr && itr->snapshot_finish)
591
+ if (!on_exit && itr && itr->snapshot_finish)
548592 return itr->snapshot_finish(itr);
549593 return 0;
550594 }
....@@ -559,11 +603,13 @@
559603 }
560604
561605 int auxtrace_record__options(struct auxtrace_record *itr,
562
- struct perf_evlist *evlist,
606
+ struct evlist *evlist,
563607 struct record_opts *opts)
564608 {
565
- if (itr)
609
+ if (itr) {
610
+ itr->evlist = evlist;
566611 return itr->recording_options(itr, evlist, opts);
612
+ }
567613 return 0;
568614 }
569615
....@@ -580,15 +626,169 @@
580626 if (!str)
581627 return 0;
582628
583
- if (itr)
629
+ /* PMU-agnostic options */
630
+ switch (*str) {
631
+ case 'e':
632
+ opts->auxtrace_snapshot_on_exit = true;
633
+ str++;
634
+ break;
635
+ default:
636
+ break;
637
+ }
638
+
639
+ if (itr && itr->parse_snapshot_options)
584640 return itr->parse_snapshot_options(itr, opts, str);
585641
586642 pr_err("No AUX area tracing to snapshot\n");
587643 return -EINVAL;
588644 }
589645
646
+int auxtrace_record__read_finish(struct auxtrace_record *itr, int idx)
647
+{
648
+ struct evsel *evsel;
649
+
650
+ if (!itr->evlist || !itr->pmu)
651
+ return -EINVAL;
652
+
653
+ evlist__for_each_entry(itr->evlist, evsel) {
654
+ if (evsel->core.attr.type == itr->pmu->type) {
655
+ if (evsel->disabled)
656
+ return 0;
657
+ return perf_evlist__enable_event_idx(itr->evlist, evsel,
658
+ idx);
659
+ }
660
+ }
661
+ return -EINVAL;
662
+}
663
+
664
+/*
665
+ * Event record size is 16-bit which results in a maximum size of about 64KiB.
666
+ * Allow about 4KiB for the rest of the sample record, to give a maximum
667
+ * AUX area sample size of 60KiB.
668
+ */
669
+#define MAX_AUX_SAMPLE_SIZE (60 * 1024)
670
+
671
+/* Arbitrary default size if no other default provided */
672
+#define DEFAULT_AUX_SAMPLE_SIZE (4 * 1024)
673
+
674
+static int auxtrace_validate_aux_sample_size(struct evlist *evlist,
675
+ struct record_opts *opts)
676
+{
677
+ struct evsel *evsel;
678
+ bool has_aux_leader = false;
679
+ u32 sz;
680
+
681
+ evlist__for_each_entry(evlist, evsel) {
682
+ sz = evsel->core.attr.aux_sample_size;
683
+ if (evsel__is_group_leader(evsel)) {
684
+ has_aux_leader = evsel__is_aux_event(evsel);
685
+ if (sz) {
686
+ if (has_aux_leader)
687
+ pr_err("Cannot add AUX area sampling to an AUX area event\n");
688
+ else
689
+ pr_err("Cannot add AUX area sampling to a group leader\n");
690
+ return -EINVAL;
691
+ }
692
+ }
693
+ if (sz > MAX_AUX_SAMPLE_SIZE) {
694
+ pr_err("AUX area sample size %u too big, max. %d\n",
695
+ sz, MAX_AUX_SAMPLE_SIZE);
696
+ return -EINVAL;
697
+ }
698
+ if (sz) {
699
+ if (!has_aux_leader) {
700
+ pr_err("Cannot add AUX area sampling because group leader is not an AUX area event\n");
701
+ return -EINVAL;
702
+ }
703
+ evsel__set_sample_bit(evsel, AUX);
704
+ opts->auxtrace_sample_mode = true;
705
+ } else {
706
+ evsel__reset_sample_bit(evsel, AUX);
707
+ }
708
+ }
709
+
710
+ if (!opts->auxtrace_sample_mode) {
711
+ pr_err("AUX area sampling requires an AUX area event group leader plus other events to which to add samples\n");
712
+ return -EINVAL;
713
+ }
714
+
715
+ if (!perf_can_aux_sample()) {
716
+ pr_err("AUX area sampling is not supported by kernel\n");
717
+ return -EINVAL;
718
+ }
719
+
720
+ return 0;
721
+}
722
+
723
+int auxtrace_parse_sample_options(struct auxtrace_record *itr,
724
+ struct evlist *evlist,
725
+ struct record_opts *opts, const char *str)
726
+{
727
+ struct evsel_config_term *term;
728
+ struct evsel *aux_evsel;
729
+ bool has_aux_sample_size = false;
730
+ bool has_aux_leader = false;
731
+ struct evsel *evsel;
732
+ char *endptr;
733
+ unsigned long sz;
734
+
735
+ if (!str)
736
+ goto no_opt;
737
+
738
+ if (!itr) {
739
+ pr_err("No AUX area event to sample\n");
740
+ return -EINVAL;
741
+ }
742
+
743
+ sz = strtoul(str, &endptr, 0);
744
+ if (*endptr || sz > UINT_MAX) {
745
+ pr_err("Bad AUX area sampling option: '%s'\n", str);
746
+ return -EINVAL;
747
+ }
748
+
749
+ if (!sz)
750
+ sz = itr->default_aux_sample_size;
751
+
752
+ if (!sz)
753
+ sz = DEFAULT_AUX_SAMPLE_SIZE;
754
+
755
+ /* Set aux_sample_size based on --aux-sample option */
756
+ evlist__for_each_entry(evlist, evsel) {
757
+ if (evsel__is_group_leader(evsel)) {
758
+ has_aux_leader = evsel__is_aux_event(evsel);
759
+ } else if (has_aux_leader) {
760
+ evsel->core.attr.aux_sample_size = sz;
761
+ }
762
+ }
763
+no_opt:
764
+ aux_evsel = NULL;
765
+ /* Override with aux_sample_size from config term */
766
+ evlist__for_each_entry(evlist, evsel) {
767
+ if (evsel__is_aux_event(evsel))
768
+ aux_evsel = evsel;
769
+ term = evsel__get_config_term(evsel, AUX_SAMPLE_SIZE);
770
+ if (term) {
771
+ has_aux_sample_size = true;
772
+ evsel->core.attr.aux_sample_size = term->val.aux_sample_size;
773
+ /* If possible, group with the AUX event */
774
+ if (aux_evsel && evsel->core.attr.aux_sample_size)
775
+ perf_evlist__regroup(evlist, aux_evsel, evsel);
776
+ }
777
+ }
778
+
779
+ if (!str && !has_aux_sample_size)
780
+ return 0;
781
+
782
+ if (!itr) {
783
+ pr_err("No AUX area event to sample\n");
784
+ return -EINVAL;
785
+ }
786
+
787
+ return auxtrace_validate_aux_sample_size(evlist, opts);
788
+}
789
+
590790 struct auxtrace_record *__weak
591
-auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, int *err)
791
+auxtrace_record__init(struct evlist *evlist __maybe_unused, int *err)
592792 {
593793 *err = 0;
594794 return NULL;
....@@ -615,7 +815,7 @@
615815 struct auxtrace_index *auxtrace_index, *n;
616816
617817 list_for_each_entry_safe(auxtrace_index, n, head, list) {
618
- list_del(&auxtrace_index->list);
818
+ list_del_init(&auxtrace_index->list);
619819 free(auxtrace_index);
620820 }
621821 }
....@@ -801,6 +1001,113 @@
8011001 }
8021002 }
8031003
1004
+struct auxtrace_queue *auxtrace_queues__sample_queue(struct auxtrace_queues *queues,
1005
+ struct perf_sample *sample,
1006
+ struct perf_session *session)
1007
+{
1008
+ struct perf_sample_id *sid;
1009
+ unsigned int idx;
1010
+ u64 id;
1011
+
1012
+ id = sample->id;
1013
+ if (!id)
1014
+ return NULL;
1015
+
1016
+ sid = perf_evlist__id2sid(session->evlist, id);
1017
+ if (!sid)
1018
+ return NULL;
1019
+
1020
+ idx = sid->idx;
1021
+
1022
+ if (idx >= queues->nr_queues)
1023
+ return NULL;
1024
+
1025
+ return &queues->queue_array[idx];
1026
+}
1027
+
1028
+int auxtrace_queues__add_sample(struct auxtrace_queues *queues,
1029
+ struct perf_session *session,
1030
+ struct perf_sample *sample, u64 data_offset,
1031
+ u64 reference)
1032
+{
1033
+ struct auxtrace_buffer buffer = {
1034
+ .pid = -1,
1035
+ .data_offset = data_offset,
1036
+ .reference = reference,
1037
+ .size = sample->aux_sample.size,
1038
+ };
1039
+ struct perf_sample_id *sid;
1040
+ u64 id = sample->id;
1041
+ unsigned int idx;
1042
+
1043
+ if (!id)
1044
+ return -EINVAL;
1045
+
1046
+ sid = perf_evlist__id2sid(session->evlist, id);
1047
+ if (!sid)
1048
+ return -ENOENT;
1049
+
1050
+ idx = sid->idx;
1051
+ buffer.tid = sid->tid;
1052
+ buffer.cpu = sid->cpu;
1053
+
1054
+ return auxtrace_queues__add_buffer(queues, session, idx, &buffer, NULL);
1055
+}
1056
+
1057
+struct queue_data {
1058
+ bool samples;
1059
+ bool events;
1060
+};
1061
+
1062
+static int auxtrace_queue_data_cb(struct perf_session *session,
1063
+ union perf_event *event, u64 offset,
1064
+ void *data)
1065
+{
1066
+ struct queue_data *qd = data;
1067
+ struct perf_sample sample;
1068
+ int err;
1069
+
1070
+ if (qd->events && event->header.type == PERF_RECORD_AUXTRACE) {
1071
+ if (event->header.size < sizeof(struct perf_record_auxtrace))
1072
+ return -EINVAL;
1073
+ offset += event->header.size;
1074
+ return session->auxtrace->queue_data(session, NULL, event,
1075
+ offset);
1076
+ }
1077
+
1078
+ if (!qd->samples || event->header.type != PERF_RECORD_SAMPLE)
1079
+ return 0;
1080
+
1081
+ err = perf_evlist__parse_sample(session->evlist, event, &sample);
1082
+ if (err)
1083
+ return err;
1084
+
1085
+ if (!sample.aux_sample.size)
1086
+ return 0;
1087
+
1088
+ offset += sample.aux_sample.data - (void *)event;
1089
+
1090
+ return session->auxtrace->queue_data(session, &sample, NULL, offset);
1091
+}
1092
+
1093
+int auxtrace_queue_data(struct perf_session *session, bool samples, bool events)
1094
+{
1095
+ struct queue_data qd = {
1096
+ .samples = samples,
1097
+ .events = events,
1098
+ };
1099
+
1100
+ if (auxtrace__dont_decode(session))
1101
+ return 0;
1102
+
1103
+ if (!session->auxtrace || !session->auxtrace->queue_data)
1104
+ return -EINVAL;
1105
+
1106
+ return perf_session__peek_events(session, session->header.data_offset,
1107
+ session->header.data_size,
1108
+ auxtrace_queue_data_cb, &qd);
1109
+}
1110
+
8041111 void *auxtrace_buffer__get_data(struct auxtrace_buffer *buffer, int fd)
8051112 {
8061113 size_t adj = buffer->data_offset & (page_size - 1);
....@@ -851,13 +1158,13 @@
8511158 free(buffer);
8521159 }
8531160
854
-void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type,
1161
+void auxtrace_synth_error(struct perf_record_auxtrace_error *auxtrace_error, int type,
8551162 int code, int cpu, pid_t pid, pid_t tid, u64 ip,
856
- const char *msg)
1163
+ const char *msg, u64 timestamp)
8571164 {
8581165 size_t size;
8591166
860
- memset(auxtrace_error, 0, sizeof(struct auxtrace_error_event));
1167
+ memset(auxtrace_error, 0, sizeof(struct perf_record_auxtrace_error));
8611168
8621169 auxtrace_error->header.type = PERF_RECORD_AUXTRACE_ERROR;
8631170 auxtrace_error->type = type;
....@@ -865,7 +1172,9 @@
8651172 auxtrace_error->cpu = cpu;
8661173 auxtrace_error->pid = pid;
8671174 auxtrace_error->tid = tid;
1175
+ auxtrace_error->fmt = 1;
8681176 auxtrace_error->ip = ip;
1177
+ auxtrace_error->time = timestamp;
8691178 strlcpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG);
8701179
8711180 size = (void *)auxtrace_error->msg - (void *)auxtrace_error +
....@@ -884,12 +1193,12 @@
8841193
8851194 pr_debug2("Synthesizing auxtrace information\n");
8861195 priv_size = auxtrace_record__info_priv_size(itr, session->evlist);
887
- ev = zalloc(sizeof(struct auxtrace_info_event) + priv_size);
1196
+ ev = zalloc(sizeof(struct perf_record_auxtrace_info) + priv_size);
8881197 if (!ev)
8891198 return -ENOMEM;
8901199
8911200 ev->auxtrace_info.header.type = PERF_RECORD_AUXTRACE_INFO;
892
- ev->auxtrace_info.header.size = sizeof(struct auxtrace_info_event) +
1201
+ ev->auxtrace_info.header.size = sizeof(struct perf_record_auxtrace_info) +
8931202 priv_size;
8941203 err = auxtrace_record__info_fill(itr, session, &ev->auxtrace_info,
8951204 priv_size);
....@@ -902,40 +1211,88 @@
9021211 return err;
9031212 }
9041213
905
-int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
906
- union perf_event *event,
907
- struct perf_session *session)
1214
+static void unleader_evsel(struct evlist *evlist, struct evsel *leader)
1215
+{
1216
+ struct evsel *new_leader = NULL;
1217
+ struct evsel *evsel;
1218
+
1219
+ /* Find new leader for the group */
1220
+ evlist__for_each_entry(evlist, evsel) {
1221
+ if (evsel->leader != leader || evsel == leader)
1222
+ continue;
1223
+ if (!new_leader)
1224
+ new_leader = evsel;
1225
+ evsel->leader = new_leader;
1226
+ }
1227
+
1228
+ /* Update group information */
1229
+ if (new_leader) {
1230
+ zfree(&new_leader->group_name);
1231
+ new_leader->group_name = leader->group_name;
1232
+ leader->group_name = NULL;
1233
+
1234
+ new_leader->core.nr_members = leader->core.nr_members - 1;
1235
+ leader->core.nr_members = 1;
1236
+ }
1237
+}
1238
+
1239
+static void unleader_auxtrace(struct perf_session *session)
1240
+{
1241
+ struct evsel *evsel;
1242
+
1243
+ evlist__for_each_entry(session->evlist, evsel) {
1244
+ if (auxtrace__evsel_is_auxtrace(session, evsel) &&
1245
+ evsel__is_group_leader(evsel)) {
1246
+ unleader_evsel(session->evlist, evsel);
1247
+ }
1248
+ }
1249
+}
1250
+
1251
+int perf_event__process_auxtrace_info(struct perf_session *session,
1252
+ union perf_event *event)
9081253 {
9091254 enum auxtrace_type type = event->auxtrace_info.type;
1255
+ int err;
9101256
9111257 if (dump_trace)
9121258 fprintf(stdout, " type: %u\n", type);
9131259
9141260 switch (type) {
9151261 case PERF_AUXTRACE_INTEL_PT:
916
- return intel_pt_process_auxtrace_info(event, session);
1262
+ err = intel_pt_process_auxtrace_info(event, session);
1263
+ break;
9171264 case PERF_AUXTRACE_INTEL_BTS:
918
- return intel_bts_process_auxtrace_info(event, session);
1265
+ err = intel_bts_process_auxtrace_info(event, session);
1266
+ break;
9191267 case PERF_AUXTRACE_ARM_SPE:
920
- return arm_spe_process_auxtrace_info(event, session);
1268
+ err = arm_spe_process_auxtrace_info(event, session);
1269
+ break;
9211270 case PERF_AUXTRACE_CS_ETM:
922
- return cs_etm__process_auxtrace_info(event, session);
1271
+ err = cs_etm__process_auxtrace_info(event, session);
1272
+ break;
9231273 case PERF_AUXTRACE_S390_CPUMSF:
924
- return s390_cpumsf_process_auxtrace_info(event, session);
1274
+ err = s390_cpumsf_process_auxtrace_info(event, session);
1275
+ break;
9251276 case PERF_AUXTRACE_UNKNOWN:
9261277 default:
9271278 return -EINVAL;
9281279 }
1280
+
1281
+ if (err)
1282
+ return err;
1283
+
1284
+ unleader_auxtrace(session);
1285
+
1286
+ return 0;
9291287 }
9301288
931
-s64 perf_event__process_auxtrace(struct perf_tool *tool,
932
- union perf_event *event,
933
- struct perf_session *session)
1289
+s64 perf_event__process_auxtrace(struct perf_session *session,
1290
+ union perf_event *event)
9341291 {
9351292 s64 err;
9361293
9371294 if (dump_trace)
938
- fprintf(stdout, " size: %#"PRIx64" offset: %#"PRIx64" ref: %#"PRIx64" idx: %u tid: %d cpu: %d\n",
1295
+ fprintf(stdout, " size: %#"PRI_lx64" offset: %#"PRI_lx64" ref: %#"PRI_lx64" idx: %u tid: %d cpu: %d\n",
9391296 event->auxtrace.size, event->auxtrace.offset,
9401297 event->auxtrace.reference, event->auxtrace.idx,
9411298 event->auxtrace.tid, event->auxtrace.cpu);
....@@ -946,7 +1303,7 @@
9461303 if (!session->auxtrace || event->header.type != PERF_RECORD_AUXTRACE)
9471304 return -EINVAL;
9481305
949
- err = session->auxtrace->process_auxtrace_event(session, event, tool);
1306
+ err = session->auxtrace->process_auxtrace_event(session, event, session->tool);
9501307 if (err < 0)
9511308 return err;
9521309
....@@ -960,19 +1317,73 @@
9601317 #define PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ 64
9611318 #define PERF_ITRACE_MAX_LAST_BRANCH_SZ 1024
9621319
963
-void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts)
1320
+void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts,
1321
+ bool no_sample)
9641322 {
965
- synth_opts->instructions = true;
9661323 synth_opts->branches = true;
9671324 synth_opts->transactions = true;
9681325 synth_opts->ptwrites = true;
9691326 synth_opts->pwr_events = true;
1327
+ synth_opts->other_events = true;
9701328 synth_opts->errors = true;
971
- synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE;
972
- synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
1329
+ synth_opts->flc = true;
1330
+ synth_opts->llc = true;
1331
+ synth_opts->tlb = true;
1332
+ synth_opts->remote_access = true;
1333
+
1334
+ if (no_sample) {
1335
+ synth_opts->period_type = PERF_ITRACE_PERIOD_INSTRUCTIONS;
1336
+ synth_opts->period = 1;
1337
+ synth_opts->calls = true;
1338
+ } else {
1339
+ synth_opts->instructions = true;
1340
+ synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE;
1341
+ synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
1342
+ }
9731343 synth_opts->callchain_sz = PERF_ITRACE_DEFAULT_CALLCHAIN_SZ;
9741344 synth_opts->last_branch_sz = PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ;
9751345 synth_opts->initial_skip = 0;
1346
+}
1347
+
1348
+static int get_flag(const char **ptr, unsigned int *flags)
1349
+{
1350
+ while (1) {
1351
+ char c = **ptr;
1352
+
1353
+ if (c >= 'a' && c <= 'z') {
1354
+ *flags |= 1 << (c - 'a');
1355
+ ++*ptr;
1356
+ return 0;
1357
+ } else if (c == ' ') {
1358
+ ++*ptr;
1359
+ continue;
1360
+ } else {
1361
+ return -1;
1362
+ }
1363
+ }
1364
+}
1365
+
1366
+static int get_flags(const char **ptr, unsigned int *plus_flags, unsigned int *minus_flags)
1367
+{
1368
+ while (1) {
1369
+ switch (**ptr) {
1370
+ case '+':
1371
+ ++*ptr;
1372
+ if (get_flag(ptr, plus_flags))
1373
+ return -1;
1374
+ break;
1375
+ case '-':
1376
+ ++*ptr;
1377
+ if (get_flag(ptr, minus_flags))
1378
+ return -1;
1379
+ break;
1380
+ case ' ':
1381
+ ++*ptr;
1382
+ break;
1383
+ default:
1384
+ return 0;
1385
+ }
1386
+ }
9761387 }
9771388
9781389 /*
....@@ -997,7 +1408,8 @@
9971408 }
9981409
9991410 if (!str) {
1000
- itrace_synth_opts__set_default(synth_opts);
1411
+ itrace_synth_opts__set_default(synth_opts,
1412
+ synth_opts->default_no_sample);
10011413 return 0;
10021414 }
10031415
....@@ -1056,11 +1468,20 @@
10561468 case 'p':
10571469 synth_opts->pwr_events = true;
10581470 break;
1471
+ case 'o':
1472
+ synth_opts->other_events = true;
1473
+ break;
10591474 case 'e':
10601475 synth_opts->errors = true;
1476
+ if (get_flags(&p, &synth_opts->error_plus_flags,
1477
+ &synth_opts->error_minus_flags))
1478
+ goto out_err;
10611479 break;
10621480 case 'd':
10631481 synth_opts->log = true;
1482
+ if (get_flags(&p, &synth_opts->log_plus_flags,
1483
+ &synth_opts->log_minus_flags))
1484
+ goto out_err;
10641485 break;
10651486 case 'c':
10661487 synth_opts->branches = true;
....@@ -1070,8 +1491,12 @@
10701491 synth_opts->branches = true;
10711492 synth_opts->returns = true;
10721493 break;
1494
+ case 'G':
10731495 case 'g':
1074
- synth_opts->callchain = true;
1496
+ if (p[-1] == 'G')
1497
+ synth_opts->add_callchain = true;
1498
+ else
1499
+ synth_opts->callchain = true;
10751500 synth_opts->callchain_sz =
10761501 PERF_ITRACE_DEFAULT_CALLCHAIN_SZ;
10771502 while (*p == ' ' || *p == ',')
....@@ -1086,8 +1511,12 @@
10861511 synth_opts->callchain_sz = val;
10871512 }
10881513 break;
1514
+ case 'L':
10891515 case 'l':
1090
- synth_opts->last_branch = true;
1516
+ if (p[-1] == 'L')
1517
+ synth_opts->add_last_branch = true;
1518
+ else
1519
+ synth_opts->last_branch = true;
10911520 synth_opts->last_branch_sz =
10921521 PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ;
10931522 while (*p == ' ' || *p == ',')
....@@ -1108,6 +1537,21 @@
11081537 if (p == endptr)
11091538 goto out_err;
11101539 p = endptr;
1540
+ break;
1541
+ case 'f':
1542
+ synth_opts->flc = true;
1543
+ break;
1544
+ case 'm':
1545
+ synth_opts->llc = true;
1546
+ break;
1547
+ case 't':
1548
+ synth_opts->tlb = true;
1549
+ break;
1550
+ case 'a':
1551
+ synth_opts->remote_access = true;
1552
+ break;
1553
+ case 'q':
1554
+ synth_opts->quick += 1;
11111555 break;
11121556 case ' ':
11131557 case ',':
....@@ -1149,20 +1593,35 @@
11491593
11501594 size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *fp)
11511595 {
1152
- struct auxtrace_error_event *e = &event->auxtrace_error;
1596
+ struct perf_record_auxtrace_error *e = &event->auxtrace_error;
1597
+ unsigned long long nsecs = e->time;
1598
+ const char *msg = e->msg;
11531599 int ret;
11541600
11551601 ret = fprintf(fp, " %s error type %u",
11561602 auxtrace_error_name(e->type), e->type);
1157
- ret += fprintf(fp, " cpu %d pid %d tid %d ip %#"PRIx64" code %u: %s\n",
1158
- e->cpu, e->pid, e->tid, e->ip, e->code, e->msg);
1603
+
1604
+ if (e->fmt && nsecs) {
1605
+ unsigned long secs = nsecs / NSEC_PER_SEC;
1606
+
1607
+ nsecs -= secs * NSEC_PER_SEC;
1608
+ ret += fprintf(fp, " time %lu.%09llu", secs, nsecs);
1609
+ } else {
1610
+ ret += fprintf(fp, " time 0");
1611
+ }
1612
+
1613
+ if (!e->fmt)
1614
+ msg = (const char *)&e->time;
1615
+
1616
+ ret += fprintf(fp, " cpu %d pid %d tid %d ip %#"PRI_lx64" code %u: %s\n",
1617
+ e->cpu, e->pid, e->tid, e->ip, e->code, msg);
11591618 return ret;
11601619 }
11611620
11621621 void perf_session__auxtrace_error_inc(struct perf_session *session,
11631622 union perf_event *event)
11641623 {
1165
- struct auxtrace_error_event *e = &event->auxtrace_error;
1624
+ struct perf_record_auxtrace_error *e = &event->auxtrace_error;
11661625
11671626 if (e->type < PERF_AUXTRACE_ERROR_MAX)
11681627 session->evlist->stats.nr_auxtrace_errors[e->type] += 1;
....@@ -1181,9 +1640,8 @@
11811640 }
11821641 }
11831642
1184
-int perf_event__process_auxtrace_error(struct perf_tool *tool __maybe_unused,
1185
- union perf_event *event,
1186
- struct perf_session *session)
1643
+int perf_event__process_auxtrace_error(struct perf_session *session,
1644
+ union perf_event *event)
11871645 {
11881646 if (auxtrace__dont_decode(session))
11891647 return 0;
....@@ -1192,11 +1650,12 @@
11921650 return 0;
11931651 }
11941652
1195
-static int __auxtrace_mmap__read(struct auxtrace_mmap *mm,
1653
+static int __auxtrace_mmap__read(struct mmap *map,
11961654 struct auxtrace_record *itr,
11971655 struct perf_tool *tool, process_auxtrace_t fn,
11981656 bool snapshot, size_t snapshot_size)
11991657 {
1658
+ struct auxtrace_mmap *mm = &map->auxtrace_mmap;
12001659 u64 head, old = mm->prev, offset, ref;
12011660 unsigned char *data = mm->base;
12021661 size_t size, head_off, old_off, len1, len2, padding;
....@@ -1283,7 +1742,7 @@
12831742 ev.auxtrace.tid = mm->tid;
12841743 ev.auxtrace.cpu = mm->cpu;
12851744
1286
- if (fn(tool, &ev, data1, len1, data2, len2))
1745
+ if (fn(tool, map, &ev, data1, len1, data2, len2))
12871746 return -1;
12881747
12891748 mm->prev = head;
....@@ -1302,18 +1761,18 @@
13021761 return 1;
13031762 }
13041763
1305
-int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
1764
+int auxtrace_mmap__read(struct mmap *map, struct auxtrace_record *itr,
13061765 struct perf_tool *tool, process_auxtrace_t fn)
13071766 {
1308
- return __auxtrace_mmap__read(mm, itr, tool, fn, false, 0);
1767
+ return __auxtrace_mmap__read(map, itr, tool, fn, false, 0);
13091768 }
13101769
1311
-int auxtrace_mmap__read_snapshot(struct auxtrace_mmap *mm,
1770
+int auxtrace_mmap__read_snapshot(struct mmap *map,
13121771 struct auxtrace_record *itr,
13131772 struct perf_tool *tool, process_auxtrace_t fn,
13141773 size_t snapshot_size)
13151774 {
1316
- return __auxtrace_mmap__read(mm, itr, tool, fn, true, snapshot_size);
1775
+ return __auxtrace_mmap__read(map, itr, tool, fn, true, snapshot_size);
13171776 }
13181777
13191778 /**
....@@ -1393,7 +1852,7 @@
13931852 return;
13941853
13951854 auxtrace_cache__drop(c);
1396
- free(c->hashtable);
1855
+ zfree(&c->hashtable);
13971856 free(c);
13981857 }
13991858
....@@ -1420,6 +1879,34 @@
14201879 return 0;
14211880 }
14221881
1882
+static struct auxtrace_cache_entry *auxtrace_cache__rm(struct auxtrace_cache *c,
1883
+ u32 key)
1884
+{
1885
+ struct auxtrace_cache_entry *entry;
1886
+ struct hlist_head *hlist;
1887
+ struct hlist_node *n;
1888
+
1889
+ if (!c)
1890
+ return NULL;
1891
+
1892
+ hlist = &c->hashtable[hash_32(key, c->bits)];
1893
+ hlist_for_each_entry_safe(entry, n, hlist, hash) {
1894
+ if (entry->key == key) {
1895
+ hlist_del(&entry->hash);
1896
+ return entry;
1897
+ }
1898
+ }
1899
+
1900
+ return NULL;
1901
+}
1902
+
1903
+void auxtrace_cache__remove(struct auxtrace_cache *c, u32 key)
1904
+{
1905
+ struct auxtrace_cache_entry *entry = auxtrace_cache__rm(c, key);
1906
+
1907
+ auxtrace_cache__free_entry(c, entry);
1908
+}
1909
+
14231910 void *auxtrace_cache__lookup(struct auxtrace_cache *c, u32 key)
14241911 {
14251912 struct auxtrace_cache_entry *entry;
....@@ -1439,12 +1926,11 @@
14391926
14401927 static void addr_filter__free_str(struct addr_filter *filt)
14411928 {
1442
- free(filt->str);
1929
+ zfree(&filt->str);
14431930 filt->action = NULL;
14441931 filt->sym_from = NULL;
14451932 filt->sym_to = NULL;
14461933 filt->filename = NULL;
1447
- filt->str = NULL;
14481934 }
14491935
14501936 static struct addr_filter *addr_filter__new(void)
....@@ -1678,11 +2164,19 @@
16782164 bool near;
16792165 };
16802166
2167
+static bool kern_sym_name_match(const char *kname, const char *name)
2168
+{
2169
+ size_t n = strlen(name);
2170
+
2171
+ return !strcmp(kname, name) ||
2172
+ (!strncmp(kname, name, n) && kname[n] == '\t');
2173
+}
2174
+
16812175 static bool kern_sym_match(struct sym_args *args, const char *name, char type)
16822176 {
16832177 /* A function with the same name, and global or the n'th found or any */
16842178 return kallsyms__is_function(type) &&
1685
- !strcmp(name, args->name) &&
2179
+ kern_sym_name_match(name, args->name) &&
16862180 ((args->global && isupper(type)) ||
16872181 (args->selected && ++(args->cnt) == args->idx) ||
16882182 (!args->global && !args->selected));
....@@ -1890,7 +2384,8 @@
18902384 if (!map)
18912385 return NULL;
18922386
1893
- map__load(map);
2387
+ if (map__load(map) < 0)
2388
+ pr_err("File '%s' not found or has no symbols.\n", name);
18942389
18952390 dso = dso__get(map->dso);
18962391
....@@ -1974,17 +2469,14 @@
19742469
19752470 static int addr_filter__entire_dso(struct addr_filter *filt, struct dso *dso)
19762471 {
1977
- struct symbol *first_sym = dso__first_symbol(dso);
1978
- struct symbol *last_sym = dso__last_symbol(dso);
1979
-
1980
- if (!first_sym || !last_sym) {
1981
- pr_err("Failed to determine filter for %s\nNo symbols found.\n",
2472
+ if (dso__data_file_size(dso, NULL)) {
2473
+ pr_err("Failed to determine filter for %s\nCannot determine file size.\n",
19822474 filt->filename);
19832475 return -EINVAL;
19842476 }
19852477
1986
- filt->addr = first_sym->start;
1987
- filt->size = last_sym->end - first_sym->start;
2478
+ filt->addr = 0;
2479
+ filt->size = dso->data.file_size;
19882480
19892481 return 0;
19902482 }
....@@ -2067,7 +2559,7 @@
20672559 return err < 0 ? NULL : filter;
20682560 }
20692561
2070
-static int parse_addr_filter(struct perf_evsel *evsel, const char *filter,
2562
+static int parse_addr_filter(struct evsel *evsel, const char *filter,
20712563 int max_nr)
20722564 {
20732565 struct addr_filters filts;
....@@ -2100,7 +2592,7 @@
21002592 goto out_exit;
21012593 }
21022594
2103
- if (perf_evsel__append_addr_filter(evsel, new_filter)) {
2595
+ if (evsel__append_addr_filter(evsel, new_filter)) {
21042596 err = -ENOMEM;
21052597 goto out_exit;
21062598 }
....@@ -2118,21 +2610,9 @@
21182610 return err;
21192611 }
21202612
2121
-static struct perf_pmu *perf_evsel__find_pmu(struct perf_evsel *evsel)
2613
+static int evsel__nr_addr_filter(struct evsel *evsel)
21222614 {
2123
- struct perf_pmu *pmu = NULL;
2124
-
2125
- while ((pmu = perf_pmu__scan(pmu)) != NULL) {
2126
- if (pmu->type == evsel->attr.type)
2127
- break;
2128
- }
2129
-
2130
- return pmu;
2131
-}
2132
-
2133
-static int perf_evsel__nr_addr_filter(struct perf_evsel *evsel)
2134
-{
2135
- struct perf_pmu *pmu = perf_evsel__find_pmu(evsel);
2615
+ struct perf_pmu *pmu = evsel__find_pmu(evsel);
21362616 int nr_addr_filters = 0;
21372617
21382618 if (!pmu)
....@@ -2143,15 +2623,15 @@
21432623 return nr_addr_filters;
21442624 }
21452625
2146
-int auxtrace_parse_filters(struct perf_evlist *evlist)
2626
+int auxtrace_parse_filters(struct evlist *evlist)
21472627 {
2148
- struct perf_evsel *evsel;
2628
+ struct evsel *evsel;
21492629 char *filter;
21502630 int err, max_nr;
21512631
21522632 evlist__for_each_entry(evlist, evsel) {
21532633 filter = evsel->filter;
2154
- max_nr = perf_evsel__nr_addr_filter(evsel);
2634
+ max_nr = evsel__nr_addr_filter(evsel);
21552635 if (!filter || !max_nr)
21562636 continue;
21572637 evsel->filter = NULL;
....@@ -2164,3 +2644,55 @@
21642644
21652645 return 0;
21662646 }
2647
+
2648
+int auxtrace__process_event(struct perf_session *session, union perf_event *event,
2649
+ struct perf_sample *sample, struct perf_tool *tool)
2650
+{
2651
+ if (!session->auxtrace)
2652
+ return 0;
2653
+
2654
+ return session->auxtrace->process_event(session, event, sample, tool);
2655
+}
2656
+
2657
+void auxtrace__dump_auxtrace_sample(struct perf_session *session,
2658
+ struct perf_sample *sample)
2659
+{
2660
+ if (!session->auxtrace || !session->auxtrace->dump_auxtrace_sample ||
2661
+ auxtrace__dont_decode(session))
2662
+ return;
2663
+
2664
+ session->auxtrace->dump_auxtrace_sample(session, sample);
2665
+}
2666
+
2667
+int auxtrace__flush_events(struct perf_session *session, struct perf_tool *tool)
2668
+{
2669
+ if (!session->auxtrace)
2670
+ return 0;
2671
+
2672
+ return session->auxtrace->flush_events(session, tool);
2673
+}
2674
+
2675
+void auxtrace__free_events(struct perf_session *session)
2676
+{
2677
+ if (!session->auxtrace)
2678
+ return;
2679
+
2680
+ return session->auxtrace->free_events(session);
2681
+}
2682
+
2683
+void auxtrace__free(struct perf_session *session)
2684
+{
2685
+ if (!session->auxtrace)
2686
+ return;
2687
+
2688
+ return session->auxtrace->free(session);
2689
+}
2690
+
2691
+bool auxtrace__evsel_is_auxtrace(struct perf_session *session,
2692
+ struct evsel *evsel)
2693
+{
2694
+ if (!session->auxtrace || !session->auxtrace->evsel_is_auxtrace)
2695
+ return false;
2696
+
2697
+ return session->auxtrace->evsel_is_auxtrace(session, evsel);
2698
+}