History

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf tooling updates from Ingo Molnar: "Perf tooling updates and fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf annotate browser: Help for cycling thru hottest instructions with TAB/shift+TAB perf stat: Only auto-merge events that are PMU aliases perf test: Add test case for PERF_SAMPLE_PHYS_ADDR perf script: Support physical address perf mem: Support physical address perf sort: Add sort option for physical address perf tools: Support new sample type for physical address perf vendor events powerpc: Remove duplicate events perf intel-pt: Fix syntax in documentation of config option perf test powerpc: Fix 'Object code reading' test perf trace: Support syscall name globbing perf syscalltbl: Support glob matching on syscall names perf report: Calculate the average cycles of iterations

Linus Torvalds committed 9 years ago

Commit e6328a72 parents 33f82bd 770e96137 files · +368 −268Browse files

Unified · Split

37 files
  1. tools/include/uapi/linux/perf_event.h +3 −1
  2. tools/perf/Documentation/intel-pt.txt +1 −1
  3. tools/perf/Documentation/perf-mem.txt +4 −0
  4. tools/perf/Documentation/perf-record.txt +4 −1
  5. tools/perf/Documentation/perf-report.txt +1 −0
  6. tools/perf/Documentation/perf-script.txt +1 −1
  7. tools/perf/Documentation/perf-trace.txt +1 −1
  8. tools/perf/builtin-mem.c +71 −26
  9. tools/perf/builtin-record.c +2 −0
  10. tools/perf/builtin-script.c +13 −2
  11. tools/perf/builtin-stat.c +1 −1
  12. tools/perf/builtin-trace.c +35 −4
  13. tools/perf/perf.h +1 −0
  14. tools/perf/pmu-events/arch/powerpc/power9/frontend.json +1 −6
  15. tools/perf/pmu-events/arch/powerpc/power9/other.json +0 −120
  16. tools/perf/pmu-events/arch/powerpc/power9/pipeline.json +1 −6
  17. tools/perf/pmu-events/arch/powerpc/power9/pmc.json +1 −6
  18. tools/perf/tests/code-reading.c +5 −0
  19. tools/perf/tests/sample-parsing.c +5 −1
  20. tools/perf/ui/browsers/annotate.c +2 −1
  21. tools/perf/ui/browsers/hists.c +2 −6
  22. tools/perf/ui/stdio/hist.c +3 −7
  23. tools/perf/util/callchain.c +23 −26
  24. tools/perf/util/callchain.h +4 −5
  25. tools/perf/util/event.h +1 −0
  26. tools/perf/util/evsel.c +18 −1
  27. tools/perf/util/evsel.h +1 −0
  28. tools/perf/util/hist.c +4 −0
  29. tools/perf/util/hist.h +1 −0
  30. tools/perf/util/machine.c +59 −37
  31. tools/perf/util/parse-events.c +16 −8
  32. tools/perf/util/session.c +3 −0
  33. tools/perf/util/sort.c +42 −0
  34. tools/perf/util/sort.h +1 −0
  35. tools/perf/util/symbol.h +1 −0
  36. tools/perf/util/syscalltbl.c +33 −0
  37. tools/perf/util/syscalltbl.h +3 −0
