diff options
| -rw-r--r-- | tools/arch/powerpc/include/uapi/asm/unistd.h | 1 | ||||
| -rw-r--r-- | tools/include/uapi/drm/drm.h | 7 | ||||
| -rw-r--r-- | tools/include/uapi/linux/bpf.h | 2 | ||||
| -rw-r--r-- | tools/include/uapi/linux/if_link.h | 2 | ||||
| -rw-r--r-- | tools/perf/arch/powerpc/util/skip-callchain-idx.c | 2 | ||||
| -rw-r--r-- | tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 2 | ||||
| -rw-r--r-- | tools/perf/bench/numa.c | 5 | ||||
| -rw-r--r-- | tools/perf/builtin-annotate.c | 11 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 3 | ||||
| -rw-r--r-- | tools/perf/builtin-script.c | 30 | ||||
| -rw-r--r-- | tools/perf/tests/parse-events.c | 25 | ||||
| -rw-r--r-- | tools/perf/tests/topology.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/c++/clang.cpp | 11 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 12 | ||||
| -rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/pmu.c | 99 |
16 files changed, 194 insertions, 21 deletions
diff --git a/tools/arch/powerpc/include/uapi/asm/unistd.h b/tools/arch/powerpc/include/uapi/asm/unistd.h index 389c36fd8299..ac5ba55066dd 100644 --- a/tools/arch/powerpc/include/uapi/asm/unistd.h +++ b/tools/arch/powerpc/include/uapi/asm/unistd.h | |||
| @@ -398,5 +398,6 @@ | |||
| 398 | #define __NR_pkey_alloc 384 | 398 | #define __NR_pkey_alloc 384 |
| 399 | #define __NR_pkey_free 385 | 399 | #define __NR_pkey_free 385 |
| 400 | #define __NR_pkey_mprotect 386 | 400 | #define __NR_pkey_mprotect 386 |
| 401 | #define __NR_rseq 387 | ||
| 401 | 402 | ||
| 402 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ | 403 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ |
diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h index 6fdff5945c8a..9c660e1688ab 100644 --- a/tools/include/uapi/drm/drm.h +++ b/tools/include/uapi/drm/drm.h | |||
| @@ -680,6 +680,13 @@ struct drm_get_cap { | |||
| 680 | */ | 680 | */ |
| 681 | #define DRM_CLIENT_CAP_ATOMIC 3 | 681 | #define DRM_CLIENT_CAP_ATOMIC 3 |
| 682 | 682 | ||
| 683 | /** | ||
| 684 | * DRM_CLIENT_CAP_ASPECT_RATIO | ||
| 685 | * | ||
| 686 | * If set to 1, the DRM core will provide aspect ratio information in modes. | ||
| 687 | */ | ||
| 688 | #define DRM_CLIENT_CAP_ASPECT_RATIO 4 | ||
| 689 | |||
| 683 | /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ | 690 | /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ |
| 684 | struct drm_set_client_cap { | 691 | struct drm_set_client_cap { |
| 685 | __u64 capability; | 692 | __u64 capability; |
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index e0b06784f227..59b19b6a40d7 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
| @@ -2630,7 +2630,7 @@ struct bpf_fib_lookup { | |||
| 2630 | union { | 2630 | union { |
| 2631 | /* inputs to lookup */ | 2631 | /* inputs to lookup */ |
| 2632 | __u8 tos; /* AF_INET */ | 2632 | __u8 tos; /* AF_INET */ |
| 2633 | __be32 flowlabel; /* AF_INET6 */ | 2633 | __be32 flowinfo; /* AF_INET6, flow_label + priority */ |
| 2634 | 2634 | ||
| 2635 | /* output: metric of fib result (IPv4/IPv6 only) */ | 2635 | /* output: metric of fib result (IPv4/IPv6 only) */ |
| 2636 | __u32 rt_metric; | 2636 | __u32 rt_metric; |
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index 68699f654118..cf01b6824244 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h | |||
| @@ -333,6 +333,7 @@ enum { | |||
| 333 | IFLA_BRPORT_BCAST_FLOOD, | 333 | IFLA_BRPORT_BCAST_FLOOD, |
| 334 | IFLA_BRPORT_GROUP_FWD_MASK, | 334 | IFLA_BRPORT_GROUP_FWD_MASK, |
| 335 | IFLA_BRPORT_NEIGH_SUPPRESS, | 335 | IFLA_BRPORT_NEIGH_SUPPRESS, |
| 336 | IFLA_BRPORT_ISOLATED, | ||
| 336 | __IFLA_BRPORT_MAX | 337 | __IFLA_BRPORT_MAX |
| 337 | }; | 338 | }; |
| 338 | #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) | 339 | #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) |
| @@ -516,6 +517,7 @@ enum { | |||
| 516 | IFLA_VXLAN_COLLECT_METADATA, | 517 | IFLA_VXLAN_COLLECT_METADATA, |
| 517 | IFLA_VXLAN_LABEL, | 518 | IFLA_VXLAN_LABEL, |
| 518 | IFLA_VXLAN_GPE, | 519 | IFLA_VXLAN_GPE, |
| 520 | IFLA_VXLAN_TTL_INHERIT, | ||
| 519 | __IFLA_VXLAN_MAX | 521 | __IFLA_VXLAN_MAX |
| 520 | }; | 522 | }; |
| 521 | #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) | 523 | #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) |
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index 3598b8b75d27..ef5d59a5742e 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c | |||
| @@ -243,7 +243,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) | |||
| 243 | u64 ip; | 243 | u64 ip; |
| 244 | u64 skip_slot = -1; | 244 | u64 skip_slot = -1; |
| 245 | 245 | ||
| 246 | if (chain->nr < 3) | 246 | if (!chain || chain->nr < 3) |
| 247 | return skip_slot; | 247 | return skip_slot; |
| 248 | 248 | ||
| 249 | ip = chain->ips[2]; | 249 | ip = chain->ips[2]; |
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index 4dfe42666d0c..f0b1709a5ffb 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | |||
| @@ -341,6 +341,8 @@ | |||
| 341 | 330 common pkey_alloc __x64_sys_pkey_alloc | 341 | 330 common pkey_alloc __x64_sys_pkey_alloc |
| 342 | 331 common pkey_free __x64_sys_pkey_free | 342 | 331 common pkey_free __x64_sys_pkey_free |
| 343 | 332 common statx __x64_sys_statx | 343 | 332 common statx __x64_sys_statx |
| 344 | 333 common io_pgetevents __x64_sys_io_pgetevents | ||
| 345 | 334 common rseq __x64_sys_rseq | ||
| 344 | 346 | ||
| 345 | # | 347 | # |
| 346 | # x32-specific system call numbers start at 512 to avoid cache impact | 348 | # x32-specific system call numbers start at 512 to avoid cache impact |
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 63eb49082774..44195514b19e 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
| @@ -1098,7 +1098,7 @@ static void *worker_thread(void *__tdata) | |||
| 1098 | u8 *global_data; | 1098 | u8 *global_data; |
| 1099 | u8 *process_data; | 1099 | u8 *process_data; |
| 1100 | u8 *thread_data; | 1100 | u8 *thread_data; |
| 1101 | u64 bytes_done; | 1101 | u64 bytes_done, secs; |
| 1102 | long work_done; | 1102 | long work_done; |
| 1103 | u32 l; | 1103 | u32 l; |
| 1104 | struct rusage rusage; | 1104 | struct rusage rusage; |
| @@ -1254,7 +1254,8 @@ static void *worker_thread(void *__tdata) | |||
| 1254 | timersub(&stop, &start0, &diff); | 1254 | timersub(&stop, &start0, &diff); |
| 1255 | td->runtime_ns = diff.tv_sec * NSEC_PER_SEC; | 1255 | td->runtime_ns = diff.tv_sec * NSEC_PER_SEC; |
| 1256 | td->runtime_ns += diff.tv_usec * NSEC_PER_USEC; | 1256 | td->runtime_ns += diff.tv_usec * NSEC_PER_USEC; |
| 1257 | td->speed_gbs = bytes_done / (td->runtime_ns / NSEC_PER_SEC) / 1e9; | 1257 | secs = td->runtime_ns / NSEC_PER_SEC; |
| 1258 | td->speed_gbs = secs ? bytes_done / secs / 1e9 : 0; | ||
| 1258 | 1259 | ||
| 1259 | getrusage(RUSAGE_THREAD, &rusage); | 1260 | getrusage(RUSAGE_THREAD, &rusage); |
| 1260 | td->system_time_ns = rusage.ru_stime.tv_sec * NSEC_PER_SEC; | 1261 | td->system_time_ns = rusage.ru_stime.tv_sec * NSEC_PER_SEC; |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 5eb22cc56363..8180319285af 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -283,6 +283,15 @@ out_put: | |||
| 283 | return ret; | 283 | return ret; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static int process_feature_event(struct perf_tool *tool, | ||
| 287 | union perf_event *event, | ||
| 288 | struct perf_session *session) | ||
| 289 | { | ||
| 290 | if (event->feat.feat_id < HEADER_LAST_FEATURE) | ||
| 291 | return perf_event__process_feature(tool, event, session); | ||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 286 | static int hist_entry__tty_annotate(struct hist_entry *he, | 295 | static int hist_entry__tty_annotate(struct hist_entry *he, |
| 287 | struct perf_evsel *evsel, | 296 | struct perf_evsel *evsel, |
| 288 | struct perf_annotate *ann) | 297 | struct perf_annotate *ann) |
| @@ -471,7 +480,7 @@ int cmd_annotate(int argc, const char **argv) | |||
| 471 | .attr = perf_event__process_attr, | 480 | .attr = perf_event__process_attr, |
| 472 | .build_id = perf_event__process_build_id, | 481 | .build_id = perf_event__process_build_id, |
| 473 | .tracing_data = perf_event__process_tracing_data, | 482 | .tracing_data = perf_event__process_tracing_data, |
| 474 | .feature = perf_event__process_feature, | 483 | .feature = process_feature_event, |
| 475 | .ordered_events = true, | 484 | .ordered_events = true, |
| 476 | .ordering_requires_timestamps = true, | 485 | .ordering_requires_timestamps = true, |
| 477 | }, | 486 | }, |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index cdb5b6949832..c04dc7b53797 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -217,7 +217,8 @@ static int process_feature_event(struct perf_tool *tool, | |||
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | /* | 219 | /* |
| 220 | * All features are received, we can force the | 220 | * (feat_id = HEADER_LAST_FEATURE) is the end marker which |
| 221 | * means all features are received, now we can force the | ||
| 221 | * group if needed. | 222 | * group if needed. |
| 222 | */ | 223 | */ |
| 223 | setup_forced_leader(rep, session->evlist); | 224 | setup_forced_leader(rep, session->evlist); |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index a31d7082188e..568ddfac3213 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -1834,6 +1834,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, | |||
| 1834 | struct perf_evlist *evlist; | 1834 | struct perf_evlist *evlist; |
| 1835 | struct perf_evsel *evsel, *pos; | 1835 | struct perf_evsel *evsel, *pos; |
| 1836 | int err; | 1836 | int err; |
| 1837 | static struct perf_evsel_script *es; | ||
| 1837 | 1838 | ||
| 1838 | err = perf_event__process_attr(tool, event, pevlist); | 1839 | err = perf_event__process_attr(tool, event, pevlist); |
| 1839 | if (err) | 1840 | if (err) |
| @@ -1842,6 +1843,19 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, | |||
| 1842 | evlist = *pevlist; | 1843 | evlist = *pevlist; |
| 1843 | evsel = perf_evlist__last(*pevlist); | 1844 | evsel = perf_evlist__last(*pevlist); |
| 1844 | 1845 | ||
| 1846 | if (!evsel->priv) { | ||
| 1847 | if (scr->per_event_dump) { | ||
| 1848 | evsel->priv = perf_evsel_script__new(evsel, | ||
| 1849 | scr->session->data); | ||
| 1850 | } else { | ||
| 1851 | es = zalloc(sizeof(*es)); | ||
| 1852 | if (!es) | ||
| 1853 | return -ENOMEM; | ||
| 1854 | es->fp = stdout; | ||
| 1855 | evsel->priv = es; | ||
| 1856 | } | ||
| 1857 | } | ||
| 1858 | |||
| 1845 | if (evsel->attr.type >= PERF_TYPE_MAX && | 1859 | if (evsel->attr.type >= PERF_TYPE_MAX && |
| 1846 | evsel->attr.type != PERF_TYPE_SYNTH) | 1860 | evsel->attr.type != PERF_TYPE_SYNTH) |
| 1847 | return 0; | 1861 | return 0; |
| @@ -3030,6 +3044,15 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused, | |||
| 3030 | return set_maps(script); | 3044 | return set_maps(script); |
| 3031 | } | 3045 | } |
| 3032 | 3046 | ||
| 3047 | static int process_feature_event(struct perf_tool *tool, | ||
| 3048 | union perf_event *event, | ||
| 3049 | struct perf_session *session) | ||
| 3050 | { | ||
| 3051 | if (event->feat.feat_id < HEADER_LAST_FEATURE) | ||
| 3052 | return perf_event__process_feature(tool, event, session); | ||
| 3053 | return 0; | ||
| 3054 | } | ||
| 3055 | |||
| 3033 | #ifdef HAVE_AUXTRACE_SUPPORT | 3056 | #ifdef HAVE_AUXTRACE_SUPPORT |
| 3034 | static int perf_script__process_auxtrace_info(struct perf_tool *tool, | 3057 | static int perf_script__process_auxtrace_info(struct perf_tool *tool, |
| 3035 | union perf_event *event, | 3058 | union perf_event *event, |
| @@ -3074,7 +3097,7 @@ int cmd_script(int argc, const char **argv) | |||
| 3074 | .attr = process_attr, | 3097 | .attr = process_attr, |
| 3075 | .event_update = perf_event__process_event_update, | 3098 | .event_update = perf_event__process_event_update, |
| 3076 | .tracing_data = perf_event__process_tracing_data, | 3099 | .tracing_data = perf_event__process_tracing_data, |
| 3077 | .feature = perf_event__process_feature, | 3100 | .feature = process_feature_event, |
| 3078 | .build_id = perf_event__process_build_id, | 3101 | .build_id = perf_event__process_build_id, |
| 3079 | .id_index = perf_event__process_id_index, | 3102 | .id_index = perf_event__process_id_index, |
| 3080 | .auxtrace_info = perf_script__process_auxtrace_info, | 3103 | .auxtrace_info = perf_script__process_auxtrace_info, |
| @@ -3125,8 +3148,9 @@ int cmd_script(int argc, const char **argv) | |||
| 3125 | "+field to add and -field to remove." | 3148 | "+field to add and -field to remove." |
| 3126 | "Valid types: hw,sw,trace,raw,synth. " | 3149 | "Valid types: hw,sw,trace,raw,synth. " |
| 3127 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," | 3150 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," |
| 3128 | "addr,symoff,period,iregs,uregs,brstack,brstacksym,flags," | 3151 | "addr,symoff,srcline,period,iregs,uregs,brstack," |
| 3129 | "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", | 3152 | "brstacksym,flags,bpf-output,brstackinsn,brstackoff," |
| 3153 | "callindent,insn,insnlen,synth,phys_addr,metric,misc", | ||
| 3130 | parse_output_fields), | 3154 | parse_output_fields), |
| 3131 | OPT_BOOLEAN('a', "all-cpus", &system_wide, | 3155 | OPT_BOOLEAN('a', "all-cpus", &system_wide, |
| 3132 | "system-wide collection from all CPUs"), | 3156 | "system-wide collection from all CPUs"), |
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 7d4077068454..61211918bfba 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
| @@ -1309,6 +1309,11 @@ static int test__checkevent_config_cache(struct perf_evlist *evlist) | |||
| 1309 | return 0; | 1309 | return 0; |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| 1312 | static bool test__intel_pt_valid(void) | ||
| 1313 | { | ||
| 1314 | return !!perf_pmu__find("intel_pt"); | ||
| 1315 | } | ||
| 1316 | |||
| 1312 | static int test__intel_pt(struct perf_evlist *evlist) | 1317 | static int test__intel_pt(struct perf_evlist *evlist) |
| 1313 | { | 1318 | { |
| 1314 | struct perf_evsel *evsel = perf_evlist__first(evlist); | 1319 | struct perf_evsel *evsel = perf_evlist__first(evlist); |
| @@ -1375,6 +1380,7 @@ struct evlist_test { | |||
| 1375 | const char *name; | 1380 | const char *name; |
| 1376 | __u32 type; | 1381 | __u32 type; |
| 1377 | const int id; | 1382 | const int id; |
| 1383 | bool (*valid)(void); | ||
| 1378 | int (*check)(struct perf_evlist *evlist); | 1384 | int (*check)(struct perf_evlist *evlist); |
| 1379 | }; | 1385 | }; |
| 1380 | 1386 | ||
| @@ -1648,6 +1654,7 @@ static struct evlist_test test__events[] = { | |||
| 1648 | }, | 1654 | }, |
| 1649 | { | 1655 | { |
| 1650 | .name = "intel_pt//u", | 1656 | .name = "intel_pt//u", |
| 1657 | .valid = test__intel_pt_valid, | ||
| 1651 | .check = test__intel_pt, | 1658 | .check = test__intel_pt, |
| 1652 | .id = 52, | 1659 | .id = 52, |
| 1653 | }, | 1660 | }, |
| @@ -1686,17 +1693,24 @@ static struct terms_test test__terms[] = { | |||
| 1686 | 1693 | ||
| 1687 | static int test_event(struct evlist_test *e) | 1694 | static int test_event(struct evlist_test *e) |
| 1688 | { | 1695 | { |
| 1696 | struct parse_events_error err = { .idx = 0, }; | ||
| 1689 | struct perf_evlist *evlist; | 1697 | struct perf_evlist *evlist; |
| 1690 | int ret; | 1698 | int ret; |
| 1691 | 1699 | ||
| 1700 | if (e->valid && !e->valid()) { | ||
| 1701 | pr_debug("... SKIP"); | ||
| 1702 | return 0; | ||
| 1703 | } | ||
| 1704 | |||
| 1692 | evlist = perf_evlist__new(); | 1705 | evlist = perf_evlist__new(); |
| 1693 | if (evlist == NULL) | 1706 | if (evlist == NULL) |
| 1694 | return -ENOMEM; | 1707 | return -ENOMEM; |
| 1695 | 1708 | ||
| 1696 | ret = parse_events(evlist, e->name, NULL); | 1709 | ret = parse_events(evlist, e->name, &err); |
| 1697 | if (ret) { | 1710 | if (ret) { |
| 1698 | pr_debug("failed to parse event '%s', err %d\n", | 1711 | pr_debug("failed to parse event '%s', err %d, str '%s'\n", |
| 1699 | e->name, ret); | 1712 | e->name, ret, err.str); |
| 1713 | parse_events_print_error(&err, e->name); | ||
| 1700 | } else { | 1714 | } else { |
| 1701 | ret = e->check(evlist); | 1715 | ret = e->check(evlist); |
| 1702 | } | 1716 | } |
| @@ -1714,10 +1728,11 @@ static int test_events(struct evlist_test *events, unsigned cnt) | |||
| 1714 | for (i = 0; i < cnt; i++) { | 1728 | for (i = 0; i < cnt; i++) { |
| 1715 | struct evlist_test *e = &events[i]; | 1729 | struct evlist_test *e = &events[i]; |
| 1716 | 1730 | ||
| 1717 | pr_debug("running test %d '%s'\n", e->id, e->name); | 1731 | pr_debug("running test %d '%s'", e->id, e->name); |
| 1718 | ret1 = test_event(e); | 1732 | ret1 = test_event(e); |
| 1719 | if (ret1) | 1733 | if (ret1) |
| 1720 | ret2 = ret1; | 1734 | ret2 = ret1; |
| 1735 | pr_debug("\n"); | ||
| 1721 | } | 1736 | } |
| 1722 | 1737 | ||
| 1723 | return ret2; | 1738 | return ret2; |
| @@ -1799,7 +1814,7 @@ static int test_pmu_events(void) | |||
| 1799 | } | 1814 | } |
| 1800 | 1815 | ||
| 1801 | while (!ret && (ent = readdir(dir))) { | 1816 | while (!ret && (ent = readdir(dir))) { |
| 1802 | struct evlist_test e; | 1817 | struct evlist_test e = { .id = 0, }; |
| 1803 | char name[2 * NAME_MAX + 1 + 12 + 3]; | 1818 | char name[2 * NAME_MAX + 1 + 12 + 3]; |
| 1804 | 1819 | ||
| 1805 | /* Names containing . are special and cannot be used directly */ | 1820 | /* Names containing . are special and cannot be used directly */ |
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 40e30a26b23c..9497d02f69e6 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c | |||
| @@ -45,6 +45,7 @@ static int session_write_header(char *path) | |||
| 45 | 45 | ||
| 46 | perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); | 46 | perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); |
| 47 | perf_header__set_feat(&session->header, HEADER_NRCPUS); | 47 | perf_header__set_feat(&session->header, HEADER_NRCPUS); |
| 48 | perf_header__set_feat(&session->header, HEADER_ARCH); | ||
| 48 | 49 | ||
| 49 | session->header.data_size += DATA_SIZE; | 50 | session->header.data_size += DATA_SIZE; |
| 50 | 51 | ||
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index bf31ceab33bd..89512504551b 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp | |||
| @@ -146,8 +146,15 @@ getBPFObjectFromModule(llvm::Module *Module) | |||
| 146 | raw_svector_ostream ostream(*Buffer); | 146 | raw_svector_ostream ostream(*Buffer); |
| 147 | 147 | ||
| 148 | legacy::PassManager PM; | 148 | legacy::PassManager PM; |
| 149 | if (TargetMachine->addPassesToEmitFile(PM, ostream, | 149 | bool NotAdded; |
| 150 | TargetMachine::CGFT_ObjectFile)) { | 150 | #if CLANG_VERSION_MAJOR < 7 |
| 151 | NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, | ||
| 152 | TargetMachine::CGFT_ObjectFile); | ||
| 153 | #else | ||
| 154 | NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, nullptr, | ||
| 155 | TargetMachine::CGFT_ObjectFile); | ||
| 156 | #endif | ||
| 157 | if (NotAdded) { | ||
| 151 | llvm::errs() << "TargetMachine can't emit a file of this type\n"; | 158 | llvm::errs() << "TargetMachine can't emit a file of this type\n"; |
| 152 | return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);; | 159 | return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);; |
| 153 | } | 160 | } |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 540cd2dcd3e7..653ff65aa2c3 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -2129,6 +2129,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) | |||
| 2129 | int cpu_nr = ff->ph->env.nr_cpus_avail; | 2129 | int cpu_nr = ff->ph->env.nr_cpus_avail; |
| 2130 | u64 size = 0; | 2130 | u64 size = 0; |
| 2131 | struct perf_header *ph = ff->ph; | 2131 | struct perf_header *ph = ff->ph; |
| 2132 | bool do_core_id_test = true; | ||
| 2132 | 2133 | ||
| 2133 | ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); | 2134 | ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); |
| 2134 | if (!ph->env.cpu) | 2135 | if (!ph->env.cpu) |
| @@ -2183,6 +2184,13 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) | |||
| 2183 | return 0; | 2184 | return 0; |
| 2184 | } | 2185 | } |
| 2185 | 2186 | ||
| 2187 | /* On s390 the socket_id number is not related to the numbers of cpus. | ||
| 2188 | * The socket_id number might be higher than the numbers of cpus. | ||
| 2189 | * This depends on the configuration. | ||
| 2190 | */ | ||
| 2191 | if (ph->env.arch && !strncmp(ph->env.arch, "s390", 4)) | ||
| 2192 | do_core_id_test = false; | ||
| 2193 | |||
| 2186 | for (i = 0; i < (u32)cpu_nr; i++) { | 2194 | for (i = 0; i < (u32)cpu_nr; i++) { |
| 2187 | if (do_read_u32(ff, &nr)) | 2195 | if (do_read_u32(ff, &nr)) |
| 2188 | goto free_cpu; | 2196 | goto free_cpu; |
| @@ -2192,7 +2200,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) | |||
| 2192 | if (do_read_u32(ff, &nr)) | 2200 | if (do_read_u32(ff, &nr)) |
| 2193 | goto free_cpu; | 2201 | goto free_cpu; |
| 2194 | 2202 | ||
| 2195 | if (nr != (u32)-1 && nr > (u32)cpu_nr) { | 2203 | if (do_core_id_test && nr != (u32)-1 && nr > (u32)cpu_nr) { |
| 2196 | pr_debug("socket_id number is too big." | 2204 | pr_debug("socket_id number is too big." |
| 2197 | "You may need to upgrade the perf tool.\n"); | 2205 | "You may need to upgrade the perf tool.\n"); |
| 2198 | goto free_cpu; | 2206 | goto free_cpu; |
| @@ -3456,7 +3464,7 @@ int perf_event__process_feature(struct perf_tool *tool, | |||
| 3456 | pr_warning("invalid record type %d in pipe-mode\n", type); | 3464 | pr_warning("invalid record type %d in pipe-mode\n", type); |
| 3457 | return 0; | 3465 | return 0; |
| 3458 | } | 3466 | } |
| 3459 | if (feat == HEADER_RESERVED || feat > HEADER_LAST_FEATURE) { | 3467 | if (feat == HEADER_RESERVED || feat >= HEADER_LAST_FEATURE) { |
| 3460 | pr_warning("invalid record type %d in pipe-mode\n", type); | 3468 | pr_warning("invalid record type %d in pipe-mode\n", type); |
| 3461 | return -1; | 3469 | return -1; |
| 3462 | } | 3470 | } |
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c index ba4c9dd18643..d426761a549d 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c | |||
| @@ -366,7 +366,7 @@ static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf, | |||
| 366 | if (len < offs) | 366 | if (len < offs) |
| 367 | return INTEL_PT_NEED_MORE_BYTES; | 367 | return INTEL_PT_NEED_MORE_BYTES; |
| 368 | byte = buf[offs++]; | 368 | byte = buf[offs++]; |
| 369 | payload |= (byte >> 1) << shift; | 369 | payload |= ((uint64_t)byte >> 1) << shift; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | packet->type = INTEL_PT_CYC; | 372 | packet->type = INTEL_PT_CYC; |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d2fb597c9a8c..3ba6a1742f91 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
| @@ -234,6 +234,74 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, | |||
| 234 | return 0; | 234 | return 0; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | static void perf_pmu_assign_str(char *name, const char *field, char **old_str, | ||
| 238 | char **new_str) | ||
| 239 | { | ||
| 240 | if (!*old_str) | ||
| 241 | goto set_new; | ||
| 242 | |||
| 243 | if (*new_str) { /* Have new string, check with old */ | ||
| 244 | if (strcasecmp(*old_str, *new_str)) | ||
| 245 | pr_debug("alias %s differs in field '%s'\n", | ||
| 246 | name, field); | ||
| 247 | zfree(old_str); | ||
| 248 | } else /* Nothing new --> keep old string */ | ||
| 249 | return; | ||
| 250 | set_new: | ||
| 251 | *old_str = *new_str; | ||
| 252 | *new_str = NULL; | ||
| 253 | } | ||
| 254 | |||
| 255 | static void perf_pmu_update_alias(struct perf_pmu_alias *old, | ||
| 256 | struct perf_pmu_alias *newalias) | ||
| 257 | { | ||
| 258 | perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc); | ||
| 259 | perf_pmu_assign_str(old->name, "long_desc", &old->long_desc, | ||
| 260 | &newalias->long_desc); | ||
| 261 | perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic); | ||
| 262 | perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr, | ||
| 263 | &newalias->metric_expr); | ||
| 264 | perf_pmu_assign_str(old->name, "metric_name", &old->metric_name, | ||
| 265 | &newalias->metric_name); | ||
| 266 | perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str); | ||
| 267 | old->scale = newalias->scale; | ||
| 268 | old->per_pkg = newalias->per_pkg; | ||
| 269 | old->snapshot = newalias->snapshot; | ||
| 270 | memcpy(old->unit, newalias->unit, sizeof(old->unit)); | ||
| 271 | } | ||
| 272 | |||
| 273 | /* Delete an alias entry. */ | ||
| 274 | static void perf_pmu_free_alias(struct perf_pmu_alias *newalias) | ||
| 275 | { | ||
| 276 | zfree(&newalias->name); | ||
| 277 | zfree(&newalias->desc); | ||
| 278 | zfree(&newalias->long_desc); | ||
| 279 | zfree(&newalias->topic); | ||
| 280 | zfree(&newalias->str); | ||
| 281 | zfree(&newalias->metric_expr); | ||
| 282 | zfree(&newalias->metric_name); | ||
| 283 | parse_events_terms__purge(&newalias->terms); | ||
| 284 | free(newalias); | ||
| 285 | } | ||
| 286 | |||
| 287 | /* Merge an alias, search in alias list. If this name is already | ||
| 288 | * present merge both of them to combine all information. | ||
| 289 | */ | ||
| 290 | static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias, | ||
| 291 | struct list_head *alist) | ||
| 292 | { | ||
| 293 | struct perf_pmu_alias *a; | ||
| 294 | |||
| 295 | list_for_each_entry(a, alist, list) { | ||
| 296 | if (!strcasecmp(newalias->name, a->name)) { | ||
| 297 | perf_pmu_update_alias(a, newalias); | ||
| 298 | perf_pmu_free_alias(newalias); | ||
| 299 | return true; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | return false; | ||
| 303 | } | ||
| 304 | |||
| 237 | static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, | 305 | static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, |
| 238 | char *desc, char *val, | 306 | char *desc, char *val, |
| 239 | char *long_desc, char *topic, | 307 | char *long_desc, char *topic, |
| @@ -241,9 +309,11 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, | |||
| 241 | char *metric_expr, | 309 | char *metric_expr, |
| 242 | char *metric_name) | 310 | char *metric_name) |
| 243 | { | 311 | { |
| 312 | struct parse_events_term *term; | ||
| 244 | struct perf_pmu_alias *alias; | 313 | struct perf_pmu_alias *alias; |
| 245 | int ret; | 314 | int ret; |
| 246 | int num; | 315 | int num; |
| 316 | char newval[256]; | ||
| 247 | 317 | ||
| 248 | alias = malloc(sizeof(*alias)); | 318 | alias = malloc(sizeof(*alias)); |
| 249 | if (!alias) | 319 | if (!alias) |
| @@ -262,6 +332,27 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, | |||
| 262 | return ret; | 332 | return ret; |
| 263 | } | 333 | } |
| 264 | 334 | ||
| 335 | /* Scan event and remove leading zeroes, spaces, newlines, some | ||
| 336 | * platforms have terms specified as | ||
| 337 | * event=0x0091 (read from files ../<PMU>/events/<FILE> | ||
| 338 | * and terms specified as event=0x91 (read from JSON files). | ||
| 339 | * | ||
| 340 | * Rebuild string to make alias->str member comparable. | ||
| 341 | */ | ||
| 342 | memset(newval, 0, sizeof(newval)); | ||
| 343 | ret = 0; | ||
| 344 | list_for_each_entry(term, &alias->terms, list) { | ||
| 345 | if (ret) | ||
| 346 | ret += scnprintf(newval + ret, sizeof(newval) - ret, | ||
| 347 | ","); | ||
| 348 | if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) | ||
| 349 | ret += scnprintf(newval + ret, sizeof(newval) - ret, | ||
| 350 | "%s=%#x", term->config, term->val.num); | ||
| 351 | else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) | ||
| 352 | ret += scnprintf(newval + ret, sizeof(newval) - ret, | ||
| 353 | "%s=%s", term->config, term->val.str); | ||
| 354 | } | ||
| 355 | |||
| 265 | alias->name = strdup(name); | 356 | alias->name = strdup(name); |
| 266 | if (dir) { | 357 | if (dir) { |
| 267 | /* | 358 | /* |
| @@ -285,9 +376,10 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, | |||
| 285 | snprintf(alias->unit, sizeof(alias->unit), "%s", unit); | 376 | snprintf(alias->unit, sizeof(alias->unit), "%s", unit); |
| 286 | } | 377 | } |
| 287 | alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1; | 378 | alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1; |
| 288 | alias->str = strdup(val); | 379 | alias->str = strdup(newval); |
| 289 | 380 | ||
| 290 | list_add_tail(&alias->list, list); | 381 | if (!perf_pmu_merge_alias(alias, list)) |
| 382 | list_add_tail(&alias->list, list); | ||
| 291 | 383 | ||
| 292 | return 0; | 384 | return 0; |
| 293 | } | 385 | } |
| @@ -303,6 +395,9 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI | |||
| 303 | 395 | ||
| 304 | buf[ret] = 0; | 396 | buf[ret] = 0; |
| 305 | 397 | ||
| 398 | /* Remove trailing newline from sysfs file */ | ||
| 399 | rtrim(buf); | ||
| 400 | |||
| 306 | return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, | 401 | return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, |
| 307 | NULL, NULL, NULL); | 402 | NULL, NULL, NULL); |
| 308 | } | 403 | } |