tools/include/uapi/linux/perf_event.h+3−1
@@ -139,8 +139,9 @@ enum perf_event_sample_format { · 138 unmodified lines
139139 PERF_SAMPLE_IDENTIFIER = 1U << 16,
140140 PERF_SAMPLE_TRANSACTION = 1U << 17,
141141 PERF_SAMPLE_REGS_INTR = 1U << 18,
142+ PERF_SAMPLE_PHYS_ADDR = 1U << 19,
142143
143− PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */
144+ PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */
144145 };
145146
146147 /*
@@ -814,6 +815,7 @@ enum perf_event_type { · 667 unmodified lines
814815 * { u64 transaction; } && PERF_SAMPLE_TRANSACTION
815816 * { u64 abi; # enum perf_sample_regs_abi
816817 * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
818+ * { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR
817819 * };
818820 */
819821 PERF_RECORD_SAMPLE = 9,
tools/perf/Documentation/intel-pt.txt+1−1
@@ -873,7 +873,7 @@ amended to take the number of elements as a parameter. · 872 unmodified lines
873873
874874 $ cat ~/.perfconfig
875875 [intel-pt]
876− mispred-all
876+ mispred-all = on
877877
878878 $ perf record -e intel_pt//u ./sort 3000
879879 Bubble sorting array of 3000 elements
tools/perf/Documentation/perf-mem.txt+4−0
@@ -59,6 +59,10 @@ OPTIONS · 58 unmodified lines
5959 --ldload::
6060 Specify desired latency for loads event.
6161
62+-p::
63+--phys-data::
64+ Record/Report sample physical addresses
65+
6266 SEE ALSO
6367 --------
6468 linkperf:perf-record[1], linkperf:perf-report[1]
tools/perf/Documentation/perf-record.txt+4−1
@@ -249,7 +249,10 @@ OPTIONS · 248 unmodified lines
249249
250250 -d::
251251 --data::
252− Record the sample addresses.
252+ Record the sample virtual addresses.
253+
254+--phys-data::
255+ Record the sample physical addresses.
253256
254257 -T::
255258 --timestamp::
tools/perf/Documentation/perf-report.txt+1−0
@@ -137,6 +137,7 @@ OPTIONS · 136 unmodified lines
137137 - mem: type of memory access for the data at the time of the sample
138138 - snoop: type of snoop (if any) for the data at the time of the sample
139139 - dcacheline: the cacheline the data address is on at the time of the sample
140+ - phys_daddr: physical address of data being executed on at the time of sample
140141
141142 And the default sort keys are changed to local_weight, mem, sym, dso,
142143 symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
tools/perf/Documentation/perf-script.txt+1−1
@@ -117,7 +117,7 @@ OPTIONS · 116 unmodified lines
117117 Comma separated list of fields to print. Options are:
118118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
119119 srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff,
120− callindent, insn, insnlen, synth.
120+ callindent, insn, insnlen, synth, phys_addr.
121121 Field list can be prepended with the type, trace, sw or hw,
122122 to indicate to which event type the field list applies.
123123 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
tools/perf/Documentation/perf-trace.txt+1−1
@@ -37,7 +37,7 @@ OPTIONS · 36 unmodified lines
3737 --expr::
3838 --event::
3939 List of syscalls and other perf events (tracepoints, HW cache events,
40− etc) to show.
40+ etc) to show. Globbing is supported, e.g.: "epoll_*", "*msg*", etc.
4141 See 'perf list' for a complete list of events.
4242 Prefixing with ! shows all syscalls but the ones specified. You may
4343 need to escape it.
tools/perf/builtin-mem.c+71−26
@@ -23,6 +23,7 @@ struct perf_mem { · 22 unmodified lines
2323 bool hide_unresolved;
2424 bool dump_raw;
2525 bool force;
26+ bool phys_addr;
2627 int operation;
2728 const char *cpu_list;
2829 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
@@ -101,6 +102,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) · 72 unmodified lines
101102
102103 rec_argv[i++] = "-d";
103104
105+ if (mem->phys_addr)
106+ rec_argv[i++] = "--phys-data";
107+
104108 for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
105109 if (!perf_mem_events[j].record)
106110 continue;
@@ -161,30 +165,60 @@ dump_raw_samples(struct perf_tool *tool, · 54 unmodified lines
161165 if (al.map != NULL)
162166 al.map->dso->hit = 1;
163167
164− if (symbol_conf.field_sep) {
165− fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64
166− "%s0x%"PRIx64"%s%s:%s\n";
168+ if (mem->phys_addr) {
169+ if (symbol_conf.field_sep) {
170+ fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%016"PRIx64
171+ "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n";
172+ } else {
173+ fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
174+ "%s0x%016"PRIx64"%s%5"PRIu64"%s0x%06"PRIx64
175+ "%s%s:%s\n";
176+ symbol_conf.field_sep = " ";
177+ }
178+
179+ printf(fmt,
180+ sample->pid,
181+ symbol_conf.field_sep,
182+ sample->tid,
183+ symbol_conf.field_sep,
184+ sample->ip,
185+ symbol_conf.field_sep,
186+ sample->addr,
187+ symbol_conf.field_sep,
188+ sample->phys_addr,
189+ symbol_conf.field_sep,
190+ sample->weight,
191+ symbol_conf.field_sep,
192+ sample->data_src,
193+ symbol_conf.field_sep,
194+ al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
195+ al.sym ? al.sym->name : "???");
167196 } else {
168− fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
169− "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n";
170− symbol_conf.field_sep = " ";
171− }
197+ if (symbol_conf.field_sep) {
198+ fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64
199+ "%s0x%"PRIx64"%s%s:%s\n";
200+ } else {
201+ fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
202+ "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n";
203+ symbol_conf.field_sep = " ";
204+ }
172205
173− printf(fmt,
174− sample->pid,
175− symbol_conf.field_sep,
176− sample->tid,
177− symbol_conf.field_sep,
178− sample->ip,
179− symbol_conf.field_sep,
180− sample->addr,
181− symbol_conf.field_sep,
182− sample->weight,
183− symbol_conf.field_sep,
184− sample->data_src,
185− symbol_conf.field_sep,
186− al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
187− al.sym ? al.sym->name : "???");
206+ printf(fmt,
207+ sample->pid,
208+ symbol_conf.field_sep,
209+ sample->tid,
210+ symbol_conf.field_sep,
211+ sample->ip,
212+ symbol_conf.field_sep,
213+ sample->addr,
214+ symbol_conf.field_sep,
215+ sample->weight,
216+ symbol_conf.field_sep,
217+ sample->data_src,
218+ symbol_conf.field_sep,
219+ al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
220+ al.sym ? al.sym->name : "???");
221+ }
188222 out_put:
189223 addr_location__put(&al);
190224 return 0;
@@ -224,7 +258,10 @@ static int report_raw_events(struct perf_mem *mem) · 33 unmodified lines
224258 if (ret < 0)
225259 goto out_delete;
226260
227− printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
261+ if (mem->phys_addr)
262+ printf("# PID, TID, IP, ADDR, PHYS ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
263+ else
264+ printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
228265
229266 ret = perf_session__process_events(session);
230267
@@ -254,9 +291,16 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem) · 23 unmodified lines
254291 * there is no weight (cost) associated with stores, so don't print
255292 * the column
256293 */
257− if (!(mem->operation & MEM_OPERATION_LOAD))
258− rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
259− "dso_daddr,tlb,locked";
294+ if (!(mem->operation & MEM_OPERATION_LOAD)) {
295+ if (mem->phys_addr)
296+ rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
297+ "dso_daddr,tlb,locked,phys_daddr";
298+ else
299+ rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
300+ "dso_daddr,tlb,locked";
301+ } else if (mem->phys_addr)
302+ rep_argv[i++] = "--sort=local_weight,mem,sym,dso,symbol_daddr,"
303+ "dso_daddr,snoop,tlb,locked,phys_daddr";
260304
261305 for (j = 1; j < argc; j++, i++)
262306 rep_argv[i] = argv[j];
@@ -373,6 +417,7 @@ int cmd_mem(int argc, const char **argv) · 110 unmodified lines
373417 "separator for columns, no spaces will be added"
374418 " between columns '.' is reserved."),
375419 OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"),
420+ OPT_BOOLEAN('p', "phys-data", &mem.phys_addr, "Record/Report sample physical addresses"),
376421 OPT_END()
377422 };
378423 const char *const mem_subcommands[] = { "record", "report", NULL };
tools/perf/builtin-record.c+2−0
@@ -1604,6 +1604,8 @@ static struct option __record_options[] = { · 1603 unmodified lines
16041604 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
16051605 "per thread counts"),
16061606 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
1607+ OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr,
1608+ "Record the sample physical addresses"),
16071609 OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
16081610 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
16091611 &record.opts.sample_time_set,
tools/perf/builtin-script.c+13−2
@@ -87,6 +87,7 @@ enum perf_output_field { · 86 unmodified lines
8787 PERF_OUTPUT_BRSTACKINSN = 1U << 23,
8888 PERF_OUTPUT_BRSTACKOFF = 1U << 24,
8989 PERF_OUTPUT_SYNTH = 1U << 25,
90+ PERF_OUTPUT_PHYS_ADDR = 1U << 26,
9091 };
9192
9293 struct output_option {
@@ -119,6 +120,7 @@ struct output_option { · 26 unmodified lines
119120 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
120121 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
121122 {.str = "synth", .field = PERF_OUTPUT_SYNTH},
123+ {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
122124 };
123125
124126 enum {
@@ -175,7 +177,8 @@ static struct { · 50 unmodified lines
175177 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
176178 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
177179 PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR |
178− PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT,
180+ PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT |
181+ PERF_OUTPUT_PHYS_ADDR,
179182
180183 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
181184 },
@@ -382,6 +385,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, · 200 unmodified lines
382385 PERF_OUTPUT_IREGS))
383386 return -EINVAL;
384387
388+ if (PRINT_FIELD(PHYS_ADDR) &&
389+ perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR",
390+ PERF_OUTPUT_PHYS_ADDR))
391+ return -EINVAL;
392+
385393 return 0;
386394 }
387395
@@ -1446,6 +1454,9 @@ static void process_event(struct perf_script *script, · 1058 unmodified lines
14461454 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
14471455 print_sample_bpf_output(sample);
14481456 print_insn(sample, attr, thread, machine);
1457+
1458+ if (PRINT_FIELD(PHYS_ADDR))
1459+ printf("%16" PRIx64, sample->phys_addr);
14491460 printf("\n");
14501461 }
14511462
@@ -2729,7 +2740,7 @@ int cmd_script(int argc, const char **argv) · 1277 unmodified lines
27292740 "Valid types: hw,sw,trace,raw,synth. "
27302741 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
27312742 "addr,symoff,period,iregs,brstack,brstacksym,flags,"
2732− "bpf-output,callindent,insn,insnlen,brstackinsn,synth",
2743+ "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr",
27332744 parse_output_fields),
27342745 OPT_BOOLEAN('a', "all-cpus", &system_wide,
27352746 "system-wide collection from all CPUs"),
tools/perf/builtin-stat.c+1−1
@@ -1257,7 +1257,7 @@ static bool collect_data(struct perf_evsel *counter, · 1256 unmodified lines
12571257 if (counter->merged_stat)
12581258 return false;
12591259 cb(counter, data, true);
1260− if (!no_merge)
1260+ if (!no_merge && counter->auto_merge_stats)
12611261 collect_all_aliases(counter, cb, data);
12621262 return true;
12631263 }
tools/perf/builtin-trace.c+35−4
@@ -1261,6 +1261,7 @@ static int trace__read_syscall_info(struct trace *trace, int id) · 1260 unmodified lines
12611261 static int trace__validate_ev_qualifier(struct trace *trace)
12621262 {
12631263 int err = 0, i;
1264+ size_t nr_allocated;
12641265 struct str_node *pos;
12651266
12661267 trace->ev_qualifier_ids.nr = strlist__nr_entries(trace->ev_qualifier);
@@ -1274,13 +1275,18 @@ static int trace__validate_ev_qualifier(struct trace *trace) · 7 unmodified lines
12741275 goto out;
12751276 }
12761277
1278+ nr_allocated = trace->ev_qualifier_ids.nr;
12771279 i = 0;
12781280
12791281 strlist__for_each_entry(pos, trace->ev_qualifier) {
12801282 const char *sc = pos->s;
1281− int id = syscalltbl__id(trace->sctbl, sc);
1283+ int id = syscalltbl__id(trace->sctbl, sc), match_next = -1;
12821284
12831285 if (id < 0) {
1286+ id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next);
1287+ if (id >= 0)
1288+ goto matches;
1289+
12841290 if (err == 0) {
12851291 fputs("Error:\tInvalid syscall ", trace->output);
12861292 err = -EINVAL;
@@ -1290,13 +1296,37 @@ static int trace__validate_ev_qualifier(struct trace *trace) · 3 unmodified lines
12901296
12911297 fputs(sc, trace->output);
12921298 }
1293−
1299+matches:
12941300 trace->ev_qualifier_ids.entries[i++] = id;
1301+ if (match_next == -1)
1302+ continue;
1303+
1304+ while (1) {
1305+ id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next);
1306+ if (id < 0)
1307+ break;
1308+ if (nr_allocated == trace->ev_qualifier_ids.nr) {
1309+ void *entries;
1310+
1311+ nr_allocated += 8;
1312+ entries = realloc(trace->ev_qualifier_ids.entries,
1313+ nr_allocated * sizeof(trace->ev_qualifier_ids.entries[0]));
1314+ if (entries == NULL) {
1315+ err = -ENOMEM;
1316+ fputs("\nError:\t Not enough memory for parsing\n", trace->output);
1317+ goto out_free;
1318+ }
1319+ trace->ev_qualifier_ids.entries = entries;
1320+ }
1321+ trace->ev_qualifier_ids.nr++;
1322+ trace->ev_qualifier_ids.entries[i++] = id;
1323+ }
12951324 }
12961325
12971326 if (err < 0) {
12981327 fputs("\nHint:\ttry 'perf list syscalls:sys_enter_*'"
12991328 "\nHint:\tand: 'man syscalls'\n", trace->output);
1329+out_free:
13001330 zfree(&trace->ev_qualifier_ids.entries);
13011331 trace->ev_qualifier_ids.nr = 0;
13021332 }
@@ -2814,7 +2844,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str, · 1511 unmodified lines
28142844 struct trace *trace = (struct trace *)opt->value;
28152845 const char *s = str;
28162846 char *sep = NULL, *lists[2] = { NULL, NULL, };
2817− int len = strlen(str) + 1, err = -1, list;
2847+ int len = strlen(str) + 1, err = -1, list, idx;
28182848 char *strace_groups_dir = system_path(STRACE_GROUPS_DIR);
28192849 char group_name[PATH_MAX];
28202850
@@ -2831,7 +2861,8 @@ static int trace__parse_events_option(const struct option *opt, const char *str, · 10 unmodified lines
28312861 *sep = '\0';
28322862
28332863 list = 0;
2834− if (syscalltbl__id(trace->sctbl, s) >= 0) {
2864+ if (syscalltbl__id(trace->sctbl, s) >= 0 ||
2865+ syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
28352866 list = 1;
28362867 } else {
28372868 path__join(group_name, sizeof(group_name), strace_groups_dir, s);
tools/perf/perf.h+1−0
@@ -43,6 +43,7 @@ struct record_opts { · 42 unmodified lines
4343 bool no_samples;
4444 bool raw_samples;
4545 bool sample_address;
46+ bool sample_phys_addr;
4647 bool sample_weight;
4748 bool sample_time;
4849 bool sample_time_set;
tools/perf/pmu-events/arch/powerpc/power9/frontend.json+1−6
@@ -79,11 +79,6 @@ · 78 unmodified lines
7979 "EventName": "PM_LD_MISS_L1",
8080 "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load."
8181 },
82− {,
83− "EventCode": "0x400F0",
84− "EventName": "PM_LD_MISS_L1",
85− "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load."
86− },
8782 {,
8883 "EventCode": "0x2E01A",
8984 "EventName": "PM_CMPLU_STALL_LSU_FLUSH_NEXT",
@@ -374,4 +369,4 @@ · 284 unmodified lines
374369 "EventName": "PM_IPTEG_FROM_L31_ECO_MOD",
375370 "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a instruction side request"
376371 }
377−]
372+]
tools/perf/pmu-events/arch/powerpc/power9/other.json+0−120
@@ -604,11 +604,6 @@ · 603 unmodified lines
604604 "EventName": "PM_L2_RTY_LD",
605605 "BriefDescription": "RC retries on PB for any load from core (excludes DCBFs)"
606606 },
607− {,
608− "EventCode": "0x3689E",
609− "EventName": "PM_L2_RTY_LD",
610− "BriefDescription": "RC retries on PB for any load from core (excludes DCBFs)"
611− },
612607 {,
613608 "EventCode": "0xE08C",
614609 "EventName": "PM_LSU0_ERAT_HIT",
@@ -714,11 +709,6 @@ · 99 unmodified lines
714709 "EventName": "PM_L3_RD0_BUSY",
715710 "BriefDescription": "Lifetime, sample of RD machine 0 valid"
716711 },
717− {,
718− "EventCode": "0x468B4",
719− "EventName": "PM_L3_RD0_BUSY",
720− "BriefDescription": "Lifetime, sample of RD machine 0 valid"
721− },
722712 {,
723713 "EventCode": "0x46080",
724714 "EventName": "PM_L2_DISP_ALL_L2MISS",
@@ -849,21 +839,11 @@ · 124 unmodified lines
849839 "EventName": "PM_RC0_BUSY",
850840 "BriefDescription": "RC mach 0 Busy. Used by PMU to sample ave RC lifetime (mach0 used as sample point)"
851841 },
852− {,
853− "EventCode": "0x2608C",
854− "EventName": "PM_RC0_BUSY",
855− "BriefDescription": "RC mach 0 Busy. Used by PMU to sample ave RC lifetime (mach0 used as sample point)"
856− },
857842 {,
858843 "EventCode": "0x36082",
859844 "EventName": "PM_L2_LD_DISP",
860845 "BriefDescription": "All successful I-or-D side load dispatches for this thread (excludes i_l2mru_tch_reqs)."
861846 },
862− {,
863− "EventCode": "0x1609E",
864− "EventName": "PM_L2_LD_DISP",
865− "BriefDescription": "All successful D side load dispatches for this thread (L2 miss + L2 hits)"
866− },
867847 {,
868848 "EventCode": "0xF8B0",
869849 "EventName": "PM_L3_SW_PREF",
@@ -1039,11 +1019,6 @@ · 169 unmodified lines
10391019 "EventName": "PM_L3_CO_MEPF",
10401020 "BriefDescription": "L3 castouts in Mepf state for this thread"
10411021 },
1042− {,
1043− "EventCode": "0x168A0",
1044− "EventName": "PM_L3_CO_MEPF",
1045− "BriefDescription": "L3 CO of line in Mep state (includes casthrough to memory). The Mepf state indicates that a line was brought in to satisfy an L3 prefetch request"
1046− },
10471022 {,
10481023 "EventCode": "0x460A2",
10491024 "EventName": "PM_L3_LAT_CI_HIT",
@@ -1149,11 +1124,6 @@ · 99 unmodified lines
11491124 "EventName": "PM_L2_RTY_ST",
11501125 "BriefDescription": "RC retries on PB for any store from core (excludes DCBFs)"
11511126 },
1152− {,
1153− "EventCode": "0x4689E",
1154− "EventName": "PM_L2_RTY_ST",
1155− "BriefDescription": "RC retries on PB for any store from core (excludes DCBFs)"
1156− },
11571127 {,
11581128 "EventCode": "0x24040",
11591129 "EventName": "PM_INST_FROM_L2_MEPF",
@@ -1254,11 +1224,6 @@ · 94 unmodified lines
12541224 "EventName": "PM_CO0_BUSY",
12551225 "BriefDescription": "CO mach 0 Busy. Used by PMU to sample ave CO lifetime (mach0 used as sample point)"
12561226 },
1257− {,
1258− "EventCode": "0x4608C",
1259− "EventName": "PM_CO0_BUSY",
1260− "BriefDescription": "CO mach 0 Busy. Used by PMU to sample ave CO lifetime (mach0 used as sample point)"
1261− },
12621227 {,
12631228 "EventCode": "0x2C122",
12641229 "EventName": "PM_MRK_DATA_FROM_L3_DISP_CONFLICT_CYC",
@@ -1394,11 +1359,6 @@ · 129 unmodified lines
13941359 "EventName": "PM_IPTEG_FROM_LMEM",
13951360 "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a instruction side request"
13961361 },
1397− {,
1398− "EventCode": "0x40006",
1399− "EventName": "PM_ISLB_MISS",
1400− "BriefDescription": "Number of ISLB misses for this thread"
1401− },
14021362 {,
14031363 "EventCode": "0xD8A8",
14041364 "EventName": "PM_ISLB_MISS",
@@ -1514,11 +1474,6 @@ · 109 unmodified lines
15141474 "EventName": "PM_L2_INST",
15151475 "BriefDescription": "All successful I-side dispatches for this thread (excludes i_l2mru_tch reqs)."
15161476 },
1517− {,
1518− "EventCode": "0x3609E",
1519− "EventName": "PM_L2_INST",
1520− "BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)"
1521− },
15221477 {,
15231478 "EventCode": "0x3504C",
15241479 "EventName": "PM_IPTEG_FROM_DL4",
@@ -1689,11 +1644,6 @@ · 164 unmodified lines
16891644 "EventName": "PM_L2_LD_HIT",
16901645 "BriefDescription": "All successful I-or-D side load dispatches for this thread that were L2 hits (excludes i_l2mru_tch_reqs)"
16911646 },
1692− {,
1693− "EventCode": "0x2609E",
1694− "EventName": "PM_L2_LD_HIT",
1695− "BriefDescription": "All successful D side load dispatches for this thread that were L2 hits for this thread"
1696− },
16971647 {,
16981648 "EventCode": "0x168AC",
16991649 "EventName": "PM_L3_CI_USAGE",
@@ -1794,21 +1744,11 @@ · 94 unmodified lines
17941744 "EventName": "PM_L3_WI0_BUSY",
17951745 "BriefDescription": "Rotating sample of 8 WI valid"
17961746 },
1797− {,
1798− "EventCode": "0x260B6",
1799− "EventName": "PM_L3_WI0_BUSY",
1800− "BriefDescription": "Rotating sample of 8 WI valid (duplicate)"
1801− },
18021747 {,
18031748 "EventCode": "0x368AC",
18041749 "EventName": "PM_L3_CO0_BUSY",
18051750 "BriefDescription": "Lifetime, sample of CO machine 0 valid"
18061751 },
1807− {,
1808− "EventCode": "0x468AC",
1809− "EventName": "PM_L3_CO0_BUSY",
1810− "BriefDescription": "Lifetime, sample of CO machine 0 valid"
1811− },
18121752 {,
18131753 "EventCode": "0x2E040",
18141754 "EventName": "PM_DPTEG_FROM_L2_MEPF",
@@ -1839,11 +1779,6 @@ · 24 unmodified lines
18391779 "EventName": "PM_L3_P0_PF_RTY",
18401780 "BriefDescription": "L3 PF received retry port 0, every retry counted"
18411781 },
1842− {,
1843− "EventCode": "0x260AE",
1844− "EventName": "PM_L3_P0_PF_RTY",
1845− "BriefDescription": "L3 PF received retry port 0, every retry counted"
1846− },
18471782 {,
18481783 "EventCode": "0x268B2",
18491784 "EventName": "PM_L3_LOC_GUESS_WRONG",
@@ -1894,11 +1829,6 @@ · 44 unmodified lines
18941829 "EventName": "PM_L3_SN0_BUSY",
18951830 "BriefDescription": "Lifetime, sample of snooper machine 0 valid"
18961831 },
1897− {,
1898− "EventCode": "0x460AC",
1899− "EventName": "PM_L3_SN0_BUSY",
1900− "BriefDescription": "Lifetime, sample of snooper machine 0 valid"
1901− },
19021832 {,
19031833 "EventCode": "0x3005C",
19041834 "EventName": "PM_BFU_BUSY",
@@ -1934,11 +1864,6 @@ · 29 unmodified lines
19341864 "EventName": "PM_L3_PF0_BUSY",
19351865 "BriefDescription": "Lifetime, sample of PF machine 0 valid"
19361866 },
1937− {,
1938− "EventCode": "0x460B4",
1939− "EventName": "PM_L3_PF0_BUSY",
1940− "BriefDescription": "Lifetime, sample of PF machine 0 valid"
1941− },
19421867 {,
19431868 "EventCode": "0xC0B0",
19441869 "EventName": "PM_LSU_FLUSH_UE",
@@ -2084,11 +2009,6 @@ · 139 unmodified lines
20842009 "EventName": "PM_L3_P1_CO_RTY",
20852010 "BriefDescription": "L3 CO received retry port 1 (memory only), every retry counted"
20862011 },
2087− {,
2088− "EventCode": "0x468AE",
2089− "EventName": "PM_L3_P1_CO_RTY",
2090− "BriefDescription": "L3 CO received retry port 3 (memory only), every retry counted"
2091− },
20922012 {,
20932013 "EventCode": "0xC0AC",
20942014 "EventName": "PM_LSU_FLUSH_EMSH",
@@ -2194,11 +2114,6 @@ · 99 unmodified lines
21942114 "EventName": "PM_L2_SN_M_WR_DONE",
21952115 "BriefDescription": "SNP dispatched for a write and was M (true M); for DMA cacheinj this will pulse if rty/push is required (won't pulse if cacheinj is accepted)"
21962116 },
2197− {,
2198− "EventCode": "0x46886",
2199− "EventName": "PM_L2_SN_M_WR_DONE",
2200− "BriefDescription": "SNP dispatched for a write and was M (true M); for DMA cacheinj this will pulse if rty/push is required (won't pulse if cacheinj is accepted)"
2201− },
22022117 {,
22032118 "EventCode": "0x489C",
22042119 "EventName": "PM_BR_CORECT_PRED_TAKEN_CMPL",
@@ -2289,21 +2204,11 @@ · 84 unmodified lines
22892204 "EventName": "PM_SN0_BUSY",
22902205 "BriefDescription": "SN mach 0 Busy. Used by PMU to sample ave SN lifetime (mach0 used as sample point)"
22912206 },
2292− {,
2293− "EventCode": "0x26090",
2294− "EventName": "PM_SN0_BUSY",
2295− "BriefDescription": "SN mach 0 Busy. Used by PMU to sample ave SN lifetime (mach0 used as sample point)"
2296− },
22972207 {,
22982208 "EventCode": "0x360AE",
22992209 "EventName": "PM_L3_P0_CO_RTY",
23002210 "BriefDescription": "L3 CO received retry port 0 (memory only), every retry counted"
23012211 },
2302− {,
2303− "EventCode": "0x460AE",
2304− "EventName": "PM_L3_P0_CO_RTY",
2305− "BriefDescription": "L3 CO received retry port 0 (memory only), every retry counted"
2306− },
23072212 {,
23082213 "EventCode": "0x168A8",
23092214 "EventName": "PM_L3_WI_USAGE",
@@ -2339,26 +2244,11 @@ · 29 unmodified lines
23392244 "EventName": "PM_L3_P1_PF_RTY",
23402245 "BriefDescription": "L3 PF received retry port 1, every retry counted"
23412246 },
2342− {,
2343− "EventCode": "0x268AE",
2344− "EventName": "PM_L3_P1_PF_RTY",
2345− "BriefDescription": "L3 PF received retry port 3, every retry counted"
2346− },
23472247 {,
23482248 "EventCode": "0x46082",
23492249 "EventName": "PM_L2_ST_DISP",
23502250 "BriefDescription": "All successful D-side store dispatches for this thread "
23512251 },
2352− {,
2353− "EventCode": "0x1689E",
2354− "EventName": "PM_L2_ST_DISP",
2355− "BriefDescription": "All successful D-side store dispatches for this thread (L2 miss + L2 hits)"
2356− },
2357− {,
2358− "EventCode": "0x36880",
2359− "EventName": "PM_L2_INST_MISS",
2360− "BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)"
2361− },
23622252 {,
23632253 "EventCode": "0x4609E",
23642254 "EventName": "PM_L2_INST_MISS",
@@ -2429,11 +2319,6 @@ · 64 unmodified lines
24292319 "EventName": "PM_INST_DISP",
24302320 "BriefDescription": "# PPC Dispatched"
24312321 },
2432− {,
2433− "EventCode": "0x300F2",
2434− "EventName": "PM_INST_DISP",
2435− "BriefDescription": "# PPC Dispatched"
2436− },
24372322 {,
24382323 "EventCode": "0x4E05E",
24392324 "EventName": "PM_TM_OUTER_TBEGIN_DISP",
@@ -2459,11 +2344,6 @@ · 19 unmodified lines
24592344 "EventName": "PM_L2_ST_HIT",
24602345 "BriefDescription": "All successful D-side store dispatches for this thread that were L2 hits"
24612346 },
2462− {,
2463− "EventCode": "0x2689E",
2464− "EventName": "PM_L2_ST_HIT",
2465− "BriefDescription": "All successful D-side store dispatches that were L2 hits for this thread"
2466− },
24672347 {,
24682348 "EventCode": "0x360A8",
24692349 "EventName": "PM_L3_CO",
tools/perf/pmu-events/arch/powerpc/power9/pipeline.json+1−6
@@ -419,11 +419,6 @@ · 418 unmodified lines
419419 "EventName": "PM_INST_GRP_PUMP_MPRED_RTY",
420420 "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for an instruction fetch"
421421 },
422− {,
423− "EventCode": "0x10016",
424− "EventName": "PM_DSLB_MISS",
425− "BriefDescription": "Data SLB Miss - Total of all segment sizes"
426− },
427422 {,
428423 "EventCode": "0xD0A8",
429424 "EventName": "PM_DSLB_MISS",
@@ -554,4 +549,4 @@ · 124 unmodified lines
554549 "EventName": "PM_MRK_DATA_FROM_L21_SHR_CYC",
555550 "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's L2 on the same chip due to a marked load"
556551 }
557−]
552+]
tools/perf/pmu-events/arch/powerpc/power9/pmc.json+1−6
@@ -4,11 +4,6 @@ · 3 unmodified lines
44 "EventName": "PM_BR_2PATH",
55 "BriefDescription": "Branches that are not strongly biased"
66 },
7− {,
8− "EventCode": "0x40036",
9− "EventName": "PM_BR_2PATH",
10− "BriefDescription": "Branches that are not strongly biased"
11− },
127 {,
138 "EventCode": "0x40056",
149 "EventName": "PM_MEM_LOC_THRESH_LSU_HIGH",
@@ -124,4 +119,4 @@ · 109 unmodified lines
124119 "EventName": "PM_1FLOP_CMPL",
125120 "BriefDescription": "one flop (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg) operation completed"
126121 }
127−]
122+]
tools/perf/tests/code-reading.c+5−0
@@ -237,6 +237,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, · 236 unmodified lines
237237
238238 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al);
239239 if (!al.map || !al.map->dso) {
240+ if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
241+ pr_debug("Hypervisor address can not be resolved - skipping\n");
242+ return 0;
243+ }
244+
240245 pr_debug("thread__find_addr_map failed\n");
241246 return -1;
242247 }
tools/perf/tests/sample-parsing.c+5−1
@@ -141,6 +141,9 @@ static bool samples_same(const struct perf_sample *s1, · 140 unmodified lines
141141 }
142142 }
143143
144+ if (type & PERF_SAMPLE_PHYS_ADDR)
145+ COMP(phys_addr);
146+
144147 return true;
145148 }
146149
@@ -206,6 +209,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) · 59 unmodified lines
206209 .mask = sample_regs,
207210 .regs = regs,
208211 },
212+ .phys_addr = 113,
209213 };
210214 struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
211215 struct perf_sample sample_out;
@@ -305,7 +309,7 @@ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_u · 93 unmodified lines
305309 * were added. Please actually update the test rather than just change
306310 * the condition below.
307311 */
308− if (PERF_SAMPLE_MAX > PERF_SAMPLE_REGS_INTR << 1) {
312+ if (PERF_SAMPLE_MAX > PERF_SAMPLE_PHYS_ADDR << 1) {
309313 pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
310314 return -1;
311315 }
tools/perf/ui/browsers/annotate.c+2−1
@@ -829,7 +829,8 @@ static int annotate_browser__run(struct annotate_browser *browser, · 828 unmodified lines
829829 "q/ESC/CTRL+C Exit\n\n"
830830 "ENTER Go to target\n"
831831 "ESC Exit\n"
832− "H Cycle thru hottest instructions\n"
832+ "H Go to hottest instruction\n"
833+ "TAB/shift+TAB Cycle thru hottest instructions\n"
833834 "j Toggle showing jump to target arrows\n"
834835 "J Toggle showing number of jump sources on targets\n"
835836 "n Search next string\n"
tools/perf/ui/browsers/hists.c+2−6
@@ -931,12 +931,8 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, · 930 unmodified lines
931931 browser->show_dso);
932932
933933 if (symbol_conf.show_branchflag_count) {
934− if (need_percent)
935− callchain_list_counts__printf_value(node, chain, NULL,
936− buf, sizeof(buf));
937− else
938− callchain_list_counts__printf_value(NULL, chain, NULL,
939− buf, sizeof(buf));
934+ callchain_list_counts__printf_value(chain, NULL,
935+ buf, sizeof(buf));
940936
941937 if (asprintf(&alloc_str2, "%s%s", str, buf) < 0)
942938 str = "Not enough memory!";
tools/perf/ui/stdio/hist.c+3−7
@@ -124,12 +124,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node, · 123 unmodified lines
124124 str = callchain_list__sym_name(chain, bf, sizeof(bf), false);
125125
126126 if (symbol_conf.show_branchflag_count) {
127− if (!period)
128− callchain_list_counts__printf_value(node, chain, NULL,
129− buf, sizeof(buf));
130− else
131− callchain_list_counts__printf_value(NULL, chain, NULL,
132− buf, sizeof(buf));
127+ callchain_list_counts__printf_value(chain, NULL,
128+ buf, sizeof(buf));
133129
134130 if (asprintf(&alloc_str, "%s%s", str, buf) < 0)
135131 str = "Not enough memory!";
@@ -313,7 +309,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, · 177 unmodified lines
313309
314310 if (symbol_conf.show_branchflag_count)
315311 ret += callchain_list_counts__printf_value(
316− NULL, chain, fp, NULL, 0);
312+ chain, fp, NULL, 0);
317313 ret += fprintf(fp, "\n");
318314
319315 if (++entries_printed == callchain_param.print_limit)
tools/perf/util/callchain.c+23−26
@@ -588,7 +588,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor) · 587 unmodified lines
588588 call->cycles_count =
589589 cursor_node->branch_flags.cycles;
590590 call->iter_count = cursor_node->nr_loop_iter;
591− call->samples_count = cursor_node->samples;
591+ call->iter_cycles = cursor_node->iter_cycles;
592592 }
593593 }
594594
@@ -722,7 +722,7 @@ static enum match_result match_chain(struct callchain_cursor_node *node, · 127 unmodified lines
722722 cnode->cycles_count +=
723723 node->branch_flags.cycles;
724724 cnode->iter_count += node->nr_loop_iter;
725− cnode->samples_count += node->samples;
725+ cnode->iter_cycles += node->iter_cycles;
726726 }
727727 }
728728
@@ -998,7 +998,7 @@ int callchain_merge(struct callchain_cursor *cursor, · 269 unmodified lines
998998 int callchain_cursor_append(struct callchain_cursor *cursor,
999999 u64 ip, struct map *map, struct symbol *sym,
10001000 bool branch, struct branch_flags *flags,
1001− int nr_loop_iter, int samples, u64 branch_from)
1001+ int nr_loop_iter, u64 iter_cycles, u64 branch_from)
10021002 {
10031003 struct callchain_cursor_node *node = *cursor->last;
10041004
@@ -1016,7 +1016,7 @@ int callchain_cursor_append(struct callchain_cursor *cursor, · 11 unmodified lines
10161016 node->sym = sym;
10171017 node->branch = branch;
10181018 node->nr_loop_iter = nr_loop_iter;
1019− node->samples = samples;
1019+ node->iter_cycles = iter_cycles;
10201020
10211021 if (flags)
10221022 memcpy(&node->branch_flags, flags,
@@ -1306,7 +1306,7 @@ static int branch_to_str(char *bf, int bfsize, · 283 unmodified lines
13061306 static int branch_from_str(char *bf, int bfsize,
13071307 u64 branch_count,
13081308 u64 cycles_count, u64 iter_count,
1309− u64 samples_count)
1309+ u64 iter_cycles)
13101310 {
13111311 int printed = 0, i = 0;
13121312 u64 cycles;
@@ -1318,9 +1318,13 @@ static int branch_from_str(char *bf, int bfsize, · 5 unmodified lines
13181318 bf + printed, bfsize - printed);
13191319 }
13201320
1321− if (iter_count && samples_count) {
1322− printed += count_pri64_printf(i++, "iterations",
1323− iter_count / samples_count,
1321+ if (iter_count) {
1322+ printed += count_pri64_printf(i++, "iter",
1323+ iter_count,
1324+ bf + printed, bfsize - printed);
1325+
1326+ printed += count_pri64_printf(i++, "avg_cycles",
1327+ iter_cycles / iter_count,
13241328 bf + printed, bfsize - printed);
13251329 }
13261330
@@ -1333,7 +1337,7 @@ static int branch_from_str(char *bf, int bfsize, · 6 unmodified lines
13331337 static int counts_str_build(char *bf, int bfsize,
13341338 u64 branch_count, u64 predicted_count,
13351339 u64 abort_count, u64 cycles_count,
1336− u64 iter_count, u64 samples_count,
1340+ u64 iter_count, u64 iter_cycles,
13371341 struct branch_type_stat *brtype_stat)
13381342 {
13391343 int printed;
@@ -1346,7 +1350,7 @@ static int counts_str_build(char *bf, int bfsize, · 6 unmodified lines
13461350 predicted_count, abort_count, brtype_stat);
13471351 } else {
13481352 printed = branch_from_str(bf, bfsize, branch_count,
1349− cycles_count, iter_count, samples_count);
1353+ cycles_count, iter_count, iter_cycles);
13501354 }
13511355
13521356 if (!printed)
@@ -1358,14 +1362,14 @@ static int counts_str_build(char *bf, int bfsize, · 5 unmodified lines
13581362 static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
13591363 u64 branch_count, u64 predicted_count,
13601364 u64 abort_count, u64 cycles_count,
1361− u64 iter_count, u64 samples_count,
1365+ u64 iter_count, u64 iter_cycles,
13621366 struct branch_type_stat *brtype_stat)
13631367 {
13641368 char str[256];
13651369
13661370 counts_str_build(str, sizeof(str), branch_count,
13671371 predicted_count, abort_count, cycles_count,
1368− iter_count, samples_count, brtype_stat);
1372+ iter_count, iter_cycles, brtype_stat);
13691373
13701374 if (fp)
13711375 return fprintf(fp, "%s", str);
@@ -1373,31 +1377,23 @@ static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, · 1 unmodified line
13731377 return scnprintf(bf, bfsize, "%s", str);
13741378 }
13751379
1376−int callchain_list_counts__printf_value(struct callchain_node *node,
1377− struct callchain_list *clist,
1380+int callchain_list_counts__printf_value(struct callchain_list *clist,
13781381 FILE *fp, char *bf, int bfsize)
13791382 {
13801383 u64 branch_count, predicted_count;
13811384 u64 abort_count, cycles_count;
1382− u64 iter_count = 0, samples_count = 0;
1385+ u64 iter_count, iter_cycles;
13831386
13841387 branch_count = clist->branch_count;
13851388 predicted_count = clist->predicted_count;
13861389 abort_count = clist->abort_count;
13871390 cycles_count = clist->cycles_count;
1388−
1389− if (node) {
1390− struct callchain_list *call;
1391−
1392− list_for_each_entry(call, &node->val, list) {
1393− iter_count += call->iter_count;
1394− samples_count += call->samples_count;
1395− }
1396− }
1391+ iter_count = clist->iter_count;
1392+ iter_cycles = clist->iter_cycles;
13971393
13981394 return callchain_counts_printf(fp, bf, bfsize, branch_count,
13991395 predicted_count, abort_count,
1400− cycles_count, iter_count, samples_count,
1396+ cycles_count, iter_count, iter_cycles,
14011397 &clist->brtype_stat);
14021398 }
14031399
@@ -1523,7 +1519,8 @@ int callchain_cursor__copy(struct callchain_cursor *dst, · 119 unmodified lines
15231519
15241520 rc = callchain_cursor_append(dst, node->ip, node->map, node->sym,
15251521 node->branch, &node->branch_flags,
1526− node->nr_loop_iter, node->samples,
1522+ node->nr_loop_iter,
1523+ node->iter_cycles,
15271524 node->branch_from);
15281525 if (rc)
15291526 break;
tools/perf/util/callchain.h+4−5
@@ -119,7 +119,7 @@ struct callchain_list { · 118 unmodified lines
119119 u64 abort_count;
120120 u64 cycles_count;
121121 u64 iter_count;
122− u64 samples_count;
122+ u64 iter_cycles;
123123 struct branch_type_stat brtype_stat;
124124 char *srcline;
125125 struct list_head list;
@@ -139,7 +139,7 @@ struct callchain_cursor_node { · 13 unmodified lines
139139 struct branch_flags branch_flags;
140140 u64 branch_from;
141141 int nr_loop_iter;
142− int samples;
142+ u64 iter_cycles;
143143 struct callchain_cursor_node *next;
144144 };
145145
@@ -201,7 +201,7 @@ static inline void callchain_cursor_reset(struct callchain_cursor *cursor) · 55 unmodified lines
201201 int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
202202 struct map *map, struct symbol *sym,
203203 bool branch, struct branch_flags *flags,
204− int nr_loop_iter, int samples, u64 branch_from);
204+ int nr_loop_iter, u64 iter_cycles, u64 branch_from);
205205
206206 /* Close a cursor writing session. Initialize for the reader */
207207 static inline void callchain_cursor_commit(struct callchain_cursor *cursor)
@@ -282,8 +282,7 @@ char *callchain_node__scnprintf_value(struct callchain_node *node, · 74 unmodified lines
282282 int callchain_node__fprintf_value(struct callchain_node *node,
283283 FILE *fp, u64 total);
284284
285−int callchain_list_counts__printf_value(struct callchain_node *node,
286− struct callchain_list *clist,
285+int callchain_list_counts__printf_value(struct callchain_list *clist,
287286 FILE *fp, char *bf, int bfsize);
288287
289288 void free_callchain(struct callchain_root *root);
tools/perf/util/event.h+1−0
@@ -200,6 +200,7 @@ struct perf_sample { · 199 unmodified lines
200200 u32 cpu;
201201 u32 raw_size;
202202 u64 data_src;
203+ u64 phys_addr;
203204 u32 flags;
204205 u16 insn_len;
205206 u8 cpumode;
tools/perf/util/evsel.c+18−1
@@ -955,6 +955,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, · 954 unmodified lines
955955 if (opts->sample_address)
956956 perf_evsel__set_sample_bit(evsel, DATA_SRC);
957957
958+ if (opts->sample_phys_addr)
959+ perf_evsel__set_sample_bit(evsel, PHYS_ADDR);
960+
958961 if (opts->no_buffering) {
959962 attr->watermark = 0;
960963 attr->wakeup_events = 1;
@@ -1464,7 +1467,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value) · 503 unmodified lines
14641467 bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
14651468 bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
14661469 bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC),
1467− bit_name(WEIGHT),
1470+ bit_name(WEIGHT), bit_name(PHYS_ADDR),
14681471 { .name = NULL, }
14691472 };
14701473 #undef bit_name
@@ -2206,6 +2209,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, · 735 unmodified lines
22062209 }
22072210 }
22082211
2212+ data->phys_addr = 0;
2213+ if (type & PERF_SAMPLE_PHYS_ADDR) {
2214+ data->phys_addr = *array;
2215+ array++;
2216+ }
2217+
22092218 return 0;
22102219 }
22112220
@@ -2311,6 +2320,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, · 99 unmodified lines
23112320 }
23122321 }
23132322
2323+ if (type & PERF_SAMPLE_PHYS_ADDR)
2324+ result += sizeof(u64);
2325+
23142326 return result;
23152327 }
23162328
@@ -2500,6 +2512,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, · 183 unmodified lines
25002512 }
25012513 }
25022514
2515+ if (type & PERF_SAMPLE_PHYS_ADDR) {
2516+ *array = sample->phys_addr;
2517+ array++;
2518+ }
2519+
25032520 return 0;
25042521 }
25052522
tools/perf/util/evsel.h+1−0
@@ -131,6 +131,7 @@ struct perf_evsel { · 130 unmodified lines
131131 bool cmdline_group_boundary;
132132 struct list_head config_terms;
133133 int bpf_fd;
134+ bool auto_merge_stats;
134135 bool merged_stat;
135136 const char * metric_expr;
136137 const char * metric_name;
tools/perf/util/hist.c+4−0
@@ -167,6 +167,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) · 166 unmodified lines
167167 symlen = unresolved_col_width + 4 + 2;
168168 hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
169169 }
170+
171+ hists__new_col_len(hists, HISTC_MEM_PHYS_DADDR,
172+ unresolved_col_width + 4 + 2);
173+
170174 } else {
171175 symlen = unresolved_col_width + 4 + 2;
172176 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
tools/perf/util/hist.h+1−0
@@ -47,6 +47,7 @@ enum hist_column { · 46 unmodified lines
4747 HISTC_GLOBAL_WEIGHT,
4848 HISTC_MEM_DADDR_SYMBOL,
4949 HISTC_MEM_DADDR_DSO,
50+ HISTC_MEM_PHYS_DADDR,
5051 HISTC_MEM_LOCKED,
5152 HISTC_MEM_TLB,
5253 HISTC_MEM_LVL,
tools/perf/util/machine.c+59−37
@@ -1635,10 +1635,12 @@ static void ip__resolve_ams(struct thread *thread, · 1634 unmodified lines
16351635 ams->al_addr = al.addr;
16361636 ams->sym = al.sym;
16371637 ams->map = al.map;
1638+ ams->phys_addr = 0;
16381639 }
16391640
16401641 static void ip__resolve_data(struct thread *thread,
1641− u8 m, struct addr_map_symbol *ams, u64 addr)
1642+ u8 m, struct addr_map_symbol *ams,
1643+ u64 addr, u64 phys_addr)
16421644 {
16431645 struct addr_location al;
16441646
@@ -1658,6 +1660,7 @@ static void ip__resolve_data(struct thread *thread, · 13 unmodified lines
16581660 ams->al_addr = al.addr;
16591661 ams->sym = al.sym;
16601662 ams->map = al.map;
1663+ ams->phys_addr = phys_addr;
16611664 }
16621665
16631666 struct mem_info *sample__resolve_mem(struct perf_sample *sample,
@@ -1669,12 +1672,18 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, · 5 unmodified lines
16691672 return NULL;
16701673
16711674 ip__resolve_ams(al->thread, &mi->iaddr, sample->ip);
1672− ip__resolve_data(al->thread, al->cpumode, &mi->daddr, sample->addr);
1675+ ip__resolve_data(al->thread, al->cpumode, &mi->daddr,
1676+ sample->addr, sample->phys_addr);
16731677 mi->data_src.val = sample->data_src;
16741678
16751679 return mi;
16761680 }
16771681
1682+struct iterations {
1683+ int nr_loop_iter;
1684+ u64 cycles;
1685+};
1686+
16781687 static int add_callchain_ip(struct thread *thread,
16791688 struct callchain_cursor *cursor,
16801689 struct symbol **parent,
@@ -1683,11 +1692,12 @@ static int add_callchain_ip(struct thread *thread, · 2 unmodified lines
16831692 u64 ip,
16841693 bool branch,
16851694 struct branch_flags *flags,
1686− int nr_loop_iter,
1687− int samples,
1695+ struct iterations *iter,
16881696 u64 branch_from)
16891697 {
16901698 struct addr_location al;
1699+ int nr_loop_iter = 0;
1700+ u64 iter_cycles = 0;
16911701
16921702 al.filtered = 0;
16931703 al.sym = NULL;
@@ -1737,9 +1747,15 @@ static int add_callchain_ip(struct thread *thread, · 43 unmodified lines
17371747
17381748 if (symbol_conf.hide_unresolved && al.sym == NULL)
17391749 return 0;
1750+
1751+ if (iter) {
1752+ nr_loop_iter = iter->nr_loop_iter;
1753+ iter_cycles = iter->cycles;
1754+ }
1755+
17401756 return callchain_cursor_append(cursor, al.addr, al.map, al.sym,
1741− branch, flags, nr_loop_iter, samples,
1742− branch_from);
1757+ branch, flags, nr_loop_iter,
1758+ iter_cycles, branch_from);
17431759 }
17441760
17451761 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1760,6 +1776,18 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, · 14 unmodified lines
17601776 return bi;
17611777 }
17621778
1779+static void save_iterations(struct iterations *iter,
1780+ struct branch_entry *be, int nr)
1781+{
1782+ int i;
1783+
1784+ iter->nr_loop_iter = nr;
1785+ iter->cycles = 0;
1786+
1787+ for (i = 0; i < nr; i++)
1788+ iter->cycles += be[i].flags.cycles;
1789+}
1790+
17631791 #define CHASHSZ 127
17641792 #define CHASHBITS 7
17651793 #define NO_ENTRY 0xff
@@ -1767,7 +1795,8 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, · 1 unmodified line
17671795 #define PERF_MAX_BRANCH_DEPTH 127
17681796
17691797 /* Remove loops. */
1770−static int remove_loops(struct branch_entry *l, int nr)
1798+static int remove_loops(struct branch_entry *l, int nr,
1799+ struct iterations *iter)
17711800 {
17721801 int i, j, off;
17731802 unsigned char chash[CHASHSZ];
@@ -1792,8 +1821,18 @@ static int remove_loops(struct branch_entry *l, int nr) · 18 unmodified lines
17921821 break;
17931822 }
17941823 if (is_loop) {
1795− memmove(l + i, l + i + off,
1796− (nr - (i + off)) * sizeof(*l));
1824+ j = nr - (i + off);
1825+ if (j > 0) {
1826+ save_iterations(iter + i + off,
1827+ l + i, off);
1828+
1829+ memmove(iter + i, iter + i + off,
1830+ j * sizeof(*iter));
1831+
1832+ memmove(l + i, l + i + off,
1833+ j * sizeof(*l));
1834+ }
1835+
17971836 nr -= off;
17981837 }
17991838 }
@@ -1883,7 +1922,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, · 83 unmodified lines
18831922
18841923 err = add_callchain_ip(thread, cursor, parent,
18851924 root_al, &cpumode, ip,
1886− branch, flags, 0, 0,
1925+ branch, flags, NULL,
18871926 branch_from);
18881927 if (err)
18891928 return (err < 0) ? err : 0;
@@ -1909,7 +1948,6 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 19 unmodified lines
19091948 int i, j, err, nr_entries;
19101949 int skip_idx = -1;
19111950 int first_call = 0;
1912− int nr_loop_iter;
19131951
19141952 if (chain)
19151953 chain_nr = chain->nr;
@@ -1942,6 +1980,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 26 unmodified lines
19421980 if (branch && callchain_param.branch_callstack) {
19431981 int nr = min(max_stack, (int)branch->nr);
19441982 struct branch_entry be[nr];
1983+ struct iterations iter[nr];
19451984
19461985 if (branch->nr > PERF_MAX_BRANCH_DEPTH) {
19471986 pr_warning("corrupted branch chain. skipping...\n");
@@ -1972,38 +2011,21 @@ static int thread__resolve_callchain_sample(struct thread *thread, · 24 unmodified lines
19722011 be[i] = branch->entries[branch->nr - i - 1];
19732012 }
19742013
1975− nr_loop_iter = nr;
1976− nr = remove_loops(be, nr);
1977−
1978− /*
1979− * Get the number of iterations.
1980− * It's only approximation, but good enough in practice.
1981− */
1982− if (nr_loop_iter > nr)
1983− nr_loop_iter = nr_loop_iter - nr + 1;
1984− else
1985− nr_loop_iter = 0;
2014+ memset(iter, 0, sizeof(struct iterations) * nr);
2015+ nr = remove_loops(be, nr, iter);
19862016
19872017 for (i = 0; i < nr; i++) {
1988− if (i == nr - 1)
1989− err = add_callchain_ip(thread, cursor, parent,
1990− root_al,
1991− NULL, be[i].to,
1992− true, &be[i].flags,
1993− nr_loop_iter, 1,
1994− be[i].from);
1995− else
1996− err = add_callchain_ip(thread, cursor, parent,
1997− root_al,
1998− NULL, be[i].to,
1999− true, &be[i].flags,
2000− 0, 0, be[i].from);
2018+ err = add_callchain_ip(thread, cursor, parent,
2019+ root_al,
2020+ NULL, be[i].to,
2021+ true, &be[i].flags,
2022+ NULL, be[i].from);
20012023
20022024 if (!err)
20032025 err = add_callchain_ip(thread, cursor, parent, root_al,
20042026 NULL, be[i].from,
20052027 true, &be[i].flags,
2006− 0, 0, 0);
2028+ &iter[i], 0);
20072029 if (err == -EINVAL)
20082030 break;
20092031 if (err)
@@ -2037,7 +2059,7 @@ check_calls: · 27 unmodified lines
20372059
20382060 err = add_callchain_ip(thread, cursor, parent,
20392061 root_al, &cpumode, ip,
2040− false, NULL, 0, 0, 0);
2062+ false, NULL, NULL, 0);
20412063
20422064 if (err)
20432065 return (err < 0) ? err : 0;
tools/perf/util/parse-events.c+16−8
@@ -310,7 +310,7 @@ static struct perf_evsel * · 309 unmodified lines
310310 __add_event(struct list_head *list, int *idx,
311311 struct perf_event_attr *attr,
312312 char *name, struct cpu_map *cpus,
313− struct list_head *config_terms)
313+ struct list_head *config_terms, bool auto_merge_stats)
314314 {
315315 struct perf_evsel *evsel;
316316
@@ -324,6 +324,7 @@ __add_event(struct list_head *list, int *idx, · 7 unmodified lines
324324 evsel->cpus = cpu_map__get(cpus);
325325 evsel->own_cpus = cpu_map__get(cpus);
326326 evsel->system_wide = !!cpus;
327+ evsel->auto_merge_stats = auto_merge_stats;
327328
328329 if (name)
329330 evsel->name = strdup(name);
@@ -339,7 +340,7 @@ static int add_event(struct list_head *list, int *idx, · 9 unmodified lines
339340 struct perf_event_attr *attr, char *name,
340341 struct list_head *config_terms)
341342 {
342− return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM;
343+ return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM;
343344 }
344345
345346 static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -1209,9 +1210,9 @@ int parse_events_add_numeric(struct parse_events_state *parse_state, · 863 unmodified lines
12091210 get_config_name(head_config), &config_terms);
12101211 }
12111212
1212−int parse_events_add_pmu(struct parse_events_state *parse_state,
1213+static int __parse_events_add_pmu(struct parse_events_state *parse_state,
12131214 struct list_head *list, char *name,
1214− struct list_head *head_config)
1215+ struct list_head *head_config, bool auto_merge_stats)
12151216 {
12161217 struct perf_event_attr attr;
12171218 struct perf_pmu_info info;
@@ -1232,7 +1233,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, · 14 unmodified lines
12321233
12331234 if (!head_config) {
12341235 attr.type = pmu->type;
1235− evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL);
1236+ evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL, auto_merge_stats);
12361237 return evsel ? 0 : -ENOMEM;
12371238 }
12381239
@@ -1254,7 +1255,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, · 15 unmodified lines
12541255
12551256 evsel = __add_event(list, &parse_state->idx, &attr,
12561257 get_config_name(head_config), pmu->cpus,
1257− &config_terms);
1258+ &config_terms, auto_merge_stats);
12581259 if (evsel) {
12591260 evsel->unit = info.unit;
12601261 evsel->scale = info.scale;
@@ -1267,6 +1268,13 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, · 6 unmodified lines
12671268 return evsel ? 0 : -ENOMEM;
12681269 }
12691270
1271+int parse_events_add_pmu(struct parse_events_state *parse_state,
1272+ struct list_head *list, char *name,
1273+ struct list_head *head_config)
1274+{
1275+ return __parse_events_add_pmu(parse_state, list, name, head_config, false);
1276+}
1277+
12701278 int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
12711279 char *str, struct list_head **listp)
12721280 {
@@ -1296,8 +1304,8 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state, · 23 unmodified lines
12961304 return -1;
12971305 list_add_tail(&term->list, head);
12981306
1299− if (!parse_events_add_pmu(parse_state, list,
1300− pmu->name, head)) {
1307+ if (!__parse_events_add_pmu(parse_state, list,
1308+ pmu->name, head, true)) {
13011309 pr_debug("%s -> %s/%s/\n", str,
13021310 pmu->name, alias->str);
13031311 ok++;
tools/perf/util/session.c+3−0
@@ -1120,6 +1120,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, · 1119 unmodified lines
11201120 if (sample_type & PERF_SAMPLE_DATA_SRC)
11211121 printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
11221122
1123+ if (sample_type & PERF_SAMPLE_PHYS_ADDR)
1124+ printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr);
1125+
11231126 if (sample_type & PERF_SAMPLE_TRANSACTION)
11241127 printf("... transaction: %" PRIx64 "\n", sample->transaction);
11251128
tools/perf/util/sort.c+42−0
@@ -1315,6 +1315,47 @@ struct sort_entry sort_mem_dcacheline = { · 1314 unmodified lines
13151315 .se_width_idx = HISTC_MEM_DCACHELINE,
13161316 };
13171317
1318+static int64_t
1319+sort__phys_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
1320+{
1321+ uint64_t l = 0, r = 0;
1322+
1323+ if (left->mem_info)
1324+ l = left->mem_info->daddr.phys_addr;
1325+ if (right->mem_info)
1326+ r = right->mem_info->daddr.phys_addr;
1327+
1328+ return (int64_t)(r - l);
1329+}
1330+
1331+static int hist_entry__phys_daddr_snprintf(struct hist_entry *he, char *bf,
1332+ size_t size, unsigned int width)
1333+{
1334+ uint64_t addr = 0;
1335+ size_t ret = 0;
1336+ size_t len = BITS_PER_LONG / 4;
1337+
1338+ addr = he->mem_info->daddr.phys_addr;
1339+
1340+ ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", he->level);
1341+
1342+ ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, addr);
1343+
1344+ ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, "");
1345+
1346+ if (ret > width)
1347+ bf[width] = '\0';
1348+
1349+ return width;
1350+}
1351+
1352+struct sort_entry sort_mem_phys_daddr = {
1353+ .se_header = "Data Physical Address",
1354+ .se_cmp = sort__phys_daddr_cmp,
1355+ .se_snprintf = hist_entry__phys_daddr_snprintf,
1356+ .se_width_idx = HISTC_MEM_PHYS_DADDR,
1357+};
1358+
13181359 static int64_t
13191360 sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
13201361 {
@@ -1547,6 +1588,7 @@ static struct sort_dimension memory_sort_dimensions[] = { · 226 unmodified lines
15471588 DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
15481589 DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
15491590 DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline),
1591+ DIM(SORT_MEM_PHYS_DADDR, "phys_daddr", sort_mem_phys_daddr),
15501592 };
15511593
15521594 #undef DIM
tools/perf/util/sort.h+1−0
@@ -245,6 +245,7 @@ enum sort_type { · 244 unmodified lines
245245 SORT_MEM_SNOOP,
246246 SORT_MEM_DCACHELINE,
247247 SORT_MEM_IADDR_SYMBOL,
248+ SORT_MEM_PHYS_DADDR,
248249 };
249250
250251 /*
tools/perf/util/symbol.h+1−0
@@ -186,6 +186,7 @@ struct addr_map_symbol { · 185 unmodified lines
186186 struct symbol *sym;
187187 u64 addr;
188188 u64 al_addr;
189+ u64 phys_addr;
189190 };
190191
191192 struct branch_info {
tools/perf/util/syscalltbl.c+33−0
@@ -19,6 +19,7 @@ · 18 unmodified lines
1919 #ifdef HAVE_SYSCALL_TABLE
2020 #include <linux/compiler.h>
2121 #include <string.h>
22+#include "string2.h"
2223 #include "util.h"
2324
2425 #if defined(__x86_64__)
@@ -105,6 +106,27 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) · 80 unmodified lines
105106 return sc ? sc->id : -1;
106107 }
107108
109+int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
110+{
111+ int i;
112+ struct syscall *syscalls = tbl->syscalls.entries;
113+
114+ for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
115+ if (strglobmatch(syscalls[i].name, syscall_glob)) {
116+ *idx = i;
117+ return syscalls[i].id;
118+ }
119+ }
120+
121+ return -1;
122+}
123+
124+int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
125+{
126+ *idx = -1;
127+ return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
128+}
129+
108130 #else /* HAVE_SYSCALL_TABLE */
109131
110132 #include <libaudit.h>
@@ -131,4 +153,15 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) · 20 unmodified lines
131153 {
132154 return audit_name_to_syscall(name, tbl->audit_machine);
133155 }
156+
157+int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
158+ const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
159+{
160+ return -1;
161+}
162+
163+int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
164+{
165+ return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
166+}
134167 #endif /* HAVE_SYSCALL_TABLE */
tools/perf/util/syscalltbl.h+3−0
@@ -17,4 +17,7 @@ void syscalltbl__delete(struct syscalltbl *tbl); · 16 unmodified lines
1717 const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
1818 int syscalltbl__id(struct syscalltbl *tbl, const char *name);
1919
20+int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
21+int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
22+
2023 #endif /* __PERF_SYSCALLTBL_H */