aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/events/core.c2
-rw-r--r--tools/arch/arm64/include/uapi/asm/unistd.h2
-rw-r--r--tools/include/uapi/asm-generic/unistd.h149
-rw-r--r--tools/include/uapi/linux/in.h9
-rw-r--r--tools/lib/bpf/libbpf.h1
-rw-r--r--tools/perf/Documentation/perf-config.txt14
-rw-r--r--tools/perf/Documentation/perf-report.txt13
-rw-r--r--tools/perf/Documentation/tips.txt7
-rw-r--r--tools/perf/arch/x86/entry/syscalls/syscall_64.tbl6
-rw-r--r--tools/perf/arch/x86/util/Build1
-rw-r--r--tools/perf/arch/x86/util/archinsn.c26
-rw-r--r--tools/perf/builtin-record.c4
-rw-r--r--tools/perf/builtin-report.c45
-rw-r--r--tools/perf/builtin-script.c111
-rw-r--r--tools/perf/builtin.h3
-rw-r--r--tools/perf/pmu-events/arch/x86/amdfam17h/branch.json12
-rw-r--r--tools/perf/pmu-events/arch/x86/amdfam17h/cache.json287
-rw-r--r--tools/perf/pmu-events/arch/x86/amdfam17h/core.json134
-rw-r--r--tools/perf/pmu-events/arch/x86/amdfam17h/floating-point.json168
-rw-r--r--tools/perf/pmu-events/arch/x86/amdfam17h/memory.json162
-rw-r--r--tools/perf/pmu-events/arch/x86/amdfam17h/other.json65
-rw-r--r--tools/perf/pmu-events/arch/x86/mapfile.csv1
-rw-r--r--tools/perf/scripts/python/export-to-postgresql.py61
-rw-r--r--tools/perf/scripts/python/export-to-sqlite.py26
-rwxr-xr-xtools/perf/scripts/python/exported-sql-viewer.py42
-rw-r--r--tools/perf/ui/browser.c10
-rw-r--r--tools/perf/ui/browsers/Build1
-rw-r--r--tools/perf/ui/browsers/annotate.c2
-rw-r--r--tools/perf/ui/browsers/hists.c141
-rw-r--r--tools/perf/ui/browsers/res_sample.c91
-rw-r--r--tools/perf/ui/browsers/scripts.c274
-rw-r--r--tools/perf/util/archinsn.h12
-rw-r--r--tools/perf/util/data.c96
-rw-r--r--tools/perf/util/data.h12
-rw-r--r--tools/perf/util/header.c44
-rw-r--r--tools/perf/util/header.h5
-rw-r--r--tools/perf/util/hist.c50
-rw-r--r--tools/perf/util/hist.h31
-rw-r--r--tools/perf/util/probe-event.c6
-rw-r--r--tools/perf/util/session.c27
-rw-r--r--tools/perf/util/sort.c39
-rw-r--r--tools/perf/util/sort.h10
-rw-r--r--tools/perf/util/symbol.c4
-rw-r--r--tools/perf/util/symbol_conf.h3
-rw-r--r--tools/perf/util/time-utils.c8
-rw-r--r--tools/perf/util/time-utils.h1
46 files changed, 1931 insertions, 287 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1032a16bd186..72d06e302e99 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7189,6 +7189,7 @@ static void perf_event_mmap_output(struct perf_event *event,
7189 struct perf_output_handle handle; 7189 struct perf_output_handle handle;
7190 struct perf_sample_data sample; 7190 struct perf_sample_data sample;
7191 int size = mmap_event->event_id.header.size; 7191 int size = mmap_event->event_id.header.size;
7192 u32 type = mmap_event->event_id.header.type;
7192 int ret; 7193 int ret;
7193 7194
7194 if (!perf_event_mmap_match(event, data)) 7195 if (!perf_event_mmap_match(event, data))
@@ -7232,6 +7233,7 @@ static void perf_event_mmap_output(struct perf_event *event,
7232 perf_output_end(&handle); 7233 perf_output_end(&handle);
7233out: 7234out:
7234 mmap_event->event_id.header.size = size; 7235 mmap_event->event_id.header.size = size;
7236 mmap_event->event_id.header.type = type;
7235} 7237}
7236 7238
7237static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) 7239static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
diff --git a/tools/arch/arm64/include/uapi/asm/unistd.h b/tools/arch/arm64/include/uapi/asm/unistd.h
index dae1584cf017..4703d218663a 100644
--- a/tools/arch/arm64/include/uapi/asm/unistd.h
+++ b/tools/arch/arm64/include/uapi/asm/unistd.h
@@ -17,5 +17,7 @@
17 17
18#define __ARCH_WANT_RENAMEAT 18#define __ARCH_WANT_RENAMEAT
19#define __ARCH_WANT_NEW_STAT 19#define __ARCH_WANT_NEW_STAT
20#define __ARCH_WANT_SET_GET_RLIMIT
21#define __ARCH_WANT_TIME32_SYSCALLS
20 22
21#include <asm-generic/unistd.h> 23#include <asm-generic/unistd.h>
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index d90127298f12..12cdf611d217 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -38,8 +38,10 @@ __SYSCALL(__NR_io_destroy, sys_io_destroy)
38__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit) 38__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
39#define __NR_io_cancel 3 39#define __NR_io_cancel 3
40__SYSCALL(__NR_io_cancel, sys_io_cancel) 40__SYSCALL(__NR_io_cancel, sys_io_cancel)
41#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
41#define __NR_io_getevents 4 42#define __NR_io_getevents 4
42__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents) 43__SC_3264(__NR_io_getevents, sys_io_getevents_time32, sys_io_getevents)
44#endif
43 45
44/* fs/xattr.c */ 46/* fs/xattr.c */
45#define __NR_setxattr 5 47#define __NR_setxattr 5
@@ -179,7 +181,7 @@ __SYSCALL(__NR_fchownat, sys_fchownat)
179#define __NR_fchown 55 181#define __NR_fchown 55
180__SYSCALL(__NR_fchown, sys_fchown) 182__SYSCALL(__NR_fchown, sys_fchown)
181#define __NR_openat 56 183#define __NR_openat 56
182__SC_COMP(__NR_openat, sys_openat, compat_sys_openat) 184__SYSCALL(__NR_openat, sys_openat)
183#define __NR_close 57 185#define __NR_close 57
184__SYSCALL(__NR_close, sys_close) 186__SYSCALL(__NR_close, sys_close)
185#define __NR_vhangup 58 187#define __NR_vhangup 58
@@ -222,10 +224,12 @@ __SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
222__SYSCALL(__NR3264_sendfile, sys_sendfile64) 224__SYSCALL(__NR3264_sendfile, sys_sendfile64)
223 225
224/* fs/select.c */ 226/* fs/select.c */
227#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
225#define __NR_pselect6 72 228#define __NR_pselect6 72
226__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6) 229__SC_COMP_3264(__NR_pselect6, sys_pselect6_time32, sys_pselect6, compat_sys_pselect6_time32)
227#define __NR_ppoll 73 230#define __NR_ppoll 73
228__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll) 231__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32)
232#endif
229 233
230/* fs/signalfd.c */ 234/* fs/signalfd.c */
231#define __NR_signalfd4 74 235#define __NR_signalfd4 74
@@ -269,16 +273,20 @@ __SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
269/* fs/timerfd.c */ 273/* fs/timerfd.c */
270#define __NR_timerfd_create 85 274#define __NR_timerfd_create 85
271__SYSCALL(__NR_timerfd_create, sys_timerfd_create) 275__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
276#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
272#define __NR_timerfd_settime 86 277#define __NR_timerfd_settime 86
273__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \ 278__SC_3264(__NR_timerfd_settime, sys_timerfd_settime32, \
274 compat_sys_timerfd_settime) 279 sys_timerfd_settime)
275#define __NR_timerfd_gettime 87 280#define __NR_timerfd_gettime 87
276__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \ 281__SC_3264(__NR_timerfd_gettime, sys_timerfd_gettime32, \
277 compat_sys_timerfd_gettime) 282 sys_timerfd_gettime)
283#endif
278 284
279/* fs/utimes.c */ 285/* fs/utimes.c */
286#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
280#define __NR_utimensat 88 287#define __NR_utimensat 88
281__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat) 288__SC_3264(__NR_utimensat, sys_utimensat_time32, sys_utimensat)
289#endif
282 290
283/* kernel/acct.c */ 291/* kernel/acct.c */
284#define __NR_acct 89 292#define __NR_acct 89
@@ -309,8 +317,10 @@ __SYSCALL(__NR_set_tid_address, sys_set_tid_address)
309__SYSCALL(__NR_unshare, sys_unshare) 317__SYSCALL(__NR_unshare, sys_unshare)
310 318
311/* kernel/futex.c */ 319/* kernel/futex.c */
320#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
312#define __NR_futex 98 321#define __NR_futex 98
313__SC_COMP(__NR_futex, sys_futex, compat_sys_futex) 322__SC_3264(__NR_futex, sys_futex_time32, sys_futex)
323#endif
314#define __NR_set_robust_list 99 324#define __NR_set_robust_list 99
315__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \ 325__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
316 compat_sys_set_robust_list) 326 compat_sys_set_robust_list)
@@ -319,8 +329,10 @@ __SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
319 compat_sys_get_robust_list) 329 compat_sys_get_robust_list)
320 330
321/* kernel/hrtimer.c */ 331/* kernel/hrtimer.c */
332#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
322#define __NR_nanosleep 101 333#define __NR_nanosleep 101
323__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep) 334__SC_3264(__NR_nanosleep, sys_nanosleep_time32, sys_nanosleep)
335#endif
324 336
325/* kernel/itimer.c */ 337/* kernel/itimer.c */
326#define __NR_getitimer 102 338#define __NR_getitimer 102
@@ -341,23 +353,29 @@ __SYSCALL(__NR_delete_module, sys_delete_module)
341/* kernel/posix-timers.c */ 353/* kernel/posix-timers.c */
342#define __NR_timer_create 107 354#define __NR_timer_create 107
343__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create) 355__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
356#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
344#define __NR_timer_gettime 108 357#define __NR_timer_gettime 108
345__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime) 358__SC_3264(__NR_timer_gettime, sys_timer_gettime32, sys_timer_gettime)
359#endif
346#define __NR_timer_getoverrun 109 360#define __NR_timer_getoverrun 109
347__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) 361__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
362#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
348#define __NR_timer_settime 110 363#define __NR_timer_settime 110
349__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime) 364__SC_3264(__NR_timer_settime, sys_timer_settime32, sys_timer_settime)
365#endif
350#define __NR_timer_delete 111 366#define __NR_timer_delete 111
351__SYSCALL(__NR_timer_delete, sys_timer_delete) 367__SYSCALL(__NR_timer_delete, sys_timer_delete)
368#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
352#define __NR_clock_settime 112 369#define __NR_clock_settime 112
353__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime) 370__SC_3264(__NR_clock_settime, sys_clock_settime32, sys_clock_settime)
354#define __NR_clock_gettime 113 371#define __NR_clock_gettime 113
355__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime) 372__SC_3264(__NR_clock_gettime, sys_clock_gettime32, sys_clock_gettime)
356#define __NR_clock_getres 114 373#define __NR_clock_getres 114
357__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres) 374__SC_3264(__NR_clock_getres, sys_clock_getres_time32, sys_clock_getres)
358#define __NR_clock_nanosleep 115 375#define __NR_clock_nanosleep 115
359__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \ 376__SC_3264(__NR_clock_nanosleep, sys_clock_nanosleep_time32, \
360 compat_sys_clock_nanosleep) 377 sys_clock_nanosleep)
378#endif
361 379
362/* kernel/printk.c */ 380/* kernel/printk.c */
363#define __NR_syslog 116 381#define __NR_syslog 116
@@ -388,9 +406,11 @@ __SYSCALL(__NR_sched_yield, sys_sched_yield)
388__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) 406__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
389#define __NR_sched_get_priority_min 126 407#define __NR_sched_get_priority_min 126
390__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) 408__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
409#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
391#define __NR_sched_rr_get_interval 127 410#define __NR_sched_rr_get_interval 127
392__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \ 411__SC_3264(__NR_sched_rr_get_interval, sys_sched_rr_get_interval_time32, \
393 compat_sys_sched_rr_get_interval) 412 sys_sched_rr_get_interval)
413#endif
394 414
395/* kernel/signal.c */ 415/* kernel/signal.c */
396#define __NR_restart_syscall 128 416#define __NR_restart_syscall 128
@@ -411,9 +431,11 @@ __SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
411__SC_COMP(__NR_rt_sigprocmask, sys_rt_sigprocmask, compat_sys_rt_sigprocmask) 431__SC_COMP(__NR_rt_sigprocmask, sys_rt_sigprocmask, compat_sys_rt_sigprocmask)
412#define __NR_rt_sigpending 136 432#define __NR_rt_sigpending 136
413__SC_COMP(__NR_rt_sigpending, sys_rt_sigpending, compat_sys_rt_sigpending) 433__SC_COMP(__NR_rt_sigpending, sys_rt_sigpending, compat_sys_rt_sigpending)
434#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
414#define __NR_rt_sigtimedwait 137 435#define __NR_rt_sigtimedwait 137
415__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \ 436__SC_COMP_3264(__NR_rt_sigtimedwait, sys_rt_sigtimedwait_time32, \
416 compat_sys_rt_sigtimedwait) 437 sys_rt_sigtimedwait, compat_sys_rt_sigtimedwait_time32)
438#endif
417#define __NR_rt_sigqueueinfo 138 439#define __NR_rt_sigqueueinfo 138
418__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \ 440__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
419 compat_sys_rt_sigqueueinfo) 441 compat_sys_rt_sigqueueinfo)
@@ -467,10 +489,15 @@ __SYSCALL(__NR_uname, sys_newuname)
467__SYSCALL(__NR_sethostname, sys_sethostname) 489__SYSCALL(__NR_sethostname, sys_sethostname)
468#define __NR_setdomainname 162 490#define __NR_setdomainname 162
469__SYSCALL(__NR_setdomainname, sys_setdomainname) 491__SYSCALL(__NR_setdomainname, sys_setdomainname)
492
493#ifdef __ARCH_WANT_SET_GET_RLIMIT
494/* getrlimit and setrlimit are superseded with prlimit64 */
470#define __NR_getrlimit 163 495#define __NR_getrlimit 163
471__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit) 496__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
472#define __NR_setrlimit 164 497#define __NR_setrlimit 164
473__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit) 498__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
499#endif
500
474#define __NR_getrusage 165 501#define __NR_getrusage 165
475__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage) 502__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
476#define __NR_umask 166 503#define __NR_umask 166
@@ -481,12 +508,14 @@ __SYSCALL(__NR_prctl, sys_prctl)
481__SYSCALL(__NR_getcpu, sys_getcpu) 508__SYSCALL(__NR_getcpu, sys_getcpu)
482 509
483/* kernel/time.c */ 510/* kernel/time.c */
511#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
484#define __NR_gettimeofday 169 512#define __NR_gettimeofday 169
485__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday) 513__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
486#define __NR_settimeofday 170 514#define __NR_settimeofday 170
487__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday) 515__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
488#define __NR_adjtimex 171 516#define __NR_adjtimex 171
489__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex) 517__SC_3264(__NR_adjtimex, sys_adjtimex_time32, sys_adjtimex)
518#endif
490 519
491/* kernel/timer.c */ 520/* kernel/timer.c */
492#define __NR_getpid 172 521#define __NR_getpid 172
@@ -511,11 +540,13 @@ __SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
511__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open) 540__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
512#define __NR_mq_unlink 181 541#define __NR_mq_unlink 181
513__SYSCALL(__NR_mq_unlink, sys_mq_unlink) 542__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
543#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
514#define __NR_mq_timedsend 182 544#define __NR_mq_timedsend 182
515__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend) 545__SC_3264(__NR_mq_timedsend, sys_mq_timedsend_time32, sys_mq_timedsend)
516#define __NR_mq_timedreceive 183 546#define __NR_mq_timedreceive 183
517__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \ 547__SC_3264(__NR_mq_timedreceive, sys_mq_timedreceive_time32, \
518 compat_sys_mq_timedreceive) 548 sys_mq_timedreceive)
549#endif
519#define __NR_mq_notify 184 550#define __NR_mq_notify 184
520__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify) 551__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
521#define __NR_mq_getsetattr 185 552#define __NR_mq_getsetattr 185
@@ -536,8 +567,10 @@ __SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
536__SYSCALL(__NR_semget, sys_semget) 567__SYSCALL(__NR_semget, sys_semget)
537#define __NR_semctl 191 568#define __NR_semctl 191
538__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl) 569__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
570#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
539#define __NR_semtimedop 192 571#define __NR_semtimedop 192
540__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop) 572__SC_COMP(__NR_semtimedop, sys_semtimedop, sys_semtimedop_time32)
573#endif
541#define __NR_semop 193 574#define __NR_semop 193
542__SYSCALL(__NR_semop, sys_semop) 575__SYSCALL(__NR_semop, sys_semop)
543 576
@@ -658,8 +691,10 @@ __SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
658__SYSCALL(__NR_perf_event_open, sys_perf_event_open) 691__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
659#define __NR_accept4 242 692#define __NR_accept4 242
660__SYSCALL(__NR_accept4, sys_accept4) 693__SYSCALL(__NR_accept4, sys_accept4)
694#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
661#define __NR_recvmmsg 243 695#define __NR_recvmmsg 243
662__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg) 696__SC_COMP_3264(__NR_recvmmsg, sys_recvmmsg_time32, sys_recvmmsg, compat_sys_recvmmsg_time32)
697#endif
663 698
664/* 699/*
665 * Architectures may provide up to 16 syscalls of their own 700 * Architectures may provide up to 16 syscalls of their own
@@ -667,8 +702,10 @@ __SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
667 */ 702 */
668#define __NR_arch_specific_syscall 244 703#define __NR_arch_specific_syscall 244
669 704
705#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
670#define __NR_wait4 260 706#define __NR_wait4 260
671__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4) 707__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
708#endif
672#define __NR_prlimit64 261 709#define __NR_prlimit64 261
673__SYSCALL(__NR_prlimit64, sys_prlimit64) 710__SYSCALL(__NR_prlimit64, sys_prlimit64)
674#define __NR_fanotify_init 262 711#define __NR_fanotify_init 262
@@ -678,10 +715,11 @@ __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
678#define __NR_name_to_handle_at 264 715#define __NR_name_to_handle_at 264
679__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) 716__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
680#define __NR_open_by_handle_at 265 717#define __NR_open_by_handle_at 265
681__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \ 718__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
682 compat_sys_open_by_handle_at) 719#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
683#define __NR_clock_adjtime 266 720#define __NR_clock_adjtime 266
684__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) 721__SC_3264(__NR_clock_adjtime, sys_clock_adjtime32, sys_clock_adjtime)
722#endif
685#define __NR_syncfs 267 723#define __NR_syncfs 267
686__SYSCALL(__NR_syncfs, sys_syncfs) 724__SYSCALL(__NR_syncfs, sys_syncfs)
687#define __NR_setns 268 725#define __NR_setns 268
@@ -734,15 +772,60 @@ __SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
734__SYSCALL(__NR_pkey_free, sys_pkey_free) 772__SYSCALL(__NR_pkey_free, sys_pkey_free)
735#define __NR_statx 291 773#define __NR_statx 291
736__SYSCALL(__NR_statx, sys_statx) 774__SYSCALL(__NR_statx, sys_statx)
775#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
737#define __NR_io_pgetevents 292 776#define __NR_io_pgetevents 292
738__SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents) 777__SC_COMP_3264(__NR_io_pgetevents, sys_io_pgetevents_time32, sys_io_pgetevents, compat_sys_io_pgetevents)
778#endif
739#define __NR_rseq 293 779#define __NR_rseq 293
740__SYSCALL(__NR_rseq, sys_rseq) 780__SYSCALL(__NR_rseq, sys_rseq)
741#define __NR_kexec_file_load 294 781#define __NR_kexec_file_load 294
742__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load) 782__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load)
783/* 295 through 402 are unassigned to sync up with generic numbers, don't use */
784#if __BITS_PER_LONG == 32
785#define __NR_clock_gettime64 403
786__SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
787#define __NR_clock_settime64 404
788__SYSCALL(__NR_clock_settime64, sys_clock_settime)
789#define __NR_clock_adjtime64 405
790__SYSCALL(__NR_clock_adjtime64, sys_clock_adjtime)
791#define __NR_clock_getres_time64 406
792__SYSCALL(__NR_clock_getres_time64, sys_clock_getres)
793#define __NR_clock_nanosleep_time64 407
794__SYSCALL(__NR_clock_nanosleep_time64, sys_clock_nanosleep)
795#define __NR_timer_gettime64 408
796__SYSCALL(__NR_timer_gettime64, sys_timer_gettime)
797#define __NR_timer_settime64 409
798__SYSCALL(__NR_timer_settime64, sys_timer_settime)
799#define __NR_timerfd_gettime64 410
800__SYSCALL(__NR_timerfd_gettime64, sys_timerfd_gettime)
801#define __NR_timerfd_settime64 411
802__SYSCALL(__NR_timerfd_settime64, sys_timerfd_settime)
803#define __NR_utimensat_time64 412
804__SYSCALL(__NR_utimensat_time64, sys_utimensat)
805#define __NR_pselect6_time64 413
806__SC_COMP(__NR_pselect6_time64, sys_pselect6, compat_sys_pselect6_time64)
807#define __NR_ppoll_time64 414
808__SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64)
809#define __NR_io_pgetevents_time64 416
810__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents)
811#define __NR_recvmmsg_time64 417
812__SC_COMP(__NR_recvmmsg_time64, sys_recvmmsg, compat_sys_recvmmsg_time64)
813#define __NR_mq_timedsend_time64 418
814__SYSCALL(__NR_mq_timedsend_time64, sys_mq_timedsend)
815#define __NR_mq_timedreceive_time64 419
816__SYSCALL(__NR_mq_timedreceive_time64, sys_mq_timedreceive)
817#define __NR_semtimedop_time64 420
818__SYSCALL(__NR_semtimedop_time64, sys_semtimedop)
819#define __NR_rt_sigtimedwait_time64 421
820__SC_COMP(__NR_rt_sigtimedwait_time64, sys_rt_sigtimedwait, compat_sys_rt_sigtimedwait_time64)
821#define __NR_futex_time64 422
822__SYSCALL(__NR_futex_time64, sys_futex)
823#define __NR_sched_rr_get_interval_time64 423
824__SYSCALL(__NR_sched_rr_get_interval_time64, sys_sched_rr_get_interval)
825#endif
743 826
744#undef __NR_syscalls 827#undef __NR_syscalls
745#define __NR_syscalls 295 828#define __NR_syscalls 424
746 829
747/* 830/*
748 * 32 bit systems traditionally used different 831 * 32 bit systems traditionally used different
diff --git a/tools/include/uapi/linux/in.h b/tools/include/uapi/linux/in.h
index a55cb8b10165..e7ad9d350a28 100644
--- a/tools/include/uapi/linux/in.h
+++ b/tools/include/uapi/linux/in.h
@@ -292,10 +292,11 @@ struct sockaddr_in {
292#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000) 292#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
293 293
294/* Defines for Multicast INADDR */ 294/* Defines for Multicast INADDR */
295#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */ 295#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */
296#define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */ 296#define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */
297#define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */ 297#define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */
298#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */ 298#define INADDR_ALLSNOOPERS_GROUP 0xe000006aU /* 224.0.0.106 */
299#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */
299#endif 300#endif
300 301
301/* <asm/byteorder.h> contains the htonl type stuff.. */ 302/* <asm/byteorder.h> contains the htonl type stuff.. */
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index b4652aa1a58a..aa1521a51687 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -10,6 +10,7 @@
10#ifndef __LIBBPF_LIBBPF_H 10#ifndef __LIBBPF_LIBBPF_H
11#define __LIBBPF_LIBBPF_H 11#define __LIBBPF_LIBBPF_H
12 12
13#include <stdarg.h>
13#include <stdio.h> 14#include <stdio.h>
14#include <stdint.h> 15#include <stdint.h>
15#include <stdbool.h> 16#include <stdbool.h>
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 86f3dcc15f83..95054a8176a2 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -584,6 +584,20 @@ llvm.*::
584 llvm.opts:: 584 llvm.opts::
585 Options passed to llc. 585 Options passed to llc.
586 586
587samples.*::
588
589 samples.context::
590 Define how many ns worth of time to show
591 around samples in perf report sample context browser.
592
593scripts.*::
594
595 Any option defines a script that is added to the scripts menu
596 in the interactive perf browser and whose output is displayed.
597 The name of the option is the name, the value is a script command line.
598 The script gets the same options passed as a full perf script,
599 in particular -i perfdata file, --cpu, --tid
600
587SEE ALSO 601SEE ALSO
588-------- 602--------
589linkperf:perf[1] 603linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 1a27bfe05039..f441baa794ce 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -105,6 +105,8 @@ OPTIONS
105 guest machine 105 guest machine
106 - sample: Number of sample 106 - sample: Number of sample
107 - period: Raw number of event count of sample 107 - period: Raw number of event count of sample
108 - time: Separate the samples by time stamp with the resolution specified by
109 --time-quantum (default 100ms). Specify with overhead and before it.
108 110
109 By default, comm, dso and symbol keys are used. 111 By default, comm, dso and symbol keys are used.
110 (i.e. --sort comm,dso,symbol) 112 (i.e. --sort comm,dso,symbol)
@@ -459,6 +461,10 @@ include::itrace.txt[]
459--socket-filter:: 461--socket-filter::
460 Only report the samples on the processor socket that match with this filter 462 Only report the samples on the processor socket that match with this filter
461 463
464--samples=N::
465 Save N individual samples for each histogram entry to show context in perf
466 report tui browser.
467
462--raw-trace:: 468--raw-trace::
463 When displaying traceevent output, do not use print fmt or plugins. 469 When displaying traceevent output, do not use print fmt or plugins.
464 470
@@ -477,6 +483,9 @@ include::itrace.txt[]
477 Please note that not all mmaps are stored, options affecting which ones 483 Please note that not all mmaps are stored, options affecting which ones
478 are include 'perf record --data', for instance. 484 are include 'perf record --data', for instance.
479 485
486--ns::
487 Show time stamps in nanoseconds.
488
480--stats:: 489--stats::
481 Display overall events statistics without any further processing. 490 Display overall events statistics without any further processing.
482 (like the one at the end of the perf report -D command) 491 (like the one at the end of the perf report -D command)
@@ -494,6 +503,10 @@ include::itrace.txt[]
494 The period/hits keywords set the base the percentage is computed 503 The period/hits keywords set the base the percentage is computed
495 on - the samples period or the number of samples (hits). 504 on - the samples period or the number of samples (hits).
496 505
506--time-quantum::
507 Configure time quantum for time sort key. Default 100ms.
508 Accepts s, us, ms, ns units.
509
497include::callchain-overhead-calculation.txt[] 510include::callchain-overhead-calculation.txt[]
498 511
499SEE ALSO 512SEE ALSO
diff --git a/tools/perf/Documentation/tips.txt b/tools/perf/Documentation/tips.txt
index 849599f39c5e..869965d629ce 100644
--- a/tools/perf/Documentation/tips.txt
+++ b/tools/perf/Documentation/tips.txt
@@ -15,6 +15,7 @@ To see callchains in a more compact form: perf report -g folded
15Show individual samples with: perf script 15Show individual samples with: perf script
16Limit to show entries above 5% only: perf report --percent-limit 5 16Limit to show entries above 5% only: perf report --percent-limit 5
17Profiling branch (mis)predictions with: perf record -b / perf report 17Profiling branch (mis)predictions with: perf record -b / perf report
18To show assembler sample contexts use perf record -b / perf script -F +brstackinsn --xed
18Treat branches as callchains: perf report --branch-history 19Treat branches as callchains: perf report --branch-history
19To count events in every 1000 msec: perf stat -I 1000 20To count events in every 1000 msec: perf stat -I 1000
20Print event counts in CSV format with: perf stat -x, 21Print event counts in CSV format with: perf stat -x,
@@ -34,3 +35,9 @@ Show current config key-value pairs: perf config --list
34Show user configuration overrides: perf config --user --list 35Show user configuration overrides: perf config --user --list
35To add Node.js USDT(User-Level Statically Defined Tracing): perf buildid-cache --add `which node` 36To add Node.js USDT(User-Level Statically Defined Tracing): perf buildid-cache --add `which node`
36To report cacheline events from previous recording: perf c2c report 37To report cacheline events from previous recording: perf c2c report
38To browse sample contexts use perf report --sample 10 and select in context menu
39To separate samples by time use perf report --sort time,overhead,sym
40To set sample time separation other than 100ms with --sort time use --time-quantum
41Add -I to perf report to sample register values visible in perf report context.
42To show IPC for sampling periods use perf record -e '{cycles,instructions}:S' and then browse context
43To show context switches in perf report sample context add --switch-events to perf record.
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
index f0b1709a5ffb..2ae92fddb6d5 100644
--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -343,6 +343,8 @@
343332 common statx __x64_sys_statx 343332 common statx __x64_sys_statx
344333 common io_pgetevents __x64_sys_io_pgetevents 344333 common io_pgetevents __x64_sys_io_pgetevents
345334 common rseq __x64_sys_rseq 345334 common rseq __x64_sys_rseq
346# don't use numbers 387 through 423, add new calls after the last
347# 'common' entry
346 348
347# 349#
348# x32-specific system call numbers start at 512 to avoid cache impact 350# x32-specific system call numbers start at 512 to avoid cache impact
@@ -361,7 +363,7 @@
361520 x32 execve __x32_compat_sys_execve/ptregs 363520 x32 execve __x32_compat_sys_execve/ptregs
362521 x32 ptrace __x32_compat_sys_ptrace 364521 x32 ptrace __x32_compat_sys_ptrace
363522 x32 rt_sigpending __x32_compat_sys_rt_sigpending 365522 x32 rt_sigpending __x32_compat_sys_rt_sigpending
364523 x32 rt_sigtimedwait __x32_compat_sys_rt_sigtimedwait 366523 x32 rt_sigtimedwait __x32_compat_sys_rt_sigtimedwait_time64
365524 x32 rt_sigqueueinfo __x32_compat_sys_rt_sigqueueinfo 367524 x32 rt_sigqueueinfo __x32_compat_sys_rt_sigqueueinfo
366525 x32 sigaltstack __x32_compat_sys_sigaltstack 368525 x32 sigaltstack __x32_compat_sys_sigaltstack
367526 x32 timer_create __x32_compat_sys_timer_create 369526 x32 timer_create __x32_compat_sys_timer_create
@@ -375,7 +377,7 @@
375534 x32 preadv __x32_compat_sys_preadv64 377534 x32 preadv __x32_compat_sys_preadv64
376535 x32 pwritev __x32_compat_sys_pwritev64 378535 x32 pwritev __x32_compat_sys_pwritev64
377536 x32 rt_tgsigqueueinfo __x32_compat_sys_rt_tgsigqueueinfo 379536 x32 rt_tgsigqueueinfo __x32_compat_sys_rt_tgsigqueueinfo
378537 x32 recvmmsg __x32_compat_sys_recvmmsg 380537 x32 recvmmsg __x32_compat_sys_recvmmsg_time64
379538 x32 sendmmsg __x32_compat_sys_sendmmsg 381538 x32 sendmmsg __x32_compat_sys_sendmmsg
380539 x32 process_vm_readv __x32_compat_sys_process_vm_readv 382539 x32 process_vm_readv __x32_compat_sys_process_vm_readv
381540 x32 process_vm_writev __x32_compat_sys_process_vm_writev 383540 x32 process_vm_writev __x32_compat_sys_process_vm_writev
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index 7aab0be5fc5f..47f9c56e744f 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -14,5 +14,6 @@ perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
14perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o 14perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
15 15
16perf-$(CONFIG_AUXTRACE) += auxtrace.o 16perf-$(CONFIG_AUXTRACE) += auxtrace.o
17perf-$(CONFIG_AUXTRACE) += archinsn.o
17perf-$(CONFIG_AUXTRACE) += intel-pt.o 18perf-$(CONFIG_AUXTRACE) += intel-pt.o
18perf-$(CONFIG_AUXTRACE) += intel-bts.o 19perf-$(CONFIG_AUXTRACE) += intel-bts.o
diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c
new file mode 100644
index 000000000000..4237bb2e7fa2
--- /dev/null
+++ b/tools/perf/arch/x86/util/archinsn.c
@@ -0,0 +1,26 @@
1// SPDX-License-Identifier: GPL-2.0
2#include "perf.h"
3#include "archinsn.h"
4#include "util/intel-pt-decoder/insn.h"
5#include "machine.h"
6#include "thread.h"
7#include "symbol.h"
8
9void arch_fetch_insn(struct perf_sample *sample,
10 struct thread *thread,
11 struct machine *machine)
12{
13 struct insn insn;
14 int len;
15 bool is64bit = false;
16
17 if (!sample->ip)
18 return;
19 len = thread__memcpy(thread, machine, sample->insn, sample->ip, sizeof(sample->insn), &is64bit);
20 if (len <= 0)
21 return;
22 insn_init(&insn, sample->insn, len, is64bit);
23 insn_get_length(&insn);
24 if (insn_complete(&insn) && insn.length <= len)
25 sample->insn_len = insn.length;
26}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f3f7f3100336..a468d882e74f 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -392,7 +392,7 @@ static int record__process_auxtrace(struct perf_tool *tool,
392 size_t padding; 392 size_t padding;
393 u8 pad[8] = {0}; 393 u8 pad[8] = {0};
394 394
395 if (!perf_data__is_pipe(data)) { 395 if (!perf_data__is_pipe(data) && !perf_data__is_dir(data)) {
396 off_t file_offset; 396 off_t file_offset;
397 int fd = perf_data__fd(data); 397 int fd = perf_data__fd(data);
398 int err; 398 int err;
@@ -837,6 +837,8 @@ static void record__init_features(struct record *rec)
837 if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns)) 837 if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns))
838 perf_header__clear_feat(&session->header, HEADER_CLOCKID); 838 perf_header__clear_feat(&session->header, HEADER_CLOCKID);
839 839
840 perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
841
840 perf_header__clear_feat(&session->header, HEADER_STAT); 842 perf_header__clear_feat(&session->header, HEADER_STAT);
841} 843}
842 844
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index ee93c18a6685..1921aaa9cece 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -47,9 +47,11 @@
47#include <errno.h> 47#include <errno.h>
48#include <inttypes.h> 48#include <inttypes.h>
49#include <regex.h> 49#include <regex.h>
50#include "sane_ctype.h"
50#include <signal.h> 51#include <signal.h>
51#include <linux/bitmap.h> 52#include <linux/bitmap.h>
52#include <linux/stringify.h> 53#include <linux/stringify.h>
54#include <linux/time64.h>
53#include <sys/types.h> 55#include <sys/types.h>
54#include <sys/stat.h> 56#include <sys/stat.h>
55#include <unistd.h> 57#include <unistd.h>
@@ -926,6 +928,43 @@ report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
926 return parse_callchain_report_opt(arg); 928 return parse_callchain_report_opt(arg);
927} 929}
928 930
931static int
932parse_time_quantum(const struct option *opt, const char *arg,
933 int unset __maybe_unused)
934{
935 unsigned long *time_q = opt->value;
936 char *end;
937
938 *time_q = strtoul(arg, &end, 0);
939 if (end == arg)
940 goto parse_err;
941 if (*time_q == 0) {
942 pr_err("time quantum cannot be 0");
943 return -1;
944 }
945 while (isspace(*end))
946 end++;
947 if (*end == 0)
948 return 0;
949 if (!strcmp(end, "s")) {
950 *time_q *= NSEC_PER_SEC;
951 return 0;
952 }
953 if (!strcmp(end, "ms")) {
954 *time_q *= NSEC_PER_MSEC;
955 return 0;
956 }
957 if (!strcmp(end, "us")) {
958 *time_q *= NSEC_PER_USEC;
959 return 0;
960 }
961 if (!strcmp(end, "ns"))
962 return 0;
963parse_err:
964 pr_err("Cannot parse time quantum `%s'\n", arg);
965 return -1;
966}
967
929int 968int
930report_parse_ignore_callees_opt(const struct option *opt __maybe_unused, 969report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
931 const char *arg, int unset __maybe_unused) 970 const char *arg, int unset __maybe_unused)
@@ -1120,6 +1159,8 @@ int cmd_report(int argc, const char **argv)
1120 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 1159 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1121 "Enable kernel symbol demangling"), 1160 "Enable kernel symbol demangling"),
1122 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), 1161 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
1162 OPT_INTEGER(0, "samples", &symbol_conf.res_sample,
1163 "Number of samples to save per histogram entry for individual browsing"),
1123 OPT_CALLBACK(0, "percent-limit", &report, "percent", 1164 OPT_CALLBACK(0, "percent-limit", &report, "percent",
1124 "Don't show entries under that percent", parse_percent_limit), 1165 "Don't show entries under that percent", parse_percent_limit),
1125 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", 1166 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
@@ -1147,6 +1188,10 @@ int cmd_report(int argc, const char **argv)
1147 OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period", 1188 OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
1148 "Set percent type local/global-period/hits", 1189 "Set percent type local/global-period/hits",
1149 annotate_parse_percent_type), 1190 annotate_parse_percent_type),
1191 OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, "Show times in nanosecs"),
1192 OPT_CALLBACK(0, "time-quantum", &symbol_conf.time_quantum, "time (ms|us|ns|s)",
1193 "Set time quantum for time sort key (default 100ms)",
1194 parse_time_quantum),
1150 OPT_END() 1195 OPT_END()
1151 }; 1196 };
1152 struct perf_data data = { 1197 struct perf_data data = {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 53f78cf3113f..2f93d60c5a17 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -29,10 +29,12 @@
29#include "util/time-utils.h" 29#include "util/time-utils.h"
30#include "util/path.h" 30#include "util/path.h"
31#include "print_binary.h" 31#include "print_binary.h"
32#include "archinsn.h"
32#include <linux/bitmap.h> 33#include <linux/bitmap.h>
33#include <linux/kernel.h> 34#include <linux/kernel.h>
34#include <linux/stringify.h> 35#include <linux/stringify.h>
35#include <linux/time64.h> 36#include <linux/time64.h>
37#include <sys/utsname.h>
36#include "asm/bug.h" 38#include "asm/bug.h"
37#include "util/mem-events.h" 39#include "util/mem-events.h"
38#include "util/dump-insn.h" 40#include "util/dump-insn.h"
@@ -58,11 +60,11 @@ static bool no_callchain;
58static bool latency_format; 60static bool latency_format;
59static bool system_wide; 61static bool system_wide;
60static bool print_flags; 62static bool print_flags;
61static bool nanosecs;
62static const char *cpu_list; 63static const char *cpu_list;
63static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 64static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
64static struct perf_stat_config stat_config; 65static struct perf_stat_config stat_config;
65static int max_blocks; 66static int max_blocks;
67static bool native_arch;
66 68
67unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; 69unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
68 70
@@ -688,7 +690,7 @@ static int perf_sample__fprintf_start(struct perf_sample *sample,
688 secs = nsecs / NSEC_PER_SEC; 690 secs = nsecs / NSEC_PER_SEC;
689 nsecs -= secs * NSEC_PER_SEC; 691 nsecs -= secs * NSEC_PER_SEC;
690 692
691 if (nanosecs) 693 if (symbol_conf.nanosecs)
692 printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs); 694 printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
693 else { 695 else {
694 char sample_time[32]; 696 char sample_time[32];
@@ -1227,6 +1229,12 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample,
1227 return len + dlen; 1229 return len + dlen;
1228} 1230}
1229 1231
1232__weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused,
1233 struct thread *thread __maybe_unused,
1234 struct machine *machine __maybe_unused)
1235{
1236}
1237
1230static int perf_sample__fprintf_insn(struct perf_sample *sample, 1238static int perf_sample__fprintf_insn(struct perf_sample *sample,
1231 struct perf_event_attr *attr, 1239 struct perf_event_attr *attr,
1232 struct thread *thread, 1240 struct thread *thread,
@@ -1234,9 +1242,12 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample,
1234{ 1242{
1235 int printed = 0; 1243 int printed = 0;
1236 1244
1245 if (sample->insn_len == 0 && native_arch)
1246 arch_fetch_insn(sample, thread, machine);
1247
1237 if (PRINT_FIELD(INSNLEN)) 1248 if (PRINT_FIELD(INSNLEN))
1238 printed += fprintf(fp, " ilen: %d", sample->insn_len); 1249 printed += fprintf(fp, " ilen: %d", sample->insn_len);
1239 if (PRINT_FIELD(INSN)) { 1250 if (PRINT_FIELD(INSN) && sample->insn_len) {
1240 int i; 1251 int i;
1241 1252
1242 printed += fprintf(fp, " insn:"); 1253 printed += fprintf(fp, " insn:");
@@ -1922,6 +1933,13 @@ static int cleanup_scripting(void)
1922 return scripting_ops ? scripting_ops->stop_script() : 0; 1933 return scripting_ops ? scripting_ops->stop_script() : 0;
1923} 1934}
1924 1935
1936static bool filter_cpu(struct perf_sample *sample)
1937{
1938 if (cpu_list)
1939 return !test_bit(sample->cpu, cpu_bitmap);
1940 return false;
1941}
1942
1925static int process_sample_event(struct perf_tool *tool, 1943static int process_sample_event(struct perf_tool *tool,
1926 union perf_event *event, 1944 union perf_event *event,
1927 struct perf_sample *sample, 1945 struct perf_sample *sample,
@@ -1956,7 +1974,7 @@ static int process_sample_event(struct perf_tool *tool,
1956 if (al.filtered) 1974 if (al.filtered)
1957 goto out_put; 1975 goto out_put;
1958 1976
1959 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 1977 if (filter_cpu(sample))
1960 goto out_put; 1978 goto out_put;
1961 1979
1962 if (scripting_ops) 1980 if (scripting_ops)
@@ -2041,9 +2059,11 @@ static int process_comm_event(struct perf_tool *tool,
2041 sample->tid = event->comm.tid; 2059 sample->tid = event->comm.tid;
2042 sample->pid = event->comm.pid; 2060 sample->pid = event->comm.pid;
2043 } 2061 }
2044 perf_sample__fprintf_start(sample, thread, evsel, 2062 if (!filter_cpu(sample)) {
2063 perf_sample__fprintf_start(sample, thread, evsel,
2045 PERF_RECORD_COMM, stdout); 2064 PERF_RECORD_COMM, stdout);
2046 perf_event__fprintf(event, stdout); 2065 perf_event__fprintf(event, stdout);
2066 }
2047 ret = 0; 2067 ret = 0;
2048out: 2068out:
2049 thread__put(thread); 2069 thread__put(thread);
@@ -2077,9 +2097,11 @@ static int process_namespaces_event(struct perf_tool *tool,
2077 sample->tid = event->namespaces.tid; 2097 sample->tid = event->namespaces.tid;
2078 sample->pid = event->namespaces.pid; 2098 sample->pid = event->namespaces.pid;
2079 } 2099 }
2080 perf_sample__fprintf_start(sample, thread, evsel, 2100 if (!filter_cpu(sample)) {
2081 PERF_RECORD_NAMESPACES, stdout); 2101 perf_sample__fprintf_start(sample, thread, evsel,
2082 perf_event__fprintf(event, stdout); 2102 PERF_RECORD_NAMESPACES, stdout);
2103 perf_event__fprintf(event, stdout);
2104 }
2083 ret = 0; 2105 ret = 0;
2084out: 2106out:
2085 thread__put(thread); 2107 thread__put(thread);
@@ -2111,9 +2133,11 @@ static int process_fork_event(struct perf_tool *tool,
2111 sample->tid = event->fork.tid; 2133 sample->tid = event->fork.tid;
2112 sample->pid = event->fork.pid; 2134 sample->pid = event->fork.pid;
2113 } 2135 }
2114 perf_sample__fprintf_start(sample, thread, evsel, 2136 if (!filter_cpu(sample)) {
2115 PERF_RECORD_FORK, stdout); 2137 perf_sample__fprintf_start(sample, thread, evsel,
2116 perf_event__fprintf(event, stdout); 2138 PERF_RECORD_FORK, stdout);
2139 perf_event__fprintf(event, stdout);
2140 }
2117 thread__put(thread); 2141 thread__put(thread);
2118 2142
2119 return 0; 2143 return 0;
@@ -2141,9 +2165,11 @@ static int process_exit_event(struct perf_tool *tool,
2141 sample->tid = event->fork.tid; 2165 sample->tid = event->fork.tid;
2142 sample->pid = event->fork.pid; 2166 sample->pid = event->fork.pid;
2143 } 2167 }
2144 perf_sample__fprintf_start(sample, thread, evsel, 2168 if (!filter_cpu(sample)) {
2145 PERF_RECORD_EXIT, stdout); 2169 perf_sample__fprintf_start(sample, thread, evsel,
2146 perf_event__fprintf(event, stdout); 2170 PERF_RECORD_EXIT, stdout);
2171 perf_event__fprintf(event, stdout);
2172 }
2147 2173
2148 if (perf_event__process_exit(tool, event, sample, machine) < 0) 2174 if (perf_event__process_exit(tool, event, sample, machine) < 0)
2149 err = -1; 2175 err = -1;
@@ -2177,9 +2203,11 @@ static int process_mmap_event(struct perf_tool *tool,
2177 sample->tid = event->mmap.tid; 2203 sample->tid = event->mmap.tid;
2178 sample->pid = event->mmap.pid; 2204 sample->pid = event->mmap.pid;
2179 } 2205 }
2180 perf_sample__fprintf_start(sample, thread, evsel, 2206 if (!filter_cpu(sample)) {
2181 PERF_RECORD_MMAP, stdout); 2207 perf_sample__fprintf_start(sample, thread, evsel,
2182 perf_event__fprintf(event, stdout); 2208 PERF_RECORD_MMAP, stdout);
2209 perf_event__fprintf(event, stdout);
2210 }
2183 thread__put(thread); 2211 thread__put(thread);
2184 return 0; 2212 return 0;
2185} 2213}
@@ -2209,9 +2237,11 @@ static int process_mmap2_event(struct perf_tool *tool,
2209 sample->tid = event->mmap2.tid; 2237 sample->tid = event->mmap2.tid;
2210 sample->pid = event->mmap2.pid; 2238 sample->pid = event->mmap2.pid;
2211 } 2239 }
2212 perf_sample__fprintf_start(sample, thread, evsel, 2240 if (!filter_cpu(sample)) {
2213 PERF_RECORD_MMAP2, stdout); 2241 perf_sample__fprintf_start(sample, thread, evsel,
2214 perf_event__fprintf(event, stdout); 2242 PERF_RECORD_MMAP2, stdout);
2243 perf_event__fprintf(event, stdout);
2244 }
2215 thread__put(thread); 2245 thread__put(thread);
2216 return 0; 2246 return 0;
2217} 2247}
@@ -2236,9 +2266,11 @@ static int process_switch_event(struct perf_tool *tool,
2236 return -1; 2266 return -1;
2237 } 2267 }
2238 2268
2239 perf_sample__fprintf_start(sample, thread, evsel, 2269 if (!filter_cpu(sample)) {
2240 PERF_RECORD_SWITCH, stdout); 2270 perf_sample__fprintf_start(sample, thread, evsel,
2241 perf_event__fprintf(event, stdout); 2271 PERF_RECORD_SWITCH, stdout);
2272 perf_event__fprintf(event, stdout);
2273 }
2242 thread__put(thread); 2274 thread__put(thread);
2243 return 0; 2275 return 0;
2244} 2276}
@@ -2259,9 +2291,11 @@ process_lost_event(struct perf_tool *tool,
2259 if (thread == NULL) 2291 if (thread == NULL)
2260 return -1; 2292 return -1;
2261 2293
2262 perf_sample__fprintf_start(sample, thread, evsel, 2294 if (!filter_cpu(sample)) {
2263 PERF_RECORD_LOST, stdout); 2295 perf_sample__fprintf_start(sample, thread, evsel,
2264 perf_event__fprintf(event, stdout); 2296 PERF_RECORD_LOST, stdout);
2297 perf_event__fprintf(event, stdout);
2298 }
2265 thread__put(thread); 2299 thread__put(thread);
2266 return 0; 2300 return 0;
2267} 2301}
@@ -2948,7 +2982,8 @@ static int check_ev_match(char *dir_name, char *scriptname,
2948 * will list all statically runnable scripts, select one, execute it and 2982 * will list all statically runnable scripts, select one, execute it and
2949 * show the output in a perf browser. 2983 * show the output in a perf browser.
2950 */ 2984 */
2951int find_scripts(char **scripts_array, char **scripts_path_array) 2985int find_scripts(char **scripts_array, char **scripts_path_array, int num,
2986 int pathlen)
2952{ 2987{
2953 struct dirent *script_dirent, *lang_dirent; 2988 struct dirent *script_dirent, *lang_dirent;
2954 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 2989 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
@@ -2993,7 +3028,10 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
2993 /* Skip those real time scripts: xxxtop.p[yl] */ 3028 /* Skip those real time scripts: xxxtop.p[yl] */
2994 if (strstr(script_dirent->d_name, "top.")) 3029 if (strstr(script_dirent->d_name, "top."))
2995 continue; 3030 continue;
2996 sprintf(scripts_path_array[i], "%s/%s", lang_path, 3031 if (i >= num)
3032 break;
3033 snprintf(scripts_path_array[i], pathlen, "%s/%s",
3034 lang_path,
2997 script_dirent->d_name); 3035 script_dirent->d_name);
2998 temp = strchr(script_dirent->d_name, '.'); 3036 temp = strchr(script_dirent->d_name, '.');
2999 snprintf(scripts_array[i], 3037 snprintf(scripts_array[i],
@@ -3232,7 +3270,7 @@ static int parse_insn_trace(const struct option *opt __maybe_unused,
3232{ 3270{
3233 parse_output_fields(NULL, "+insn,-event,-period", 0); 3271 parse_output_fields(NULL, "+insn,-event,-period", 0);
3234 itrace_parse_synth_opts(opt, "i0ns", 0); 3272 itrace_parse_synth_opts(opt, "i0ns", 0);
3235 nanosecs = true; 3273 symbol_conf.nanosecs = true;
3236 return 0; 3274 return 0;
3237} 3275}
3238 3276
@@ -3250,7 +3288,7 @@ static int parse_call_trace(const struct option *opt __maybe_unused,
3250{ 3288{
3251 parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0); 3289 parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);
3252 itrace_parse_synth_opts(opt, "cewp", 0); 3290 itrace_parse_synth_opts(opt, "cewp", 0);
3253 nanosecs = true; 3291 symbol_conf.nanosecs = true;
3254 return 0; 3292 return 0;
3255} 3293}
3256 3294
@@ -3260,7 +3298,7 @@ static int parse_callret_trace(const struct option *opt __maybe_unused,
3260{ 3298{
3261 parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0); 3299 parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0);
3262 itrace_parse_synth_opts(opt, "crewp", 0); 3300 itrace_parse_synth_opts(opt, "crewp", 0);
3263 nanosecs = true; 3301 symbol_conf.nanosecs = true;
3264 return 0; 3302 return 0;
3265} 3303}
3266 3304
@@ -3277,6 +3315,7 @@ int cmd_script(int argc, const char **argv)
3277 .set = false, 3315 .set = false,
3278 .default_no_sample = true, 3316 .default_no_sample = true,
3279 }; 3317 };
3318 struct utsname uts;
3280 char *script_path = NULL; 3319 char *script_path = NULL;
3281 const char **__argv; 3320 const char **__argv;
3282 int i, j, err = 0; 3321 int i, j, err = 0;
@@ -3395,7 +3434,7 @@ int cmd_script(int argc, const char **argv)
3395 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), 3434 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
3396 OPT_INTEGER(0, "max-blocks", &max_blocks, 3435 OPT_INTEGER(0, "max-blocks", &max_blocks,
3397 "Maximum number of code blocks to dump with brstackinsn"), 3436 "Maximum number of code blocks to dump with brstackinsn"),
3398 OPT_BOOLEAN(0, "ns", &nanosecs, 3437 OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs,
3399 "Use 9 decimal places when displaying time"), 3438 "Use 9 decimal places when displaying time"),
3400 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 3439 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3401 "Instruction Tracing options\n" ITRACE_HELP, 3440 "Instruction Tracing options\n" ITRACE_HELP,
@@ -3615,6 +3654,12 @@ int cmd_script(int argc, const char **argv)
3615 if (symbol__init(&session->header.env) < 0) 3654 if (symbol__init(&session->header.env) < 0)
3616 goto out_delete; 3655 goto out_delete;
3617 3656
3657 uname(&uts);
3658 if (!strcmp(uts.machine, session->header.env.arch) ||
3659 (!strcmp(uts.machine, "x86_64") &&
3660 !strcmp(session->header.env.arch, "i386")))
3661 native_arch = true;
3662
3618 script.session = session; 3663 script.session = session;
3619 script__setup_sample_type(&script); 3664 script__setup_sample_type(&script);
3620 3665
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 05745f3ce912..999fe9170122 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -40,5 +40,6 @@ int cmd_mem(int argc, const char **argv);
40int cmd_data(int argc, const char **argv); 40int cmd_data(int argc, const char **argv);
41int cmd_ftrace(int argc, const char **argv); 41int cmd_ftrace(int argc, const char **argv);
42 42
43int find_scripts(char **scripts_array, char **scripts_path_array); 43int find_scripts(char **scripts_array, char **scripts_path_array, int num,
44 int pathlen);
44#endif 45#endif
diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/branch.json b/tools/perf/pmu-events/arch/x86/amdfam17h/branch.json
new file mode 100644
index 000000000000..93ddfd8053ca
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/amdfam17h/branch.json
@@ -0,0 +1,12 @@
1[
2 {
3 "EventName": "bp_l1_btb_correct",
4 "EventCode": "0x8a",
5 "BriefDescription": "L1 BTB Correction."
6 },
7 {
8 "EventName": "bp_l2_btb_correct",
9 "EventCode": "0x8b",
10 "BriefDescription": "L2 BTB Correction."
11 }
12]
diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json b/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json
new file mode 100644
index 000000000000..fad4af9142cb
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json
@@ -0,0 +1,287 @@
1[
2 {
3 "EventName": "ic_fw32",
4 "EventCode": "0x80",
5 "BriefDescription": "The number of 32B fetch windows transferred from IC pipe to DE instruction decoder (includes non-cacheable and cacheable fill responses)."
6 },
7 {
8 "EventName": "ic_fw32_miss",
9 "EventCode": "0x81",
10 "BriefDescription": "The number of 32B fetch windows tried to read the L1 IC and missed in the full tag."
11 },
12 {
13 "EventName": "ic_cache_fill_l2",
14 "EventCode": "0x82",
15 "BriefDescription": "The number of 64 byte instruction cache line was fulfilled from the L2 cache."
16 },
17 {
18 "EventName": "ic_cache_fill_sys",
19 "EventCode": "0x83",
20 "BriefDescription": "The number of 64 byte instruction cache line fulfilled from system memory or another cache."
21 },
22 {
23 "EventName": "bp_l1_tlb_miss_l2_hit",
24 "EventCode": "0x84",
25 "BriefDescription": "The number of instruction fetches that miss in the L1 ITLB but hit in the L2 ITLB."
26 },
27 {
28 "EventName": "bp_l1_tlb_miss_l2_miss",
29 "EventCode": "0x85",
30 "BriefDescription": "The number of instruction fetches that miss in both the L1 and L2 TLBs."
31 },
32 {
33 "EventName": "bp_snp_re_sync",
34 "EventCode": "0x86",
35 "BriefDescription": "The number of pipeline restarts caused by invalidating probes that hit on the instruction stream currently being executed. This would happen if the active instruction stream was being modified by another processor in an MP system - typically a highly unlikely event."
36 },
37 {
38 "EventName": "ic_fetch_stall.ic_stall_any",
39 "EventCode": "0x87",
40 "BriefDescription": "IC pipe was stalled during this clock cycle for any reason (nothing valid in pipe ICM1).",
41 "PublicDescription": "Instruction Pipe Stall. IC pipe was stalled during this clock cycle for any reason (nothing valid in pipe ICM1).",
42 "UMask": "0x4"
43 },
44 {
45 "EventName": "ic_fetch_stall.ic_stall_dq_empty",
46 "EventCode": "0x87",
47 "BriefDescription": "IC pipe was stalled during this clock cycle (including IC to OC fetches) due to DQ empty.",
48 "PublicDescription": "Instruction Pipe Stall. IC pipe was stalled during this clock cycle (including IC to OC fetches) due to DQ empty.",
49 "UMask": "0x2"
50 },
51 {
52 "EventName": "ic_fetch_stall.ic_stall_back_pressure",
53 "EventCode": "0x87",
54 "BriefDescription": "IC pipe was stalled during this clock cycle (including IC to OC fetches) due to back-pressure.",
55 "PublicDescription": "Instruction Pipe Stall. IC pipe was stalled during this clock cycle (including IC to OC fetches) due to back-pressure.",
56 "UMask": "0x1"
57 },
58 {
59 "EventName": "ic_cache_inval.l2_invalidating_probe",
60 "EventCode": "0x8c",
61 "BriefDescription": "IC line invalidated due to L2 invalidating probe (external or LS).",
62 "PublicDescription": "The number of instruction cache lines invalidated. A non-SMC event is CMC (cross modifying code), either from the other thread of the core or another core. IC line invalidated due to L2 invalidating probe (external or LS).",
63 "UMask": "0x2"
64 },
65 {
66 "EventName": "ic_cache_inval.fill_invalidated",
67 "EventCode": "0x8c",
68 "BriefDescription": "IC line invalidated due to overwriting fill response.",
69 "PublicDescription": "The number of instruction cache lines invalidated. A non-SMC event is CMC (cross modifying code), either from the other thread of the core or another core. IC line invalidated due to overwriting fill response.",
70 "UMask": "0x1"
71 },
72 {
73 "EventName": "bp_tlb_rel",
74 "EventCode": "0x99",
75 "BriefDescription": "The number of ITLB reload requests."
76 },
77 {
78 "EventName": "l2_request_g1.rd_blk_l",
79 "EventCode": "0x60",
80 "BriefDescription": "Requests to L2 Group1.",
81 "PublicDescription": "Requests to L2 Group1.",
82 "UMask": "0x80"
83 },
84 {
85 "EventName": "l2_request_g1.rd_blk_x",
86 "EventCode": "0x60",
87 "BriefDescription": "Requests to L2 Group1.",
88 "PublicDescription": "Requests to L2 Group1.",
89 "UMask": "0x40"
90 },
91 {
92 "EventName": "l2_request_g1.ls_rd_blk_c_s",
93 "EventCode": "0x60",
94 "BriefDescription": "Requests to L2 Group1.",
95 "PublicDescription": "Requests to L2 Group1.",
96 "UMask": "0x20"
97 },
98 {
99 "EventName": "l2_request_g1.cacheable_ic_read",
100 "EventCode": "0x60",
101 "BriefDescription": "Requests to L2 Group1.",
102 "PublicDescription": "Requests to L2 Group1.",
103 "UMask": "0x10"
104 },
105 {
106 "EventName": "l2_request_g1.change_to_x",
107 "EventCode": "0x60",
108 "BriefDescription": "Requests to L2 Group1.",
109 "PublicDescription": "Requests to L2 Group1.",
110 "UMask": "0x8"
111 },
112 {
113 "EventName": "l2_request_g1.prefetch_l2",
114 "EventCode": "0x60",
115 "BriefDescription": "Requests to L2 Group1.",
116 "PublicDescription": "Requests to L2 Group1.",
117 "UMask": "0x4"
118 },
119 {
120 "EventName": "l2_request_g1.l2_hw_pf",
121 "EventCode": "0x60",
122 "BriefDescription": "Requests to L2 Group1.",
123 "PublicDescription": "Requests to L2 Group1.",
124 "UMask": "0x2"
125 },
126 {
127 "EventName": "l2_request_g1.other_requests",
128 "EventCode": "0x60",
129 "BriefDescription": "Events covered by l2_request_g2.",
130 "PublicDescription": "Requests to L2 Group1. Events covered by l2_request_g2.",
131 "UMask": "0x1"
132 },
133 {
134 "EventName": "l2_request_g2.group1",
135 "EventCode": "0x61",
136 "BriefDescription": "All Group 1 commands not in unit0.",
137 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous. All Group 1 commands not in unit0.",
138 "UMask": "0x80"
139 },
140 {
141 "EventName": "l2_request_g2.ls_rd_sized",
142 "EventCode": "0x61",
143 "BriefDescription": "RdSized, RdSized32, RdSized64.",
144 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous. RdSized, RdSized32, RdSized64.",
145 "UMask": "0x40"
146 },
147 {
148 "EventName": "l2_request_g2.ls_rd_sized_nc",
149 "EventCode": "0x61",
150 "BriefDescription": "RdSizedNC, RdSized32NC, RdSized64NC.",
151 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous. RdSizedNC, RdSized32NC, RdSized64NC.",
152 "UMask": "0x20"
153 },
154 {
155 "EventName": "l2_request_g2.ic_rd_sized",
156 "EventCode": "0x61",
157 "BriefDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
158 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
159 "UMask": "0x10"
160 },
161 {
162 "EventName": "l2_request_g2.ic_rd_sized_nc",
163 "EventCode": "0x61",
164 "BriefDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
165 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
166 "UMask": "0x8"
167 },
168 {
169 "EventName": "l2_request_g2.smc_inval",
170 "EventCode": "0x61",
171 "BriefDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
172 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
173 "UMask": "0x4"
174 },
175 {
176 "EventName": "l2_request_g2.bus_locks_originator",
177 "EventCode": "0x61",
178 "BriefDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
179 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
180 "UMask": "0x2"
181 },
182 {
183 "EventName": "l2_request_g2.bus_locks_responses",
184 "EventCode": "0x61",
185 "BriefDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
186 "PublicDescription": "Multi-events in that LS and IF requests can be received simultaneous.",
187 "UMask": "0x1"
188 },
189 {
190 "EventName": "l2_latency.l2_cycles_waiting_on_fills",
191 "EventCode": "0x62",
192 "BriefDescription": "Total cycles spent waiting for L2 fills to complete from L3 or memory, divided by four. Event counts are for both threads. To calculate average latency, the number of fills from both threads must be used.",
193 "PublicDescription": "Total cycles spent waiting for L2 fills to complete from L3 or memory, divided by four. Event counts are for both threads. To calculate average latency, the number of fills from both threads must be used.",
194 "UMask": "0x1"
195 },
196 {
197 "EventName": "l2_wcb_req.wcb_write",
198 "EventCode": "0x63",
199 "PublicDescription": "LS (Load/Store unit) to L2 WCB (Write Combining Buffer) write requests.",
200 "BriefDescription": "LS to L2 WCB write requests.",
201 "UMask": "0x40"
202 },
203 {
204 "EventName": "l2_wcb_req.wcb_close",
205 "EventCode": "0x63",
206 "BriefDescription": "LS to L2 WCB close requests.",
207 "PublicDescription": "LS (Load/Store unit) to L2 WCB (Write Combining Buffer) close requests.",
208 "UMask": "0x20"
209 },
210 {
211 "EventName": "l2_wcb_req.zero_byte_store",
212 "EventCode": "0x63",
213 "BriefDescription": "LS to L2 WCB zero byte store requests.",
214 "PublicDescription": "LS (Load/Store unit) to L2 WCB (Write Combining Buffer) zero byte store requests.",
215 "UMask": "0x4"
216 },
217 {
218 "EventName": "l2_wcb_req.cl_zero",
219 "EventCode": "0x63",
220 "PublicDescription": "LS to L2 WCB cache line zeroing requests.",
221 "BriefDescription": "LS (Load/Store unit) to L2 WCB (Write Combining Buffer) cache line zeroing requests.",
222 "UMask": "0x1"
223 },
224 {
225 "EventName": "l2_cache_req_stat.ls_rd_blk_cs",
226 "EventCode": "0x64",
227 "BriefDescription": "LS ReadBlock C/S Hit.",
228 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. LS ReadBlock C/S Hit.",
229 "UMask": "0x80"
230 },
231 {
232 "EventName": "l2_cache_req_stat.ls_rd_blk_l_hit_x",
233 "EventCode": "0x64",
234 "BriefDescription": "LS Read Block L Hit X.",
235 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. LS Read Block L Hit X.",
236 "UMask": "0x40"
237 },
238 {
239 "EventName": "l2_cache_req_stat.ls_rd_blk_l_hit_s",
240 "EventCode": "0x64",
241 "BriefDescription": "LsRdBlkL Hit Shared.",
242 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. LsRdBlkL Hit Shared.",
243 "UMask": "0x20"
244 },
245 {
246 "EventName": "l2_cache_req_stat.ls_rd_blk_x",
247 "EventCode": "0x64",
248 "BriefDescription": "LsRdBlkX/ChgToX Hit X. Count RdBlkX finding Shared as a Miss.",
249 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. LsRdBlkX/ChgToX Hit X. Count RdBlkX finding Shared as a Miss.",
250 "UMask": "0x10"
251 },
252 {
253 "EventName": "l2_cache_req_stat.ls_rd_blk_c",
254 "EventCode": "0x64",
255 "BriefDescription": "LS Read Block C S L X Change to X Miss.",
256 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. LS Read Block C S L X Change to X Miss.",
257 "UMask": "0x8"
258 },
259 {
260 "EventName": "l2_cache_req_stat.ic_fill_hit_x",
261 "EventCode": "0x64",
262 "BriefDescription": "IC Fill Hit Exclusive Stale.",
263 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. IC Fill Hit Exclusive Stale.",
264 "UMask": "0x4"
265 },
266 {
267 "EventName": "l2_cache_req_stat.ic_fill_hit_s",
268 "EventCode": "0x64",
269 "BriefDescription": "IC Fill Hit Shared.",
270 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. IC Fill Hit Shared.",
271 "UMask": "0x2"
272 },
273 {
274 "EventName": "l2_cache_req_stat.ic_fill_miss",
275 "EventCode": "0x64",
276 "BriefDescription": "IC Fill Miss.",
277 "PublicDescription": "This event does not count accesses to the L2 cache by the L2 prefetcher, but it does count accesses by the L1 prefetcher. IC Fill Miss.",
278 "UMask": "0x1"
279 },
280 {
281 "EventName": "l2_fill_pending.l2_fill_busy",
282 "EventCode": "0x6d",
283 "BriefDescription": "Total cycles spent with one or more fill requests in flight from L2.",
284 "PublicDescription": "Total cycles spent with one or more fill requests in flight from L2.",
285 "UMask": "0x1"
286 }
287]
diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/core.json b/tools/perf/pmu-events/arch/x86/amdfam17h/core.json
new file mode 100644
index 000000000000..7b285b0a7f35
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/amdfam17h/core.json
@@ -0,0 +1,134 @@
1[
2 {
3 "EventName": "ex_ret_instr",
4 "EventCode": "0xc0",
5 "BriefDescription": "Retired Instructions."
6 },
7 {
8 "EventName": "ex_ret_cops",
9 "EventCode": "0xc1",
10 "BriefDescription": "Retired Uops.",
11 "PublicDescription": "The number of uOps retired. This includes all processor activity (instructions, exceptions, interrupts, microcode assists, etc.). The number of events logged per cycle can vary from 0 to 4."
12 },
13 {
14 "EventName": "ex_ret_brn",
15 "EventCode": "0xc2",
16 "BriefDescription": "[Retired Branch Instructions.",
17 "PublicDescription": "The number of branch instructions retired. This includes all types of architectural control flow changes, including exceptions and interrupts."
18 },
19 {
20 "EventName": "ex_ret_brn_misp",
21 "EventCode": "0xc3",
22 "BriefDescription": "Retired Branch Instructions Mispredicted.",
23 "PublicDescription": "The number of branch instructions retired, of any type, that were not correctly predicted. This includes those for which prediction is not attempted (far control transfers, exceptions and interrupts)."
24 },
25 {
26 "EventName": "ex_ret_brn_tkn",
27 "EventCode": "0xc4",
28 "BriefDescription": "Retired Taken Branch Instructions.",
29 "PublicDescription": "The number of taken branches that were retired. This includes all types of architectural control flow changes, including exceptions and interrupts."
30 },
31 {
32 "EventName": "ex_ret_brn_tkn_misp",
33 "EventCode": "0xc5",
34 "BriefDescription": "Retired Taken Branch Instructions Mispredicted.",
35 "PublicDescription": "The number of retired taken branch instructions that were mispredicted."
36 },
37 {
38 "EventName": "ex_ret_brn_far",
39 "EventCode": "0xc6",
40 "BriefDescription": "Retired Far Control Transfers.",
41 "PublicDescription": "The number of far control transfers retired including far call/jump/return, IRET, SYSCALL and SYSRET, plus exceptions and interrupts. Far control transfers are not subject to branch prediction."
42 },
43 {
44 "EventName": "ex_ret_brn_resync",
45 "EventCode": "0xc7",
46 "BriefDescription": "Retired Branch Resyncs.",
47 "PublicDescription": "The number of resync branches. These reflect pipeline restarts due to certain microcode assists and events such as writes to the active instruction stream, among other things. Each occurrence reflects a restart penalty similar to a branch mispredict. This is relatively rare."
48 },
49 {
50 "EventName": "ex_ret_near_ret",
51 "EventCode": "0xc8",
52 "BriefDescription": "Retired Near Returns.",
53 "PublicDescription": "The number of near return instructions (RET or RET Iw) retired."
54 },
55 {
56 "EventName": "ex_ret_near_ret_mispred",
57 "EventCode": "0xc9",
58 "BriefDescription": "Retired Near Returns Mispredicted.",
59 "PublicDescription": "The number of near returns retired that were not correctly predicted by the return address predictor. Each such mispredict incurs the same penalty as a mispredicted conditional branch instruction."
60 },
61 {
62 "EventName": "ex_ret_brn_ind_misp",
63 "EventCode": "0xca",
64 "BriefDescription": "Retired Indirect Branch Instructions Mispredicted.",
65 "PublicDescription": "Retired Indirect Branch Instructions Mispredicted."
66 },
67 {
68 "EventName": "ex_ret_mmx_fp_instr.sse_instr",
69 "EventCode": "0xcb",
70 "BriefDescription": "SSE instructions (SSE, SSE2, SSE3, SSSE3, SSE4A, SSE41, SSE42, AVX).",
71 "PublicDescription": "The number of MMX, SSE or x87 instructions retired. The UnitMask allows the selection of the individual classes of instructions as given in the table. Each increment represents one complete instruction. Since this event includes non-numeric instructions it is not suitable for measuring MFLOPS. SSE instructions (SSE, SSE2, SSE3, SSSE3, SSE4A, SSE41, SSE42, AVX).",
72 "UMask": "0x4"
73 },
74 {
75 "EventName": "ex_ret_mmx_fp_instr.mmx_instr",
76 "EventCode": "0xcb",
77 "BriefDescription": "MMX instructions.",
78 "PublicDescription": "The number of MMX, SSE or x87 instructions retired. The UnitMask allows the selection of the individual classes of instructions as given in the table. Each increment represents one complete instruction. Since this event includes non-numeric instructions it is not suitable for measuring MFLOPS. MMX instructions.",
79 "UMask": "0x2"
80 },
81 {
82 "EventName": "ex_ret_mmx_fp_instr.x87_instr",
83 "EventCode": "0xcb",
84 "BriefDescription": "x87 instructions.",
85 "PublicDescription": "The number of MMX, SSE or x87 instructions retired. The UnitMask allows the selection of the individual classes of instructions as given in the table. Each increment represents one complete instruction. Since this event includes non-numeric instructions it is not suitable for measuring MFLOPS. x87 instructions.",
86 "UMask": "0x1"
87 },
88 {
89 "EventName": "ex_ret_cond",
90 "EventCode": "0xd1",
91 "BriefDescription": "Retired Conditional Branch Instructions."
92 },
93 {
94 "EventName": "ex_ret_cond_misp",
95 "EventCode": "0xd2",
96 "BriefDescription": "Retired Conditional Branch Instructions Mispredicted."
97 },
98 {
99 "EventName": "ex_div_busy",
100 "EventCode": "0xd3",
101 "BriefDescription": "Div Cycles Busy count."
102 },
103 {
104 "EventName": "ex_div_count",
105 "EventCode": "0xd4",
106 "BriefDescription": "Div Op Count."
107 },
108 {
109 "EventName": "ex_tagged_ibs_ops.ibs_count_rollover",
110 "EventCode": "0x1cf",
111 "BriefDescription": "Number of times an op could not be tagged by IBS because of a previous tagged op that has not retired.",
112 "PublicDescription": "Tagged IBS Ops. Number of times an op could not be tagged by IBS because of a previous tagged op that has not retired.",
113 "UMask": "0x4"
114 },
115 {
116 "EventName": "ex_tagged_ibs_ops.ibs_tagged_ops_ret",
117 "EventCode": "0x1cf",
118 "BriefDescription": "Number of Ops tagged by IBS that retired.",
119 "PublicDescription": "Tagged IBS Ops. Number of Ops tagged by IBS that retired.",
120 "UMask": "0x2"
121 },
122 {
123 "EventName": "ex_tagged_ibs_ops.ibs_tagged_ops",
124 "EventCode": "0x1cf",
125 "BriefDescription": "Number of Ops tagged by IBS.",
126 "PublicDescription": "Tagged IBS Ops. Number of Ops tagged by IBS.",
127 "UMask": "0x1"
128 },
129 {
130 "EventName": "ex_ret_fus_brnch_inst",
131 "EventCode": "0x1d0",
132 "BriefDescription": "The number of fused retired branch instructions retired per cycle. The number of events logged per cycle can vary from 0 to 3."
133 }
134]
diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/floating-point.json b/tools/perf/pmu-events/arch/x86/amdfam17h/floating-point.json
new file mode 100644
index 000000000000..ea4711983d1d
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/amdfam17h/floating-point.json
@@ -0,0 +1,168 @@
1[
2 {
3 "EventName": "fpu_pipe_assignment.dual",
4 "EventCode": "0x00",
5 "BriefDescription": "Total number multi-pipe uOps.",
6 "PublicDescription": "The number of operations (uOps) and dual-pipe uOps dispatched to each of the 4 FPU execution pipelines. This event reflects how busy the FPU pipelines are and may be used for workload characterization. This includes all operations performed by x87, MMX, and SSE instructions, including moves. Each increment represents a one- cycle dispatch event. This event is a speculative event. Since this event includes non-numeric operations it is not suitable for measuring MFLOPS. Total number multi-pipe uOps assigned to Pipe 3.",
7 "UMask": "0xf0"
8 },
9 {
10 "EventName": "fpu_pipe_assignment.total",
11 "EventCode": "0x00",
12 "BriefDescription": "Total number uOps.",
13 "PublicDescription": "The number of operations (uOps) and dual-pipe uOps dispatched to each of the 4 FPU execution pipelines. This event reflects how busy the FPU pipelines are and may be used for workload characterization. This includes all operations performed by x87, MMX, and SSE instructions, including moves. Each increment represents a one- cycle dispatch event. This event is a speculative event. Since this event includes non-numeric operations it is not suitable for measuring MFLOPS. Total number uOps assigned to Pipe 3.",
14 "UMask": "0xf"
15 },
16 {
17 "EventName": "fp_sched_empty",
18 "EventCode": "0x01",
19 "BriefDescription": "This is a speculative event. The number of cycles in which the FPU scheduler is empty. Note that some Ops like FP loads bypass the scheduler."
20 },
21 {
22 "EventName": "fp_retx87_fp_ops.all",
23 "EventCode": "0x02",
24 "BriefDescription": "All Ops.",
25 "PublicDescription": "The number of x87 floating-point Ops that have retired. The number of events logged per cycle can vary from 0 to 8.",
26 "UMask": "0x7"
27 },
28 {
29 "EventName": "fp_retx87_fp_ops.div_sqr_r_ops",
30 "EventCode": "0x02",
31 "BriefDescription": "Divide and square root Ops.",
32 "PublicDescription": "The number of x87 floating-point Ops that have retired. The number of events logged per cycle can vary from 0 to 8. Divide and square root Ops.",
33 "UMask": "0x4"
34 },
35 {
36 "EventName": "fp_retx87_fp_ops.mul_ops",
37 "EventCode": "0x02",
38 "BriefDescription": "Multiply Ops.",
39 "PublicDescription": "The number of x87 floating-point Ops that have retired. The number of events logged per cycle can vary from 0 to 8. Multiply Ops.",
40 "UMask": "0x2"
41 },
42 {
43 "EventName": "fp_retx87_fp_ops.add_sub_ops",
44 "EventCode": "0x02",
45 "BriefDescription": "Add/subtract Ops.",
46 "PublicDescription": "The number of x87 floating-point Ops that have retired. The number of events logged per cycle can vary from 0 to 8. Add/subtract Ops.",
47 "UMask": "0x1"
48 },
49 {
50 "EventName": "fp_ret_sse_avx_ops.all",
51 "EventCode": "0x03",
52 "BriefDescription": "All FLOPS.",
53 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15.",
54 "UMask": "0xff"
55 },
56 {
57 "EventName": "fp_ret_sse_avx_ops.dp_mult_add_flops",
58 "EventCode": "0x03",
59 "BriefDescription": "Double precision multiply-add FLOPS. Multiply-add counts as 2 FLOPS.",
60 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Double precision multiply-add FLOPS. Multiply-add counts as 2 FLOPS.",
61 "UMask": "0x80"
62 },
63 {
64 "EventName": "fp_ret_sse_avx_ops.dp_div_flops",
65 "EventCode": "0x03",
66 "BriefDescription": "Double precision divide/square root FLOPS.",
67 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Double precision divide/square root FLOPS.",
68 "UMask": "0x40"
69 },
70 {
71 "EventName": "fp_ret_sse_avx_ops.dp_mult_flops",
72 "EventCode": "0x03",
73 "BriefDescription": "Double precision multiply FLOPS.",
74 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Double precision multiply FLOPS.",
75 "UMask": "0x20"
76 },
77 {
78 "EventName": "fp_ret_sse_avx_ops.dp_add_sub_flops",
79 "EventCode": "0x03",
80 "BriefDescription": "Double precision add/subtract FLOPS.",
81 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Double precision add/subtract FLOPS.",
82 "UMask": "0x10"
83 },
84 {
85 "EventName": "fp_ret_sse_avx_ops.sp_mult_add_flops",
86 "EventCode": "0x03",
87 "BriefDescription": "Single precision multiply-add FLOPS. Multiply-add counts as 2 FLOPS.",
88 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Single precision multiply-add FLOPS. Multiply-add counts as 2 FLOPS.",
89 "UMask": "0x8"
90 },
91 {
92 "EventName": "fp_ret_sse_avx_ops.sp_div_flops",
93 "EventCode": "0x03",
94 "BriefDescription": "Single-precision divide/square root FLOPS.",
95 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Single-precision divide/square root FLOPS.",
96 "UMask": "0x4"
97 },
98 {
99 "EventName": "fp_ret_sse_avx_ops.sp_mult_flops",
100 "EventCode": "0x03",
101 "BriefDescription": "Single-precision multiply FLOPS.",
102 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Single-precision multiply FLOPS.",
103 "UMask": "0x2"
104 },
105 {
106 "EventName": "fp_ret_sse_avx_ops.sp_add_sub_flops",
107 "EventCode": "0x03",
108 "BriefDescription": "Single-precision add/subtract FLOPS.",
109 "PublicDescription": "This is a retire-based event. The number of retired SSE/AVX FLOPS. The number of events logged per cycle can vary from 0 to 64. This event can count above 15. Single-precision add/subtract FLOPS.",
110 "UMask": "0x1"
111 },
112 {
113 "EventName": "fp_num_mov_elim_scal_op.optimized",
114 "EventCode": "0x04",
115 "BriefDescription": "Number of Scalar Ops optimized.",
116 "PublicDescription": "This is a dispatch based speculative event, and is useful for measuring the effectiveness of the Move elimination and Scalar code optimization schemes. Number of Scalar Ops optimized.",
117 "UMask": "0x8"
118 },
119 {
120 "EventName": "fp_num_mov_elim_scal_op.opt_potential",
121 "EventCode": "0x04",
122 "BriefDescription": "Number of Ops that are candidates for optimization (have Z-bit either set or pass).",
123 "PublicDescription": "This is a dispatch based speculative event, and is useful for measuring the effectiveness of the Move elimination and Scalar code optimization schemes. Number of Ops that are candidates for optimization (have Z-bit either set or pass).",
124 "UMask": "0x4"
125 },
126 {
127 "EventName": "fp_num_mov_elim_scal_op.sse_mov_ops_elim",
128 "EventCode": "0x04",
129 "BriefDescription": "Number of SSE Move Ops eliminated.",
130 "PublicDescription": "This is a dispatch based speculative event, and is useful for measuring the effectiveness of the Move elimination and Scalar code optimization schemes. Number of SSE Move Ops eliminated.",
131 "UMask": "0x2"
132 },
133 {
134 "EventName": "fp_num_mov_elim_scal_op.sse_mov_ops",
135 "EventCode": "0x04",
136 "BriefDescription": "Number of SSE Move Ops.",
137 "PublicDescription": "This is a dispatch based speculative event, and is useful for measuring the effectiveness of the Move elimination and Scalar code optimization schemes. Number of SSE Move Ops.",
138 "UMask": "0x1"
139 },
140 {
141 "EventName": "fp_retired_ser_ops.x87_ctrl_ret",
142 "EventCode": "0x05",
143 "BriefDescription": "x87 control word mispredict traps due to mispredictions in RC or PC, or changes in mask bits.",
144 "PublicDescription": "The number of serializing Ops retired. x87 control word mispredict traps due to mispredictions in RC or PC, or changes in mask bits.",
145 "UMask": "0x8"
146 },
147 {
148 "EventName": "fp_retired_ser_ops.x87_bot_ret",
149 "EventCode": "0x05",
150 "BriefDescription": "x87 bottom-executing uOps retired.",
151 "PublicDescription": "The number of serializing Ops retired. x87 bottom-executing uOps retired.",
152 "UMask": "0x4"
153 },
154 {
155 "EventName": "fp_retired_ser_ops.sse_ctrl_ret",
156 "EventCode": "0x05",
157 "BriefDescription": "SSE control word mispredict traps due to mispredictions in RC, FTZ or DAZ, or changes in mask bits.",
158 "PublicDescription": "The number of serializing Ops retired. SSE control word mispredict traps due to mispredictions in RC, FTZ or DAZ, or changes in mask bits.",
159 "UMask": "0x2"
160 },
161 {
162 "EventName": "fp_retired_ser_ops.sse_bot_ret",
163 "EventCode": "0x05",
164 "BriefDescription": "SSE bottom-executing uOps retired.",
165 "PublicDescription": "The number of serializing Ops retired. SSE bottom-executing uOps retired.",
166 "UMask": "0x1"
167 }
168]
diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/memory.json b/tools/perf/pmu-events/arch/x86/amdfam17h/memory.json
new file mode 100644
index 000000000000..fa2d60d4def0
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/amdfam17h/memory.json
@@ -0,0 +1,162 @@
1[
2 {
3 "EventName": "ls_locks.bus_lock",
4 "EventCode": "0x25",
5 "BriefDescription": "Bus lock when a locked operations crosses a cache boundary or is done on an uncacheable memory type.",
6 "PublicDescription": "Bus lock when a locked operations crosses a cache boundary or is done on an uncacheable memory type.",
7 "UMask": "0x1"
8 },
9 {
10 "EventName": "ls_dispatch.ld_st_dispatch",
11 "EventCode": "0x29",
12 "BriefDescription": "Load-op-Stores.",
13 "PublicDescription": "Counts the number of operations dispatched to the LS unit. Unit Masks ADDed. Load-op-Stores.",
14 "UMask": "0x4"
15 },
16 {
17 "EventName": "ls_dispatch.store_dispatch",
18 "EventCode": "0x29",
19 "BriefDescription": "Counts the number of operations dispatched to the LS unit. Unit Masks ADDed.",
20 "PublicDescription": "Counts the number of operations dispatched to the LS unit. Unit Masks ADDed.",
21 "UMask": "0x2"
22 },
23 {
24 "EventName": "ls_dispatch.ld_dispatch",
25 "EventCode": "0x29",
26 "BriefDescription": "Counts the number of operations dispatched to the LS unit. Unit Masks ADDed.",
27 "PublicDescription": "Counts the number of operations dispatched to the LS unit. Unit Masks ADDed.",
28 "UMask": "0x1"
29 },
30 {
31 "EventName": "ls_stlf",
32 "EventCode": "0x35",
33 "BriefDescription": "Number of STLF hits."
34 },
35 {
36 "EventName": "ls_dc_accesses",
37 "EventCode": "0x40",
38 "BriefDescription": "The number of accesses to the data cache for load and store references. This may include certain microcode scratchpad accesses, although these are generally rare. Each increment represents an eight-byte access, although the instruction may only be accessing a portion of that. This event is a speculative event."
39 },
40 {
41 "EventName": "ls_l1_d_tlb_miss.all",
42 "EventCode": "0x45",
43 "BriefDescription": "L1 DTLB Miss or Reload off all sizes.",
44 "PublicDescription": "L1 DTLB Miss or Reload off all sizes.",
45 "UMask": "0xff"
46 },
47 {
48 "EventName": "ls_l1_d_tlb_miss.tlb_reload_1g_l2_miss",
49 "EventCode": "0x45",
50 "BriefDescription": "L1 DTLB Miss of a page of 1G size.",
51 "PublicDescription": "L1 DTLB Miss of a page of 1G size.",
52 "UMask": "0x80"
53 },
54 {
55 "EventName": "ls_l1_d_tlb_miss.tlb_reload_2m_l2_miss",
56 "EventCode": "0x45",
57 "BriefDescription": "L1 DTLB Miss of a page of 2M size.",
58 "PublicDescription": "L1 DTLB Miss of a page of 2M size.",
59 "UMask": "0x40"
60 },
61 {
62 "EventName": "ls_l1_d_tlb_miss.tlb_reload_32k_l2_miss",
63 "EventCode": "0x45",
64 "BriefDescription": "L1 DTLB Miss of a page of 32K size.",
65 "PublicDescription": "L1 DTLB Miss of a page of 32K size.",
66 "UMask": "0x20"
67 },
68 {
69 "EventName": "ls_l1_d_tlb_miss.tlb_reload_4k_l2_miss",
70 "EventCode": "0x45",
71 "BriefDescription": "L1 DTLB Miss of a page of 4K size.",
72 "PublicDescription": "L1 DTLB Miss of a page of 4K size.",
73 "UMask": "0x10"
74 },
75 {
76 "EventName": "ls_l1_d_tlb_miss.tlb_reload_1g_l2_hit",
77 "EventCode": "0x45",
78 "BriefDescription": "L1 DTLB Reload of a page of 1G size.",
79 "PublicDescription": "L1 DTLB Reload of a page of 1G size.",
80 "UMask": "0x8"
81 },
82 {
83 "EventName": "ls_l1_d_tlb_miss.tlb_reload_2m_l2_hit",
84 "EventCode": "0x45",
85 "BriefDescription": "L1 DTLB Reload of a page of 2M size.",
86 "PublicDescription": "L1 DTLB Reload of a page of 2M size.",
87 "UMask": "0x4"
88 },
89 {
90 "EventName": "ls_l1_d_tlb_miss.tlb_reload_32k_l2_hit",
91 "EventCode": "0x45",
92 "BriefDescription": "L1 DTLB Reload of a page of 32K size.",
93 "PublicDescription": "L1 DTLB Reload of a page of 32K size.",
94 "UMask": "0x2"
95 },
96 {
97 "EventName": "ls_l1_d_tlb_miss.tlb_reload_4k_l2_hit",
98 "EventCode": "0x45",
99 "BriefDescription": "L1 DTLB Reload of a page of 4K size.",
100 "PublicDescription": "L1 DTLB Reload of a page of 4K size.",
101 "UMask": "0x1"
102 },
103 {
104 "EventName": "ls_tablewalker.perf_mon_tablewalk_alloc_iside",
105 "EventCode": "0x46",
106 "BriefDescription": "Tablewalker allocation.",
107 "PublicDescription": "Tablewalker allocation.",
108 "UMask": "0xc"
109 },
110 {
111 "EventName": "ls_tablewalker.perf_mon_tablewalk_alloc_dside",
112 "EventCode": "0x46",
113 "BriefDescription": "Tablewalker allocation.",
114 "PublicDescription": "Tablewalker allocation.",
115 "UMask": "0x3"
116 },
117 {
118 "EventName": "ls_misal_accesses",
119 "EventCode": "0x47",
120 "BriefDescription": "Misaligned loads."
121 },
122 {
123 "EventName": "ls_pref_instr_disp.prefetch_nta",
124 "EventCode": "0x4b",
125 "BriefDescription": "Software Prefetch Instructions (PREFETCHNTA instruction) Dispatched.",
126 "PublicDescription": "Software Prefetch Instructions (PREFETCHNTA instruction) Dispatched.",
127 "UMask": "0x4"
128 },
129 {
130 "EventName": "ls_pref_instr_disp.store_prefetch_w",
131 "EventCode": "0x4b",
132 "BriefDescription": "Software Prefetch Instructions (3DNow PREFETCHW instruction) Dispatched.",
133 "PublicDescription": "Software Prefetch Instructions (3DNow PREFETCHW instruction) Dispatched.",
134 "UMask": "0x2"
135 },
136 {
137 "EventName": "ls_pref_instr_disp.load_prefetch_w",
138 "EventCode": "0x4b",
139 "BriefDescription": "Prefetch, Prefetch_T0_T1_T2.",
140 "PublicDescription": "Software Prefetch Instructions Dispatched. Prefetch, Prefetch_T0_T1_T2.",
141 "UMask": "0x1"
142 },
143 {
144 "EventName": "ls_inef_sw_pref.mab_mch_cnt",
145 "EventCode": "0x52",
146 "BriefDescription": "The number of software prefetches that did not fetch data outside of the processor core.",
147 "PublicDescription": "The number of software prefetches that did not fetch data outside of the processor core.",
148 "UMask": "0x2"
149 },
150 {
151 "EventName": "ls_inef_sw_pref.data_pipe_sw_pf_dc_hit",
152 "EventCode": "0x52",
153 "BriefDescription": "The number of software prefetches that did not fetch data outside of the processor core.",
154 "PublicDescription": "The number of software prefetches that did not fetch data outside of the processor core.",
155 "UMask": "0x1"
156 },
157 {
158 "EventName": "ls_not_halted_cyc",
159 "EventCode": "0x76",
160 "BriefDescription": "Cycles not in Halt."
161 }
162]
diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/other.json b/tools/perf/pmu-events/arch/x86/amdfam17h/other.json
new file mode 100644
index 000000000000..b26a00d05a2e
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/amdfam17h/other.json
@@ -0,0 +1,65 @@
1[
2 {
3 "EventName": "ic_oc_mode_switch.oc_ic_mode_switch",
4 "EventCode": "0x28a",
5 "BriefDescription": "OC to IC mode switch.",
6 "PublicDescription": "OC Mode Switch. OC to IC mode switch.",
7 "UMask": "0x2"
8 },
9 {
10 "EventName": "ic_oc_mode_switch.ic_oc_mode_switch",
11 "EventCode": "0x28a",
12 "BriefDescription": "IC to OC mode switch.",
13 "PublicDescription": "OC Mode Switch. IC to OC mode switch.",
14 "UMask": "0x1"
15 },
16 {
17 "EventName": "de_dis_dispatch_token_stalls0.retire_token_stall",
18 "EventCode": "0xaf",
19 "BriefDescription": "RETIRE Tokens unavailable.",
20 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall. RETIRE Tokens unavailable.",
21 "UMask": "0x40"
22 },
23 {
24 "EventName": "de_dis_dispatch_token_stalls0.agsq_token_stall",
25 "EventCode": "0xaf",
26 "BriefDescription": "AGSQ Tokens unavailable.",
27 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall. AGSQ Tokens unavailable.",
28 "UMask": "0x20"
29 },
30 {
31 "EventName": "de_dis_dispatch_token_stalls0.alu_token_stall",
32 "EventCode": "0xaf",
33 "BriefDescription": "ALU tokens total unavailable.",
34 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall. ALU tokens total unavailable.",
35 "UMask": "0x10"
36 },
37 {
38 "EventName": "de_dis_dispatch_token_stalls0.alsq3_0_token_stall",
39 "EventCode": "0xaf",
40 "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall.",
41 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall.",
42 "UMask": "0x8"
43 },
44 {
45 "EventName": "de_dis_dispatch_token_stalls0.alsq3_token_stall",
46 "EventCode": "0xaf",
47 "BriefDescription": "ALSQ 3 Tokens unavailable.",
48 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall. ALSQ 3 Tokens unavailable.",
49 "UMask": "0x4"
50 },
51 {
52 "EventName": "de_dis_dispatch_token_stalls0.alsq2_token_stall",
53 "EventCode": "0xaf",
54 "BriefDescription": "ALSQ 2 Tokens unavailable.",
55 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall. ALSQ 2 Tokens unavailable.",
56 "UMask": "0x2"
57 },
58 {
59 "EventName": "de_dis_dispatch_token_stalls0.alsq1_token_stall",
60 "EventCode": "0xaf",
61 "BriefDescription": "ALSQ 1 Tokens unavailable.",
62 "PublicDescription": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall. ALSQ 1 Tokens unavailable.",
63 "UMask": "0x1"
64 }
65]
diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv
index e05c2c8458fc..d6984a3017e0 100644
--- a/tools/perf/pmu-events/arch/x86/mapfile.csv
+++ b/tools/perf/pmu-events/arch/x86/mapfile.csv
@@ -33,3 +33,4 @@ GenuineIntel-6-25,v2,westmereep-sp,core
33GenuineIntel-6-2F,v2,westmereex,core 33GenuineIntel-6-2F,v2,westmereex,core
34GenuineIntel-6-55-[01234],v1,skylakex,core 34GenuineIntel-6-55-[01234],v1,skylakex,core
35GenuineIntel-6-55-[56789ABCDEF],v1,cascadelakex,core 35GenuineIntel-6-55-[56789ABCDEF],v1,cascadelakex,core
36AuthenticAMD-23-[[:xdigit:]]+,v1,amdfam17h,core
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py
index 390a351d15ea..c3eae1d77d36 100644
--- a/tools/perf/scripts/python/export-to-postgresql.py
+++ b/tools/perf/scripts/python/export-to-postgresql.py
@@ -10,6 +10,8 @@
10# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 10# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11# more details. 11# more details.
12 12
13from __future__ import print_function
14
13import os 15import os
14import sys 16import sys
15import struct 17import struct
@@ -199,6 +201,18 @@ import datetime
199 201
200from PySide.QtSql import * 202from PySide.QtSql import *
201 203
204if sys.version_info < (3, 0):
205 def toserverstr(str):
206 return str
207 def toclientstr(str):
208 return str
209else:
210 # Assume UTF-8 server_encoding and client_encoding
211 def toserverstr(str):
212 return bytes(str, "UTF_8")
213 def toclientstr(str):
214 return bytes(str, "UTF_8")
215
202# Need to access PostgreSQL C library directly to use COPY FROM STDIN 216# Need to access PostgreSQL C library directly to use COPY FROM STDIN
203from ctypes import * 217from ctypes import *
204libpq = CDLL("libpq.so.5") 218libpq = CDLL("libpq.so.5")
@@ -234,12 +248,17 @@ perf_db_export_mode = True
234perf_db_export_calls = False 248perf_db_export_calls = False
235perf_db_export_callchains = False 249perf_db_export_callchains = False
236 250
251def printerr(*args, **kw_args):
252 print(*args, file=sys.stderr, **kw_args)
253
254def printdate(*args, **kw_args):
255 print(datetime.datetime.today(), *args, sep=' ', **kw_args)
237 256
238def usage(): 257def usage():
239 print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]" 258 printerr("Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]")
240 print >> sys.stderr, "where: columns 'all' or 'branches'" 259 printerr("where: columns 'all' or 'branches'")
241 print >> sys.stderr, " calls 'calls' => create calls and call_paths table" 260 printerr(" calls 'calls' => create calls and call_paths table")
242 print >> sys.stderr, " callchains 'callchains' => create call_paths table" 261 printerr(" callchains 'callchains' => create call_paths table")
243 raise Exception("Too few arguments") 262 raise Exception("Too few arguments")
244 263
245if (len(sys.argv) < 2): 264if (len(sys.argv) < 2):
@@ -273,7 +292,7 @@ def do_query(q, s):
273 return 292 return
274 raise Exception("Query failed: " + q.lastError().text()) 293 raise Exception("Query failed: " + q.lastError().text())
275 294
276print datetime.datetime.today(), "Creating database..." 295printdate("Creating database...")
277 296
278db = QSqlDatabase.addDatabase('QPSQL') 297db = QSqlDatabase.addDatabase('QPSQL')
279query = QSqlQuery(db) 298query = QSqlQuery(db)
@@ -506,12 +525,12 @@ do_query(query, 'CREATE VIEW samples_view AS '
506 ' FROM samples') 525 ' FROM samples')
507 526
508 527
509file_header = struct.pack("!11sii", "PGCOPY\n\377\r\n\0", 0, 0) 528file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0)
510file_trailer = "\377\377" 529file_trailer = b"\377\377"
511 530
512def open_output_file(file_name): 531def open_output_file(file_name):
513 path_name = output_dir_name + "/" + file_name 532 path_name = output_dir_name + "/" + file_name
514 file = open(path_name, "w+") 533 file = open(path_name, "wb+")
515 file.write(file_header) 534 file.write(file_header)
516 return file 535 return file
517 536
@@ -526,13 +545,13 @@ def copy_output_file_direct(file, table_name):
526 545
527# Use COPY FROM STDIN because security may prevent postgres from accessing the files directly 546# Use COPY FROM STDIN because security may prevent postgres from accessing the files directly
528def copy_output_file(file, table_name): 547def copy_output_file(file, table_name):
529 conn = PQconnectdb("dbname = " + dbname) 548 conn = PQconnectdb(toclientstr("dbname = " + dbname))
530 if (PQstatus(conn)): 549 if (PQstatus(conn)):
531 raise Exception("COPY FROM STDIN PQconnectdb failed") 550 raise Exception("COPY FROM STDIN PQconnectdb failed")
532 file.write(file_trailer) 551 file.write(file_trailer)
533 file.seek(0) 552 file.seek(0)
534 sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')" 553 sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')"
535 res = PQexec(conn, sql) 554 res = PQexec(conn, toclientstr(sql))
536 if (PQresultStatus(res) != 4): 555 if (PQresultStatus(res) != 4):
537 raise Exception("COPY FROM STDIN PQexec failed") 556 raise Exception("COPY FROM STDIN PQexec failed")
538 data = file.read(65536) 557 data = file.read(65536)
@@ -566,7 +585,7 @@ if perf_db_export_calls:
566 call_file = open_output_file("call_table.bin") 585 call_file = open_output_file("call_table.bin")
567 586
568def trace_begin(): 587def trace_begin():
569 print datetime.datetime.today(), "Writing to intermediate files..." 588 printdate("Writing to intermediate files...")
570 # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs 589 # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs
571 evsel_table(0, "unknown") 590 evsel_table(0, "unknown")
572 machine_table(0, 0, "unknown") 591 machine_table(0, 0, "unknown")
@@ -582,7 +601,7 @@ def trace_begin():
582unhandled_count = 0 601unhandled_count = 0
583 602
584def trace_end(): 603def trace_end():
585 print datetime.datetime.today(), "Copying to database..." 604 printdate("Copying to database...")
586 copy_output_file(evsel_file, "selected_events") 605 copy_output_file(evsel_file, "selected_events")
587 copy_output_file(machine_file, "machines") 606 copy_output_file(machine_file, "machines")
588 copy_output_file(thread_file, "threads") 607 copy_output_file(thread_file, "threads")
@@ -597,7 +616,7 @@ def trace_end():
597 if perf_db_export_calls: 616 if perf_db_export_calls:
598 copy_output_file(call_file, "calls") 617 copy_output_file(call_file, "calls")
599 618
600 print datetime.datetime.today(), "Removing intermediate files..." 619 printdate("Removing intermediate files...")
601 remove_output_file(evsel_file) 620 remove_output_file(evsel_file)
602 remove_output_file(machine_file) 621 remove_output_file(machine_file)
603 remove_output_file(thread_file) 622 remove_output_file(thread_file)
@@ -612,7 +631,7 @@ def trace_end():
612 if perf_db_export_calls: 631 if perf_db_export_calls:
613 remove_output_file(call_file) 632 remove_output_file(call_file)
614 os.rmdir(output_dir_name) 633 os.rmdir(output_dir_name)
615 print datetime.datetime.today(), "Adding primary keys" 634 printdate("Adding primary keys")
616 do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') 635 do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)')
617 do_query(query, 'ALTER TABLE machines ADD PRIMARY KEY (id)') 636 do_query(query, 'ALTER TABLE machines ADD PRIMARY KEY (id)')
618 do_query(query, 'ALTER TABLE threads ADD PRIMARY KEY (id)') 637 do_query(query, 'ALTER TABLE threads ADD PRIMARY KEY (id)')
@@ -627,7 +646,7 @@ def trace_end():
627 if perf_db_export_calls: 646 if perf_db_export_calls:
628 do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') 647 do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)')
629 648
630 print datetime.datetime.today(), "Adding foreign keys" 649 printdate("Adding foreign keys")
631 do_query(query, 'ALTER TABLE threads ' 650 do_query(query, 'ALTER TABLE threads '
632 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' 651 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),'
633 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') 652 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)')
@@ -663,8 +682,8 @@ def trace_end():
663 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 682 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
664 683
665 if (unhandled_count): 684 if (unhandled_count):
666 print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" 685 printdate("Warning: ", unhandled_count, " unhandled events")
667 print datetime.datetime.today(), "Done" 686 printdate("Done")
668 687
669def trace_unhandled(event_name, context, event_fields_dict): 688def trace_unhandled(event_name, context, event_fields_dict):
670 global unhandled_count 689 global unhandled_count
@@ -674,12 +693,14 @@ def sched__sched_switch(*x):
674 pass 693 pass
675 694
676def evsel_table(evsel_id, evsel_name, *x): 695def evsel_table(evsel_id, evsel_name, *x):
696 evsel_name = toserverstr(evsel_name)
677 n = len(evsel_name) 697 n = len(evsel_name)
678 fmt = "!hiqi" + str(n) + "s" 698 fmt = "!hiqi" + str(n) + "s"
679 value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name) 699 value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name)
680 evsel_file.write(value) 700 evsel_file.write(value)
681 701
682def machine_table(machine_id, pid, root_dir, *x): 702def machine_table(machine_id, pid, root_dir, *x):
703 root_dir = toserverstr(root_dir)
683 n = len(root_dir) 704 n = len(root_dir)
684 fmt = "!hiqiii" + str(n) + "s" 705 fmt = "!hiqiii" + str(n) + "s"
685 value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir) 706 value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir)
@@ -690,6 +711,7 @@ def thread_table(thread_id, machine_id, process_id, pid, tid, *x):
690 thread_file.write(value) 711 thread_file.write(value)
691 712
692def comm_table(comm_id, comm_str, *x): 713def comm_table(comm_id, comm_str, *x):
714 comm_str = toserverstr(comm_str)
693 n = len(comm_str) 715 n = len(comm_str)
694 fmt = "!hiqi" + str(n) + "s" 716 fmt = "!hiqi" + str(n) + "s"
695 value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) 717 value = struct.pack(fmt, 2, 8, comm_id, n, comm_str)
@@ -701,6 +723,9 @@ def comm_thread_table(comm_thread_id, comm_id, thread_id, *x):
701 comm_thread_file.write(value) 723 comm_thread_file.write(value)
702 724
703def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x): 725def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x):
726 short_name = toserverstr(short_name)
727 long_name = toserverstr(long_name)
728 build_id = toserverstr(build_id)
704 n1 = len(short_name) 729 n1 = len(short_name)
705 n2 = len(long_name) 730 n2 = len(long_name)
706 n3 = len(build_id) 731 n3 = len(build_id)
@@ -709,12 +734,14 @@ def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x):
709 dso_file.write(value) 734 dso_file.write(value)
710 735
711def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x): 736def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x):
737 symbol_name = toserverstr(symbol_name)
712 n = len(symbol_name) 738 n = len(symbol_name)
713 fmt = "!hiqiqiqiqiii" + str(n) + "s" 739 fmt = "!hiqiqiqiqiii" + str(n) + "s"
714 value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name) 740 value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name)
715 symbol_file.write(value) 741 symbol_file.write(value)
716 742
717def branch_type_table(branch_type, name, *x): 743def branch_type_table(branch_type, name, *x):
744 name = toserverstr(name)
718 n = len(name) 745 n = len(name)
719 fmt = "!hiii" + str(n) + "s" 746 fmt = "!hiii" + str(n) + "s"
720 value = struct.pack(fmt, 2, 4, branch_type, n, name) 747 value = struct.pack(fmt, 2, 4, branch_type, n, name)
diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py
index eb63e6c7107f..3b71902a5a21 100644
--- a/tools/perf/scripts/python/export-to-sqlite.py
+++ b/tools/perf/scripts/python/export-to-sqlite.py
@@ -10,6 +10,8 @@
10# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 10# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11# more details. 11# more details.
12 12
13from __future__ import print_function
14
13import os 15import os
14import sys 16import sys
15import struct 17import struct
@@ -60,11 +62,17 @@ perf_db_export_mode = True
60perf_db_export_calls = False 62perf_db_export_calls = False
61perf_db_export_callchains = False 63perf_db_export_callchains = False
62 64
65def printerr(*args, **keyword_args):
66 print(*args, file=sys.stderr, **keyword_args)
67
68def printdate(*args, **kw_args):
69 print(datetime.datetime.today(), *args, sep=' ', **kw_args)
70
63def usage(): 71def usage():
64 print >> sys.stderr, "Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]" 72 printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]");
65 print >> sys.stderr, "where: columns 'all' or 'branches'" 73 printerr("where: columns 'all' or 'branches'");
66 print >> sys.stderr, " calls 'calls' => create calls and call_paths table" 74 printerr(" calls 'calls' => create calls and call_paths table");
67 print >> sys.stderr, " callchains 'callchains' => create call_paths table" 75 printerr(" callchains 'callchains' => create call_paths table");
68 raise Exception("Too few arguments") 76 raise Exception("Too few arguments")
69 77
70if (len(sys.argv) < 2): 78if (len(sys.argv) < 2):
@@ -100,7 +108,7 @@ def do_query_(q):
100 return 108 return
101 raise Exception("Query failed: " + q.lastError().text()) 109 raise Exception("Query failed: " + q.lastError().text())
102 110
103print datetime.datetime.today(), "Creating database..." 111printdate("Creating database ...")
104 112
105db_exists = False 113db_exists = False
106try: 114try:
@@ -378,7 +386,7 @@ if perf_db_export_calls:
378 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 386 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
379 387
380def trace_begin(): 388def trace_begin():
381 print datetime.datetime.today(), "Writing records..." 389 printdate("Writing records...")
382 do_query(query, 'BEGIN TRANSACTION') 390 do_query(query, 'BEGIN TRANSACTION')
383 # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs 391 # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs
384 evsel_table(0, "unknown") 392 evsel_table(0, "unknown")
@@ -397,14 +405,14 @@ unhandled_count = 0
397def trace_end(): 405def trace_end():
398 do_query(query, 'END TRANSACTION') 406 do_query(query, 'END TRANSACTION')
399 407
400 print datetime.datetime.today(), "Adding indexes" 408 printdate("Adding indexes")
401 if perf_db_export_calls: 409 if perf_db_export_calls:
402 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') 410 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
403 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 411 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
404 412
405 if (unhandled_count): 413 if (unhandled_count):
406 print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" 414 printdate("Warning: ", unhandled_count, " unhandled events")
407 print datetime.datetime.today(), "Done" 415 printdate("Done")
408 416
409def trace_unhandled(event_name, context, event_fields_dict): 417def trace_unhandled(event_name, context, event_fields_dict):
410 global unhandled_count 418 global unhandled_count
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index afec9479ca7f..e38518cdcbc3 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -88,11 +88,20 @@
88# 7fab593ea956 48 89 15 3b 13 22 00 movq %rdx, 0x22133b(%rip) 88# 7fab593ea956 48 89 15 3b 13 22 00 movq %rdx, 0x22133b(%rip)
89# 8107675243232 2 ls 22011 22011 hardware interrupt No 7fab593ea956 _dl_start+0x26 (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel]) 89# 8107675243232 2 ls 22011 22011 hardware interrupt No 7fab593ea956 _dl_start+0x26 (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])
90 90
91from __future__ import print_function
92
91import sys 93import sys
92import weakref 94import weakref
93import threading 95import threading
94import string 96import string
95import cPickle 97try:
98 # Python2
99 import cPickle as pickle
100 # size of pickled integer big enough for record size
101 glb_nsz = 8
102except ImportError:
103 import pickle
104 glb_nsz = 16
96import re 105import re
97import os 106import os
98from PySide.QtCore import * 107from PySide.QtCore import *
@@ -102,6 +111,15 @@ from decimal import *
102from ctypes import * 111from ctypes import *
103from multiprocessing import Process, Array, Value, Event 112from multiprocessing import Process, Array, Value, Event
104 113
114# xrange is range in Python3
115try:
116 xrange
117except NameError:
118 xrange = range
119
120def printerr(*args, **keyword_args):
121 print(*args, file=sys.stderr, **keyword_args)
122
105# Data formatting helpers 123# Data formatting helpers
106 124
107def tohex(ip): 125def tohex(ip):
@@ -1004,10 +1022,6 @@ class ChildDataItemFinder():
1004 1022
1005glb_chunk_sz = 10000 1023glb_chunk_sz = 10000
1006 1024
1007# size of pickled integer big enough for record size
1008
1009glb_nsz = 8
1010
1011# Background process for SQL data fetcher 1025# Background process for SQL data fetcher
1012 1026
1013class SQLFetcherProcess(): 1027class SQLFetcherProcess():
@@ -1066,7 +1080,7 @@ class SQLFetcherProcess():
1066 return True 1080 return True
1067 if space >= glb_nsz: 1081 if space >= glb_nsz:
1068 # Use 0 (or space < glb_nsz) to mean there is no more at the top of the buffer 1082 # Use 0 (or space < glb_nsz) to mean there is no more at the top of the buffer
1069 nd = cPickle.dumps(0, cPickle.HIGHEST_PROTOCOL) 1083 nd = pickle.dumps(0, pickle.HIGHEST_PROTOCOL)
1070 self.buffer[self.local_head : self.local_head + len(nd)] = nd 1084 self.buffer[self.local_head : self.local_head + len(nd)] = nd
1071 self.local_head = 0 1085 self.local_head = 0
1072 if self.local_tail - self.local_head > sz: 1086 if self.local_tail - self.local_head > sz:
@@ -1084,9 +1098,9 @@ class SQLFetcherProcess():
1084 self.wait_event.wait() 1098 self.wait_event.wait()
1085 1099
1086 def AddToBuffer(self, obj): 1100 def AddToBuffer(self, obj):
1087 d = cPickle.dumps(obj, cPickle.HIGHEST_PROTOCOL) 1101 d = pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
1088 n = len(d) 1102 n = len(d)
1089 nd = cPickle.dumps(n, cPickle.HIGHEST_PROTOCOL) 1103 nd = pickle.dumps(n, pickle.HIGHEST_PROTOCOL)
1090 sz = n + glb_nsz 1104 sz = n + glb_nsz
1091 self.WaitForSpace(sz) 1105 self.WaitForSpace(sz)
1092 pos = self.local_head 1106 pos = self.local_head
@@ -1198,12 +1212,12 @@ class SQLFetcher(QObject):
1198 pos = self.local_tail 1212 pos = self.local_tail
1199 if len(self.buffer) - pos < glb_nsz: 1213 if len(self.buffer) - pos < glb_nsz:
1200 pos = 0 1214 pos = 0
1201 n = cPickle.loads(self.buffer[pos : pos + glb_nsz]) 1215 n = pickle.loads(self.buffer[pos : pos + glb_nsz])
1202 if n == 0: 1216 if n == 0:
1203 pos = 0 1217 pos = 0
1204 n = cPickle.loads(self.buffer[0 : glb_nsz]) 1218 n = pickle.loads(self.buffer[0 : glb_nsz])
1205 pos += glb_nsz 1219 pos += glb_nsz
1206 obj = cPickle.loads(self.buffer[pos : pos + n]) 1220 obj = pickle.loads(self.buffer[pos : pos + n])
1207 self.local_tail = pos + n 1221 self.local_tail = pos + n
1208 return obj 1222 return obj
1209 1223
@@ -2973,7 +2987,7 @@ class DBRef():
2973 2987
2974def Main(): 2988def Main():
2975 if (len(sys.argv) < 2): 2989 if (len(sys.argv) < 2):
2976 print >> sys.stderr, "Usage is: exported-sql-viewer.py {<database name> | --help-only}" 2990 printerr("Usage is: exported-sql-viewer.py {<database name> | --help-only}");
2977 raise Exception("Too few arguments") 2991 raise Exception("Too few arguments")
2978 2992
2979 dbname = sys.argv[1] 2993 dbname = sys.argv[1]
@@ -2986,8 +3000,8 @@ def Main():
2986 3000
2987 is_sqlite3 = False 3001 is_sqlite3 = False
2988 try: 3002 try:
2989 f = open(dbname) 3003 f = open(dbname, "rb")
2990 if f.read(15) == "SQLite format 3": 3004 if f.read(15) == b'SQLite format 3':
2991 is_sqlite3 = True 3005 is_sqlite3 = True
2992 f.close() 3006 f.close()
2993 except: 3007 except:
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 4f75561424ed..4ad37d8c7d6a 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -611,14 +611,16 @@ void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence)
611 browser->top = browser->entries; 611 browser->top = browser->entries;
612 break; 612 break;
613 case SEEK_CUR: 613 case SEEK_CUR:
614 browser->top = browser->top + browser->top_idx + offset; 614 browser->top = (char **)browser->top + offset;
615 break; 615 break;
616 case SEEK_END: 616 case SEEK_END:
617 browser->top = browser->top + browser->nr_entries - 1 + offset; 617 browser->top = (char **)browser->entries + browser->nr_entries - 1 + offset;
618 break; 618 break;
619 default: 619 default:
620 return; 620 return;
621 } 621 }
622 assert((char **)browser->top < (char **)browser->entries + browser->nr_entries);
623 assert((char **)browser->top >= (char **)browser->entries);
622} 624}
623 625
624unsigned int ui_browser__argv_refresh(struct ui_browser *browser) 626unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
@@ -630,7 +632,9 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
630 browser->top = browser->entries; 632 browser->top = browser->entries;
631 633
632 pos = (char **)browser->top; 634 pos = (char **)browser->top;
633 while (idx < browser->nr_entries) { 635 while (idx < browser->nr_entries &&
636 row < (unsigned)SLtt_Screen_Rows - 1) {
637 assert(pos < (char **)browser->entries + browser->nr_entries);
634 if (!browser->filter || !browser->filter(browser, *pos)) { 638 if (!browser->filter || !browser->filter(browser, *pos)) {
635 ui_browser__gotorc(browser, row, 0); 639 ui_browser__gotorc(browser, row, 0);
636 browser->write(browser, pos, row); 640 browser->write(browser, pos, row);
diff --git a/tools/perf/ui/browsers/Build b/tools/perf/ui/browsers/Build
index 8fee56b46502..fdf86f7981ca 100644
--- a/tools/perf/ui/browsers/Build
+++ b/tools/perf/ui/browsers/Build
@@ -3,6 +3,7 @@ perf-y += hists.o
3perf-y += map.o 3perf-y += map.o
4perf-y += scripts.o 4perf-y += scripts.o
5perf-y += header.o 5perf-y += header.o
6perf-y += res_sample.o
6 7
7CFLAGS_annotate.o += -DENABLE_SLFUTURE_CONST 8CFLAGS_annotate.o += -DENABLE_SLFUTURE_CONST
8CFLAGS_hists.o += -DENABLE_SLFUTURE_CONST 9CFLAGS_hists.o += -DENABLE_SLFUTURE_CONST
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 35bdfd8b1e71..98d934a36d86 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -750,7 +750,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
750 continue; 750 continue;
751 case 'r': 751 case 'r':
752 { 752 {
753 script_browse(NULL); 753 script_browse(NULL, NULL);
754 continue; 754 continue;
755 } 755 }
756 case 'k': 756 case 'k':
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index aef800d97ea1..3421ecbdd3f0 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -7,6 +7,7 @@
7#include <string.h> 7#include <string.h>
8#include <linux/rbtree.h> 8#include <linux/rbtree.h>
9#include <sys/ttydefaults.h> 9#include <sys/ttydefaults.h>
10#include <linux/time64.h>
10 11
11#include "../../util/callchain.h" 12#include "../../util/callchain.h"
12#include "../../util/evsel.h" 13#include "../../util/evsel.h"
@@ -30,6 +31,7 @@
30#include "srcline.h" 31#include "srcline.h"
31#include "string2.h" 32#include "string2.h"
32#include "units.h" 33#include "units.h"
34#include "time-utils.h"
33 35
34#include "sane_ctype.h" 36#include "sane_ctype.h"
35 37
@@ -1224,6 +1226,8 @@ void hist_browser__init_hpp(void)
1224 hist_browser__hpp_color_overhead_guest_us; 1226 hist_browser__hpp_color_overhead_guest_us;
1225 perf_hpp__format[PERF_HPP__OVERHEAD_ACC].color = 1227 perf_hpp__format[PERF_HPP__OVERHEAD_ACC].color =
1226 hist_browser__hpp_color_overhead_acc; 1228 hist_browser__hpp_color_overhead_acc;
1229
1230 res_sample_init();
1227} 1231}
1228 1232
1229static int hist_browser__show_entry(struct hist_browser *browser, 1233static int hist_browser__show_entry(struct hist_browser *browser,
@@ -2338,9 +2342,12 @@ close_file_and_continue:
2338} 2342}
2339 2343
2340struct popup_action { 2344struct popup_action {
2345 unsigned long time;
2341 struct thread *thread; 2346 struct thread *thread;
2342 struct map_symbol ms; 2347 struct map_symbol ms;
2343 int socket; 2348 int socket;
2349 struct perf_evsel *evsel;
2350 enum rstype rstype;
2344 2351
2345 int (*fn)(struct hist_browser *browser, struct popup_action *act); 2352 int (*fn)(struct hist_browser *browser, struct popup_action *act);
2346}; 2353};
@@ -2527,46 +2534,137 @@ static int
2527do_run_script(struct hist_browser *browser __maybe_unused, 2534do_run_script(struct hist_browser *browser __maybe_unused,
2528 struct popup_action *act) 2535 struct popup_action *act)
2529{ 2536{
2530 char script_opt[64]; 2537 char *script_opt;
2531 memset(script_opt, 0, sizeof(script_opt)); 2538 int len;
2539 int n = 0;
2532 2540
2541 len = 100;
2542 if (act->thread)
2543 len += strlen(thread__comm_str(act->thread));
2544 else if (act->ms.sym)
2545 len += strlen(act->ms.sym->name);
2546 script_opt = malloc(len);
2547 if (!script_opt)
2548 return -1;
2549
2550 script_opt[0] = 0;
2533 if (act->thread) { 2551 if (act->thread) {
2534 scnprintf(script_opt, sizeof(script_opt), " -c %s ", 2552 n = scnprintf(script_opt, len, " -c %s ",
2535 thread__comm_str(act->thread)); 2553 thread__comm_str(act->thread));
2536 } else if (act->ms.sym) { 2554 } else if (act->ms.sym) {
2537 scnprintf(script_opt, sizeof(script_opt), " -S %s ", 2555 n = scnprintf(script_opt, len, " -S %s ",
2538 act->ms.sym->name); 2556 act->ms.sym->name);
2539 } 2557 }
2540 2558
2541 script_browse(script_opt); 2559 if (act->time) {
2560 char start[32], end[32];
2561 unsigned long starttime = act->time;
2562 unsigned long endtime = act->time + symbol_conf.time_quantum;
2563
2564 if (starttime == endtime) { /* Display 1ms as fallback */
2565 starttime -= 1*NSEC_PER_MSEC;
2566 endtime += 1*NSEC_PER_MSEC;
2567 }
2568 timestamp__scnprintf_usec(starttime, start, sizeof start);
2569 timestamp__scnprintf_usec(endtime, end, sizeof end);
2570 n += snprintf(script_opt + n, len - n, " --time %s,%s", start, end);
2571 }
2572
2573 script_browse(script_opt, act->evsel);
2574 free(script_opt);
2542 return 0; 2575 return 0;
2543} 2576}
2544 2577
2545static int 2578static int
2546add_script_opt(struct hist_browser *browser __maybe_unused, 2579do_res_sample_script(struct hist_browser *browser __maybe_unused,
2580 struct popup_action *act)
2581{
2582 struct hist_entry *he;
2583
2584 he = hist_browser__selected_entry(browser);
2585 res_sample_browse(he->res_samples, he->num_res, act->evsel, act->rstype);
2586 return 0;
2587}
2588
2589static int
2590add_script_opt_2(struct hist_browser *browser __maybe_unused,
2547 struct popup_action *act, char **optstr, 2591 struct popup_action *act, char **optstr,
2548 struct thread *thread, struct symbol *sym) 2592 struct thread *thread, struct symbol *sym,
2593 struct perf_evsel *evsel, const char *tstr)
2549{ 2594{
2595
2550 if (thread) { 2596 if (thread) {
2551 if (asprintf(optstr, "Run scripts for samples of thread [%s]", 2597 if (asprintf(optstr, "Run scripts for samples of thread [%s]%s",
2552 thread__comm_str(thread)) < 0) 2598 thread__comm_str(thread), tstr) < 0)
2553 return 0; 2599 return 0;
2554 } else if (sym) { 2600 } else if (sym) {
2555 if (asprintf(optstr, "Run scripts for samples of symbol [%s]", 2601 if (asprintf(optstr, "Run scripts for samples of symbol [%s]%s",
2556 sym->name) < 0) 2602 sym->name, tstr) < 0)
2557 return 0; 2603 return 0;
2558 } else { 2604 } else {
2559 if (asprintf(optstr, "Run scripts for all samples") < 0) 2605 if (asprintf(optstr, "Run scripts for all samples%s", tstr) < 0)
2560 return 0; 2606 return 0;
2561 } 2607 }
2562 2608
2563 act->thread = thread; 2609 act->thread = thread;
2564 act->ms.sym = sym; 2610 act->ms.sym = sym;
2611 act->evsel = evsel;
2565 act->fn = do_run_script; 2612 act->fn = do_run_script;
2566 return 1; 2613 return 1;
2567} 2614}
2568 2615
2569static int 2616static int
2617add_script_opt(struct hist_browser *browser,
2618 struct popup_action *act, char **optstr,
2619 struct thread *thread, struct symbol *sym,
2620 struct perf_evsel *evsel)
2621{
2622 int n, j;
2623 struct hist_entry *he;
2624
2625 n = add_script_opt_2(browser, act, optstr, thread, sym, evsel, "");
2626
2627 he = hist_browser__selected_entry(browser);
2628 if (sort_order && strstr(sort_order, "time")) {
2629 char tstr[128];
2630
2631 optstr++;
2632 act++;
2633 j = sprintf(tstr, " in ");
2634 j += timestamp__scnprintf_usec(he->time, tstr + j,
2635 sizeof tstr - j);
2636 j += sprintf(tstr + j, "-");
2637 timestamp__scnprintf_usec(he->time + symbol_conf.time_quantum,
2638 tstr + j, sizeof tstr - j);
2639 n += add_script_opt_2(browser, act, optstr, thread, sym,
2640 evsel, tstr);
2641 act->time = he->time;
2642 }
2643 return n;
2644}
2645
2646static int
2647add_res_sample_opt(struct hist_browser *browser __maybe_unused,
2648 struct popup_action *act, char **optstr,
2649 struct res_sample *res_sample,
2650 struct perf_evsel *evsel,
2651 enum rstype type)
2652{
2653 if (!res_sample)
2654 return 0;
2655
2656 if (asprintf(optstr, "Show context for individual samples %s",
2657 type == A_ASM ? "with assembler" :
2658 type == A_SOURCE ? "with source" : "") < 0)
2659 return 0;
2660
2661 act->fn = do_res_sample_script;
2662 act->evsel = evsel;
2663 act->rstype = type;
2664 return 1;
2665}
2666
2667static int
2570do_switch_data(struct hist_browser *browser __maybe_unused, 2668do_switch_data(struct hist_browser *browser __maybe_unused,
2571 struct popup_action *act __maybe_unused) 2669 struct popup_action *act __maybe_unused)
2572{ 2670{
@@ -3031,7 +3129,7 @@ skip_annotation:
3031 nr_options += add_script_opt(browser, 3129 nr_options += add_script_opt(browser,
3032 &actions[nr_options], 3130 &actions[nr_options],
3033 &options[nr_options], 3131 &options[nr_options],
3034 thread, NULL); 3132 thread, NULL, evsel);
3035 } 3133 }
3036 /* 3134 /*
3037 * Note that browser->selection != NULL 3135 * Note that browser->selection != NULL
@@ -3046,11 +3144,24 @@ skip_annotation:
3046 nr_options += add_script_opt(browser, 3144 nr_options += add_script_opt(browser,
3047 &actions[nr_options], 3145 &actions[nr_options],
3048 &options[nr_options], 3146 &options[nr_options],
3049 NULL, browser->selection->sym); 3147 NULL, browser->selection->sym,
3148 evsel);
3050 } 3149 }
3051 } 3150 }
3052 nr_options += add_script_opt(browser, &actions[nr_options], 3151 nr_options += add_script_opt(browser, &actions[nr_options],
3053 &options[nr_options], NULL, NULL); 3152 &options[nr_options], NULL, NULL, evsel);
3153 nr_options += add_res_sample_opt(browser, &actions[nr_options],
3154 &options[nr_options],
3155 hist_browser__selected_entry(browser)->res_samples,
3156 evsel, A_NORMAL);
3157 nr_options += add_res_sample_opt(browser, &actions[nr_options],
3158 &options[nr_options],
3159 hist_browser__selected_entry(browser)->res_samples,
3160 evsel, A_ASM);
3161 nr_options += add_res_sample_opt(browser, &actions[nr_options],
3162 &options[nr_options],
3163 hist_browser__selected_entry(browser)->res_samples,
3164 evsel, A_SOURCE);
3054 nr_options += add_switch_opt(browser, &actions[nr_options], 3165 nr_options += add_switch_opt(browser, &actions[nr_options],
3055 &options[nr_options]); 3166 &options[nr_options]);
3056skip_scripting: 3167skip_scripting:
diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c
new file mode 100644
index 000000000000..c0dd73176d42
--- /dev/null
+++ b/tools/perf/ui/browsers/res_sample.c
@@ -0,0 +1,91 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Display a menu with individual samples to browse with perf script */
3#include "util.h"
4#include "hist.h"
5#include "evsel.h"
6#include "hists.h"
7#include "sort.h"
8#include "config.h"
9#include "time-utils.h"
10#include <linux/time64.h>
11
12static u64 context_len = 10 * NSEC_PER_MSEC;
13
14static int res_sample_config(const char *var, const char *value, void *data __maybe_unused)
15{
16 if (!strcmp(var, "samples.context"))
17 return perf_config_u64(&context_len, var, value);
18 return 0;
19}
20
21void res_sample_init(void)
22{
23 perf_config(res_sample_config, NULL);
24}
25
26int res_sample_browse(struct res_sample *res_samples, int num_res,
27 struct perf_evsel *evsel, enum rstype rstype)
28{
29 char **names;
30 int i, n;
31 int choice;
32 char *cmd;
33 char pbuf[256], tidbuf[32], cpubuf[32];
34 const char *perf = perf_exe(pbuf, sizeof pbuf);
35 char trange[128], tsample[64];
36 struct res_sample *r;
37 char extra_format[256];
38
39 names = calloc(num_res, sizeof(char *));
40 if (!names)
41 return -1;
42 for (i = 0; i < num_res; i++) {
43 char tbuf[64];
44
45 timestamp__scnprintf_nsec(res_samples[i].time, tbuf, sizeof tbuf);
46 if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf,
47 res_samples[i].cpu, res_samples[i].tid) < 0) {
48 while (--i >= 0)
49 free(names[i]);
50 free(names);
51 return -1;
52 }
53 }
54 choice = ui__popup_menu(num_res, names);
55 for (i = 0; i < num_res; i++)
56 free(names[i]);
57 free(names);
58
59 if (choice < 0 || choice >= num_res)
60 return -1;
61 r = &res_samples[choice];
62
63 n = timestamp__scnprintf_nsec(r->time - context_len, trange, sizeof trange);
64 trange[n++] = ',';
65 timestamp__scnprintf_nsec(r->time + context_len, trange + n, sizeof trange - n);
66
67 timestamp__scnprintf_nsec(r->time, tsample, sizeof tsample);
68
69 attr_to_script(extra_format, &evsel->attr);
70
71 if (asprintf(&cmd, "%s script %s%s --time %s %s%s %s%s --ns %s %s %s %s %s | less +/%s",
72 perf,
73 input_name ? "-i " : "",
74 input_name ? input_name : "",
75 trange,
76 r->cpu >= 0 ? "--cpu " : "",
77 r->cpu >= 0 ? (sprintf(cpubuf, "%d", r->cpu), cpubuf) : "",
78 r->tid ? "--tid " : "",
79 r->tid ? (sprintf(tidbuf, "%d", r->tid), tidbuf) : "",
80 extra_format,
81 rstype == A_ASM ? "-F +insn --xed" :
82 rstype == A_SOURCE ? "-F +srcline,+srccode" : "",
83 symbol_conf.inline_name ? "--inline" : "",
84 "--show-lost-events ",
85 r->tid ? "--show-switch-events --show-task-events " : "",
86 tsample) < 0)
87 return -1;
88 run_script(cmd);
89 free(cmd);
90 return 0;
91}
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index 90a32ac69e76..27cf3ab88d13 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -1,34 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <elf.h>
3#include <inttypes.h>
4#include <sys/ttydefaults.h>
5#include <string.h>
6#include "../../util/sort.h" 2#include "../../util/sort.h"
7#include "../../util/util.h" 3#include "../../util/util.h"
8#include "../../util/hist.h" 4#include "../../util/hist.h"
9#include "../../util/debug.h" 5#include "../../util/debug.h"
10#include "../../util/symbol.h" 6#include "../../util/symbol.h"
11#include "../browser.h" 7#include "../browser.h"
12#include "../helpline.h"
13#include "../libslang.h" 8#include "../libslang.h"
14 9#include "config.h"
15/* 2048 lines should be enough for a script output */
16#define MAX_LINES 2048
17
18/* 160 bytes for one output line */
19#define AVERAGE_LINE_LEN 160
20
21struct script_line {
22 struct list_head node;
23 char line[AVERAGE_LINE_LEN];
24};
25
26struct perf_script_browser {
27 struct ui_browser b;
28 struct list_head entries;
29 const char *script_name;
30 int nr_lines;
31};
32 10
33#define SCRIPT_NAMELEN 128 11#define SCRIPT_NAMELEN 128
34#define SCRIPT_MAX_NO 64 12#define SCRIPT_MAX_NO 64
@@ -40,149 +18,169 @@ struct perf_script_browser {
40 */ 18 */
41#define SCRIPT_FULLPATH_LEN 256 19#define SCRIPT_FULLPATH_LEN 256
42 20
21struct script_config {
22 const char **names;
23 char **paths;
24 int index;
25 const char *perf;
26 char extra_format[256];
27};
28
29void attr_to_script(char *extra_format, struct perf_event_attr *attr)
30{
31 extra_format[0] = 0;
32 if (attr->read_format & PERF_FORMAT_GROUP)
33 strcat(extra_format, " -F +metric");
34 if (attr->sample_type & PERF_SAMPLE_BRANCH_STACK)
35 strcat(extra_format, " -F +brstackinsn --xed");
36 if (attr->sample_type & PERF_SAMPLE_REGS_INTR)
37 strcat(extra_format, " -F +iregs");
38 if (attr->sample_type & PERF_SAMPLE_REGS_USER)
39 strcat(extra_format, " -F +uregs");
40 if (attr->sample_type & PERF_SAMPLE_PHYS_ADDR)
41 strcat(extra_format, " -F +phys_addr");
42}
43
44static int add_script_option(const char *name, const char *opt,
45 struct script_config *c)
46{
47 c->names[c->index] = name;
48 if (asprintf(&c->paths[c->index],
49 "%s script %s -F +metric %s %s",
50 c->perf, opt, symbol_conf.inline_name ? " --inline" : "",
51 c->extra_format) < 0)
52 return -1;
53 c->index++;
54 return 0;
55}
56
57static int scripts_config(const char *var, const char *value, void *data)
58{
59 struct script_config *c = data;
60
61 if (!strstarts(var, "scripts."))
62 return -1;
63 if (c->index >= SCRIPT_MAX_NO)
64 return -1;
65 c->names[c->index] = strdup(var + 7);
66 if (!c->names[c->index])
67 return -1;
68 if (asprintf(&c->paths[c->index], "%s %s", value,
69 c->extra_format) < 0)
70 return -1;
71 c->index++;
72 return 0;
73}
74
43/* 75/*
44 * When success, will copy the full path of the selected script 76 * When success, will copy the full path of the selected script
45 * into the buffer pointed by script_name, and return 0. 77 * into the buffer pointed by script_name, and return 0.
46 * Return -1 on failure. 78 * Return -1 on failure.
47 */ 79 */
48static int list_scripts(char *script_name) 80static int list_scripts(char *script_name, bool *custom,
81 struct perf_evsel *evsel)
49{ 82{
50 char *buf, *names[SCRIPT_MAX_NO], *paths[SCRIPT_MAX_NO]; 83 char *buf, *paths[SCRIPT_MAX_NO], *names[SCRIPT_MAX_NO];
51 int i, num, choice, ret = -1; 84 int i, num, choice;
85 int ret = 0;
86 int max_std, custom_perf;
87 char pbuf[256];
88 const char *perf = perf_exe(pbuf, sizeof pbuf);
89 struct script_config scriptc = {
90 .names = (const char **)names,
91 .paths = paths,
92 .perf = perf
93 };
94
95 script_name[0] = 0;
52 96
53 /* Preset the script name to SCRIPT_NAMELEN */ 97 /* Preset the script name to SCRIPT_NAMELEN */
54 buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN)); 98 buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN));
55 if (!buf) 99 if (!buf)
56 return ret; 100 return -1;
57 101
58 for (i = 0; i < SCRIPT_MAX_NO; i++) { 102 if (evsel)
59 names[i] = buf + i * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN); 103 attr_to_script(scriptc.extra_format, &evsel->attr);
104 add_script_option("Show individual samples", "", &scriptc);
105 add_script_option("Show individual samples with assembler", "-F +insn --xed",
106 &scriptc);
107 add_script_option("Show individual samples with source", "-F +srcline,+srccode",
108 &scriptc);
109 perf_config(scripts_config, &scriptc);
110 custom_perf = scriptc.index;
111 add_script_option("Show samples with custom perf script arguments", "", &scriptc);
112 i = scriptc.index;
113 max_std = i;
114
115 for (; i < SCRIPT_MAX_NO; i++) {
116 names[i] = buf + (i - max_std) * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN);
60 paths[i] = names[i] + SCRIPT_NAMELEN; 117 paths[i] = names[i] + SCRIPT_NAMELEN;
61 } 118 }
62 119
63 num = find_scripts(names, paths); 120 num = find_scripts(names + max_std, paths + max_std, SCRIPT_MAX_NO - max_std,
64 if (num > 0) { 121 SCRIPT_FULLPATH_LEN);
65 choice = ui__popup_menu(num, names); 122 if (num < 0)
66 if (choice < num && choice >= 0) { 123 num = 0;
67 strcpy(script_name, paths[choice]); 124 choice = ui__popup_menu(num + max_std, (char * const *)names);
68 ret = 0; 125 if (choice < 0) {
69 } 126 ret = -1;
127 goto out;
70 } 128 }
129 if (choice == custom_perf) {
130 char script_args[50];
131 int key = ui_browser__input_window("perf script command",
132 "Enter perf script command line (without perf script prefix)",
133 script_args, "", 0);
134 if (key != K_ENTER)
135 return -1;
136 sprintf(script_name, "%s script %s", perf, script_args);
137 } else if (choice < num + max_std) {
138 strcpy(script_name, paths[choice]);
139 }
140 *custom = choice >= max_std;
71 141
142out:
72 free(buf); 143 free(buf);
144 for (i = 0; i < max_std; i++)
145 free(paths[i]);
73 return ret; 146 return ret;
74} 147}
75 148
76static void script_browser__write(struct ui_browser *browser, 149void run_script(char *cmd)
77 void *entry, int row)
78{ 150{
79 struct script_line *sline = list_entry(entry, struct script_line, node); 151 pr_debug("Running %s\n", cmd);
80 bool current_entry = ui_browser__is_current_entry(browser, row); 152 SLang_reset_tty();
81 153 if (system(cmd) < 0)
82 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : 154 pr_warning("Cannot run %s\n", cmd);
83 HE_COLORSET_NORMAL); 155 /*
84 156 * SLang doesn't seem to reset the whole terminal, so be more
85 ui_browser__write_nstring(browser, sline->line, browser->width); 157 * forceful to get back to the original state.
158 */
159 printf("\033[c\033[H\033[J");
160 fflush(stdout);
161 SLang_init_tty(0, 0, 0);
162 SLsmg_refresh();
86} 163}
87 164
88static int script_browser__run(struct perf_script_browser *browser) 165int script_browse(const char *script_opt, struct perf_evsel *evsel)
89{ 166{
90 int key; 167 char *cmd, script_name[SCRIPT_FULLPATH_LEN];
168 bool custom = false;
91 169
92 if (ui_browser__show(&browser->b, browser->script_name, 170 memset(script_name, 0, SCRIPT_FULLPATH_LEN);
93 "Press ESC to exit") < 0) 171 if (list_scripts(script_name, &custom, evsel))
94 return -1; 172 return -1;
95 173
96 while (1) { 174 if (asprintf(&cmd, "%s%s %s %s%s 2>&1 | less",
97 key = ui_browser__run(&browser->b, 0); 175 custom ? "perf script -s " : "",
98 176 script_name,
99 /* We can add some special key handling here if needed */ 177 script_opt ? script_opt : "",
100 break; 178 input_name ? "-i " : "",
101 } 179 input_name ? input_name : "") < 0)
102
103 ui_browser__hide(&browser->b);
104 return key;
105}
106
107
108int script_browse(const char *script_opt)
109{
110 char cmd[SCRIPT_FULLPATH_LEN*2], script_name[SCRIPT_FULLPATH_LEN];
111 char *line = NULL;
112 size_t len = 0;
113 ssize_t retlen;
114 int ret = -1, nr_entries = 0;
115 FILE *fp;
116 void *buf;
117 struct script_line *sline;
118
119 struct perf_script_browser script = {
120 .b = {
121 .refresh = ui_browser__list_head_refresh,
122 .seek = ui_browser__list_head_seek,
123 .write = script_browser__write,
124 },
125 .script_name = script_name,
126 };
127
128 INIT_LIST_HEAD(&script.entries);
129
130 /* Save each line of the output in one struct script_line object. */
131 buf = zalloc((sizeof(*sline)) * MAX_LINES);
132 if (!buf)
133 return -1; 180 return -1;
134 sline = buf;
135
136 memset(script_name, 0, SCRIPT_FULLPATH_LEN);
137 if (list_scripts(script_name))
138 goto exit;
139
140 sprintf(cmd, "perf script -s %s ", script_name);
141 181
142 if (script_opt) 182 run_script(cmd);
143 strcat(cmd, script_opt); 183 free(cmd);
144 184
145 if (input_name) { 185 return 0;
146 strcat(cmd, " -i ");
147 strcat(cmd, input_name);
148 }
149
150 strcat(cmd, " 2>&1");
151
152 fp = popen(cmd, "r");
153 if (!fp)
154 goto exit;
155
156 while ((retlen = getline(&line, &len, fp)) != -1) {
157 strncpy(sline->line, line, AVERAGE_LINE_LEN);
158
159 /* If one output line is very large, just cut it short */
160 if (retlen >= AVERAGE_LINE_LEN) {
161 sline->line[AVERAGE_LINE_LEN - 1] = '\0';
162 sline->line[AVERAGE_LINE_LEN - 2] = '\n';
163 }
164 list_add_tail(&sline->node, &script.entries);
165
166 if (script.b.width < retlen)
167 script.b.width = retlen;
168
169 if (nr_entries++ >= MAX_LINES - 1)
170 break;
171 sline++;
172 }
173
174 if (script.b.width > AVERAGE_LINE_LEN)
175 script.b.width = AVERAGE_LINE_LEN;
176
177 free(line);
178 pclose(fp);
179
180 script.nr_lines = nr_entries;
181 script.b.nr_entries = nr_entries;
182 script.b.entries = &script.entries;
183
184 ret = script_browser__run(&script);
185exit:
186 free(buf);
187 return ret;
188} 186}
diff --git a/tools/perf/util/archinsn.h b/tools/perf/util/archinsn.h
new file mode 100644
index 000000000000..448cbb6b8d7e
--- /dev/null
+++ b/tools/perf/util/archinsn.h
@@ -0,0 +1,12 @@
1#ifndef INSN_H
2#define INSN_H 1
3
4struct perf_sample;
5struct machine;
6struct thread;
7
8void arch_fetch_insn(struct perf_sample *sample,
9 struct thread *thread,
10 struct machine *machine);
11
12#endif
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index e098e189f93e..c6b67efea11a 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -14,6 +14,7 @@
14#include "data.h" 14#include "data.h"
15#include "util.h" 15#include "util.h"
16#include "debug.h" 16#include "debug.h"
17#include "header.h"
17 18
18static void close_dir(struct perf_data_file *files, int nr) 19static void close_dir(struct perf_data_file *files, int nr)
19{ 20{
@@ -34,12 +35,16 @@ int perf_data__create_dir(struct perf_data *data, int nr)
34 struct perf_data_file *files = NULL; 35 struct perf_data_file *files = NULL;
35 int i, ret = -1; 36 int i, ret = -1;
36 37
38 if (WARN_ON(!data->is_dir))
39 return -EINVAL;
40
37 files = zalloc(nr * sizeof(*files)); 41 files = zalloc(nr * sizeof(*files));
38 if (!files) 42 if (!files)
39 return -ENOMEM; 43 return -ENOMEM;
40 44
41 data->dir.files = files; 45 data->dir.version = PERF_DIR_VERSION;
42 data->dir.nr = nr; 46 data->dir.files = files;
47 data->dir.nr = nr;
43 48
44 for (i = 0; i < nr; i++) { 49 for (i = 0; i < nr; i++) {
45 struct perf_data_file *file = &files[i]; 50 struct perf_data_file *file = &files[i];
@@ -69,6 +74,13 @@ int perf_data__open_dir(struct perf_data *data)
69 DIR *dir; 74 DIR *dir;
70 int nr = 0; 75 int nr = 0;
71 76
77 if (WARN_ON(!data->is_dir))
78 return -EINVAL;
79
80 /* The version is provided by DIR_FORMAT feature. */
81 if (WARN_ON(data->dir.version != PERF_DIR_VERSION))
82 return -1;
83
72 dir = opendir(data->path); 84 dir = opendir(data->path);
73 if (!dir) 85 if (!dir)
74 return -EINVAL; 86 return -EINVAL;
@@ -118,6 +130,26 @@ out_err:
118 return ret; 130 return ret;
119} 131}
120 132
133int perf_data__update_dir(struct perf_data *data)
134{
135 int i;
136
137 if (WARN_ON(!data->is_dir))
138 return -EINVAL;
139
140 for (i = 0; i < data->dir.nr; i++) {
141 struct perf_data_file *file = &data->dir.files[i];
142 struct stat st;
143
144 if (fstat(file->fd, &st))
145 return -1;
146
147 file->size = st.st_size;
148 }
149
150 return 0;
151}
152
121static bool check_pipe(struct perf_data *data) 153static bool check_pipe(struct perf_data *data)
122{ 154{
123 struct stat st; 155 struct stat st;
@@ -173,6 +205,16 @@ static int check_backup(struct perf_data *data)
173 return 0; 205 return 0;
174} 206}
175 207
208static bool is_dir(struct perf_data *data)
209{
210 struct stat st;
211
212 if (stat(data->path, &st))
213 return false;
214
215 return (st.st_mode & S_IFMT) == S_IFDIR;
216}
217
176static int open_file_read(struct perf_data *data) 218static int open_file_read(struct perf_data *data)
177{ 219{
178 struct stat st; 220 struct stat st;
@@ -254,6 +296,30 @@ static int open_file_dup(struct perf_data *data)
254 return open_file(data); 296 return open_file(data);
255} 297}
256 298
299static int open_dir(struct perf_data *data)
300{
301 int ret;
302
303 /*
304 * So far we open only the header, so we can read the data version and
305 * layout.
306 */
307 if (asprintf(&data->file.path, "%s/header", data->path) < 0)
308 return -1;
309
310 if (perf_data__is_write(data) &&
311 mkdir(data->path, S_IRWXU) < 0)
312 return -1;
313
314 ret = open_file(data);
315
316 /* Cleanup whatever we managed to create so far. */
317 if (ret && perf_data__is_write(data))
318 rm_rf_perf_data(data->path);
319
320 return ret;
321}
322
257int perf_data__open(struct perf_data *data) 323int perf_data__open(struct perf_data *data)
258{ 324{
259 if (check_pipe(data)) 325 if (check_pipe(data))
@@ -265,11 +331,18 @@ int perf_data__open(struct perf_data *data)
265 if (check_backup(data)) 331 if (check_backup(data))
266 return -1; 332 return -1;
267 333
268 return open_file_dup(data); 334 if (perf_data__is_read(data))
335 data->is_dir = is_dir(data);
336
337 return perf_data__is_dir(data) ?
338 open_dir(data) : open_file_dup(data);
269} 339}
270 340
271void perf_data__close(struct perf_data *data) 341void perf_data__close(struct perf_data *data)
272{ 342{
343 if (perf_data__is_dir(data))
344 perf_data__close_dir(data);
345
273 zfree(&data->file.path); 346 zfree(&data->file.path);
274 close(data->file.fd); 347 close(data->file.fd);
275} 348}
@@ -326,3 +399,20 @@ out:
326 free(new_filepath); 399 free(new_filepath);
327 return ret; 400 return ret;
328} 401}
402
403unsigned long perf_data__size(struct perf_data *data)
404{
405 u64 size = data->file.size;
406 int i;
407
408 if (!data->is_dir)
409 return size;
410
411 for (i = 0; i < data->dir.nr; i++) {
412 struct perf_data_file *file = &data->dir.files[i];
413
414 size += file->size;
415 }
416
417 return size;
418}
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h
index 14b47be2bd69..6aef8746469f 100644
--- a/tools/perf/util/data.h
+++ b/tools/perf/util/data.h
@@ -19,10 +19,12 @@ struct perf_data {
19 const char *path; 19 const char *path;
20 struct perf_data_file file; 20 struct perf_data_file file;
21 bool is_pipe; 21 bool is_pipe;
22 bool is_dir;
22 bool force; 23 bool force;
23 enum perf_data_mode mode; 24 enum perf_data_mode mode;
24 25
25 struct { 26 struct {
27 u64 version;
26 struct perf_data_file *files; 28 struct perf_data_file *files;
27 int nr; 29 int nr;
28 } dir; 30 } dir;
@@ -43,14 +45,14 @@ static inline int perf_data__is_pipe(struct perf_data *data)
43 return data->is_pipe; 45 return data->is_pipe;
44} 46}
45 47
46static inline int perf_data__fd(struct perf_data *data) 48static inline bool perf_data__is_dir(struct perf_data *data)
47{ 49{
48 return data->file.fd; 50 return data->is_dir;
49} 51}
50 52
51static inline unsigned long perf_data__size(struct perf_data *data) 53static inline int perf_data__fd(struct perf_data *data)
52{ 54{
53 return data->file.size; 55 return data->file.fd;
54} 56}
55 57
56int perf_data__open(struct perf_data *data); 58int perf_data__open(struct perf_data *data);
@@ -73,4 +75,6 @@ int perf_data__switch(struct perf_data *data,
73int perf_data__create_dir(struct perf_data *data, int nr); 75int perf_data__create_dir(struct perf_data *data, int nr);
74int perf_data__open_dir(struct perf_data *data); 76int perf_data__open_dir(struct perf_data *data);
75void perf_data__close_dir(struct perf_data *data); 77void perf_data__close_dir(struct perf_data *data);
78int perf_data__update_dir(struct perf_data *data);
79unsigned long perf_data__size(struct perf_data *data);
76#endif /* __PERF_DATA_H */ 80#endif /* __PERF_DATA_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 01b324c275b9..b0683bf4d9f3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -861,6 +861,21 @@ static int write_clockid(struct feat_fd *ff,
861 sizeof(ff->ph->env.clockid_res_ns)); 861 sizeof(ff->ph->env.clockid_res_ns));
862} 862}
863 863
864static int write_dir_format(struct feat_fd *ff,
865 struct perf_evlist *evlist __maybe_unused)
866{
867 struct perf_session *session;
868 struct perf_data *data;
869
870 session = container_of(ff->ph, struct perf_session, header);
871 data = session->data;
872
873 if (WARN_ON(!perf_data__is_dir(data)))
874 return -1;
875
876 return do_write(ff, &data->dir.version, sizeof(data->dir.version));
877}
878
864static int cpu_cache_level__sort(const void *a, const void *b) 879static int cpu_cache_level__sort(const void *a, const void *b)
865{ 880{
866 struct cpu_cache_level *cache_a = (struct cpu_cache_level *)a; 881 struct cpu_cache_level *cache_a = (struct cpu_cache_level *)a;
@@ -1341,6 +1356,17 @@ static void print_clockid(struct feat_fd *ff, FILE *fp)
1341 ff->ph->env.clockid_res_ns * 1000); 1356 ff->ph->env.clockid_res_ns * 1000);
1342} 1357}
1343 1358
1359static void print_dir_format(struct feat_fd *ff, FILE *fp)
1360{
1361 struct perf_session *session;
1362 struct perf_data *data;
1363
1364 session = container_of(ff->ph, struct perf_session, header);
1365 data = session->data;
1366
1367 fprintf(fp, "# directory data version : %"PRIu64"\n", data->dir.version);
1368}
1369
1344static void free_event_desc(struct perf_evsel *events) 1370static void free_event_desc(struct perf_evsel *events)
1345{ 1371{
1346 struct perf_evsel *evsel; 1372 struct perf_evsel *evsel;
@@ -2373,6 +2399,21 @@ static int process_clockid(struct feat_fd *ff,
2373 return 0; 2399 return 0;
2374} 2400}
2375 2401
2402static int process_dir_format(struct feat_fd *ff,
2403 void *_data __maybe_unused)
2404{
2405 struct perf_session *session;
2406 struct perf_data *data;
2407
2408 session = container_of(ff->ph, struct perf_session, header);
2409 data = session->data;
2410
2411 if (WARN_ON(!perf_data__is_dir(data)))
2412 return -1;
2413
2414 return do_read_u64(ff, &data->dir.version);
2415}
2416
2376struct feature_ops { 2417struct feature_ops {
2377 int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); 2418 int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
2378 void (*print)(struct feat_fd *ff, FILE *fp); 2419 void (*print)(struct feat_fd *ff, FILE *fp);
@@ -2432,7 +2473,8 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
2432 FEAT_OPN(CACHE, cache, true), 2473 FEAT_OPN(CACHE, cache, true),
2433 FEAT_OPR(SAMPLE_TIME, sample_time, false), 2474 FEAT_OPR(SAMPLE_TIME, sample_time, false),
2434 FEAT_OPR(MEM_TOPOLOGY, mem_topology, true), 2475 FEAT_OPR(MEM_TOPOLOGY, mem_topology, true),
2435 FEAT_OPR(CLOCKID, clockid, false) 2476 FEAT_OPR(CLOCKID, clockid, false),
2477 FEAT_OPN(DIR_FORMAT, dir_format, false)
2436}; 2478};
2437 2479
2438struct header_print_data { 2480struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 0d553ddca0a3..6a231340238d 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -39,6 +39,7 @@ enum {
39 HEADER_SAMPLE_TIME, 39 HEADER_SAMPLE_TIME,
40 HEADER_MEM_TOPOLOGY, 40 HEADER_MEM_TOPOLOGY,
41 HEADER_CLOCKID, 41 HEADER_CLOCKID,
42 HEADER_DIR_FORMAT,
42 HEADER_LAST_FEATURE, 43 HEADER_LAST_FEATURE,
43 HEADER_FEAT_BITS = 256, 44 HEADER_FEAT_BITS = 256,
44}; 45};
@@ -48,6 +49,10 @@ enum perf_header_version {
48 PERF_HEADER_VERSION_2, 49 PERF_HEADER_VERSION_2,
49}; 50};
50 51
52enum perf_dir_version {
53 PERF_DIR_VERSION = 1,
54};
55
51struct perf_file_section { 56struct perf_file_section {
52 u64 offset; 57 u64 offset;
53 u64 size; 58 u64 size;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f9eb95bf3938..1f230285d78a 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -19,6 +19,7 @@
19#include <math.h> 19#include <math.h>
20#include <inttypes.h> 20#include <inttypes.h>
21#include <sys/param.h> 21#include <sys/param.h>
22#include <linux/time64.h>
22 23
23static bool hists__filter_entry_by_dso(struct hists *hists, 24static bool hists__filter_entry_by_dso(struct hists *hists,
24 struct hist_entry *he); 25 struct hist_entry *he);
@@ -192,6 +193,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
192 hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3); 193 hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
193 hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12); 194 hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
194 hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12); 195 hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
196 hists__new_col_len(hists, HISTC_TIME, 12);
195 197
196 if (h->srcline) { 198 if (h->srcline) {
197 len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header)); 199 len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header));
@@ -246,6 +248,14 @@ static void he_stat__add_cpumode_period(struct he_stat *he_stat,
246 } 248 }
247} 249}
248 250
251static long hist_time(unsigned long htime)
252{
253 unsigned long time_quantum = symbol_conf.time_quantum;
254 if (time_quantum)
255 return (htime / time_quantum) * time_quantum;
256 return htime;
257}
258
249static void he_stat__add_period(struct he_stat *he_stat, u64 period, 259static void he_stat__add_period(struct he_stat *he_stat, u64 period,
250 u64 weight) 260 u64 weight)
251{ 261{
@@ -426,6 +436,13 @@ static int hist_entry__init(struct hist_entry *he,
426 goto err_rawdata; 436 goto err_rawdata;
427 } 437 }
428 438
439 if (symbol_conf.res_sample) {
440 he->res_samples = calloc(sizeof(struct res_sample),
441 symbol_conf.res_sample);
442 if (!he->res_samples)
443 goto err_srcline;
444 }
445
429 INIT_LIST_HEAD(&he->pairs.node); 446 INIT_LIST_HEAD(&he->pairs.node);
430 thread__get(he->thread); 447 thread__get(he->thread);
431 he->hroot_in = RB_ROOT_CACHED; 448 he->hroot_in = RB_ROOT_CACHED;
@@ -436,6 +453,9 @@ static int hist_entry__init(struct hist_entry *he,
436 453
437 return 0; 454 return 0;
438 455
456err_srcline:
457 free(he->srcline);
458
439err_rawdata: 459err_rawdata:
440 free(he->raw_data); 460 free(he->raw_data);
441 461
@@ -593,6 +613,32 @@ out:
593 return he; 613 return he;
594} 614}
595 615
616static unsigned random_max(unsigned high)
617{
618 unsigned thresh = -high % high;
619 for (;;) {
620 unsigned r = random();
621 if (r >= thresh)
622 return r % high;
623 }
624}
625
626static void hists__res_sample(struct hist_entry *he, struct perf_sample *sample)
627{
628 struct res_sample *r;
629 int j;
630
631 if (he->num_res < symbol_conf.res_sample) {
632 j = he->num_res++;
633 } else {
634 j = random_max(symbol_conf.res_sample);
635 }
636 r = &he->res_samples[j];
637 r->time = sample->time;
638 r->cpu = sample->cpu;
639 r->tid = sample->tid;
640}
641
596static struct hist_entry* 642static struct hist_entry*
597__hists__add_entry(struct hists *hists, 643__hists__add_entry(struct hists *hists,
598 struct addr_location *al, 644 struct addr_location *al,
@@ -635,10 +681,13 @@ __hists__add_entry(struct hists *hists,
635 .raw_data = sample->raw_data, 681 .raw_data = sample->raw_data,
636 .raw_size = sample->raw_size, 682 .raw_size = sample->raw_size,
637 .ops = ops, 683 .ops = ops,
684 .time = hist_time(sample->time),
638 }, *he = hists__findnew_entry(hists, &entry, al, sample_self); 685 }, *he = hists__findnew_entry(hists, &entry, al, sample_self);
639 686
640 if (!hists->has_callchains && he && he->callchain_size != 0) 687 if (!hists->has_callchains && he && he->callchain_size != 0)
641 hists->has_callchains = true; 688 hists->has_callchains = true;
689 if (he && symbol_conf.res_sample)
690 hists__res_sample(he, sample);
642 return he; 691 return he;
643} 692}
644 693
@@ -1162,6 +1211,7 @@ void hist_entry__delete(struct hist_entry *he)
1162 mem_info__zput(he->mem_info); 1211 mem_info__zput(he->mem_info);
1163 } 1212 }
1164 1213
1214 zfree(&he->res_samples);
1165 zfree(&he->stat_acc); 1215 zfree(&he->stat_acc);
1166 free_srcline(he->srcline); 1216 free_srcline(he->srcline);
1167 if (he->srcfile && he->srcfile[0]) 1217 if (he->srcfile && he->srcfile[0])
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 4af27fbab24f..76ff6c6d03b8 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -31,6 +31,7 @@ enum hist_filter {
31 31
32enum hist_column { 32enum hist_column {
33 HISTC_SYMBOL, 33 HISTC_SYMBOL,
34 HISTC_TIME,
34 HISTC_DSO, 35 HISTC_DSO,
35 HISTC_THREAD, 36 HISTC_THREAD,
36 HISTC_COMM, 37 HISTC_COMM,
@@ -432,9 +433,18 @@ struct hist_browser_timer {
432}; 433};
433 434
434struct annotation_options; 435struct annotation_options;
436struct res_sample;
437
438enum rstype {
439 A_NORMAL,
440 A_ASM,
441 A_SOURCE
442};
435 443
436#ifdef HAVE_SLANG_SUPPORT 444#ifdef HAVE_SLANG_SUPPORT
437#include "../ui/keysyms.h" 445#include "../ui/keysyms.h"
446void attr_to_script(char *buf, struct perf_event_attr *attr);
447
438int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, 448int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel,
439 struct hist_browser_timer *hbt, 449 struct hist_browser_timer *hbt,
440 struct annotation_options *annotation_opts); 450 struct annotation_options *annotation_opts);
@@ -449,7 +459,13 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
449 struct perf_env *env, 459 struct perf_env *env,
450 bool warn_lost_event, 460 bool warn_lost_event,
451 struct annotation_options *annotation_options); 461 struct annotation_options *annotation_options);
452int script_browse(const char *script_opt); 462
463int script_browse(const char *script_opt, struct perf_evsel *evsel);
464
465void run_script(char *cmd);
466int res_sample_browse(struct res_sample *res_samples, int num_res,
467 struct perf_evsel *evsel, enum rstype rstype);
468void res_sample_init(void);
453#else 469#else
454static inline 470static inline
455int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, 471int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
@@ -478,11 +494,22 @@ static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused,
478 return 0; 494 return 0;
479} 495}
480 496
481static inline int script_browse(const char *script_opt __maybe_unused) 497static inline int script_browse(const char *script_opt __maybe_unused,
498 struct perf_evsel *evsel __maybe_unused)
482{ 499{
483 return 0; 500 return 0;
484} 501}
485 502
503static inline int res_sample_browse(struct res_sample *res_samples __maybe_unused,
504 int num_res __maybe_unused,
505 struct perf_evsel *evsel __maybe_unused,
506 enum rstype rstype __maybe_unused)
507{
508 return 0;
509}
510
511static inline void res_sample_init(void) {}
512
486#define K_LEFT -1000 513#define K_LEFT -1000
487#define K_RIGHT -2000 514#define K_RIGHT -2000
488#define K_SWITCH_INPUT_DATA -3000 515#define K_SWITCH_INPUT_DATA -3000
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index a1b8d9649ca7..198e09ff611e 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -160,8 +160,10 @@ static struct map *kernel_get_module_map(const char *module)
160 if (module && strchr(module, '/')) 160 if (module && strchr(module, '/'))
161 return dso__new_map(module); 161 return dso__new_map(module);
162 162
163 if (!module) 163 if (!module) {
164 module = "kernel"; 164 pos = machine__kernel_map(host_machine);
165 return map__get(pos);
166 }
165 167
166 for (pos = maps__first(maps); pos; pos = map__next(pos)) { 168 for (pos = maps__first(maps); pos; pos = map__next(pos)) {
167 /* short_name is "[module]" */ 169 /* short_name is "[module]" */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index db643f3c2b95..0ec34227bd60 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -152,6 +152,10 @@ struct perf_session *perf_session__new(struct perf_data *data,
152 } 152 }
153 153
154 perf_evlist__init_trace_event_sample_raw(session->evlist); 154 perf_evlist__init_trace_event_sample_raw(session->evlist);
155
156 /* Open the directory data. */
157 if (data->is_dir && perf_data__open_dir(data))
158 goto out_delete;
155 } 159 }
156 } else { 160 } else {
157 session->machines.host.env = &perf_env; 161 session->machines.host.env = &perf_env;
@@ -1843,10 +1847,17 @@ fetch_mmaped_event(struct perf_session *session,
1843#define NUM_MMAPS 128 1847#define NUM_MMAPS 128
1844#endif 1848#endif
1845 1849
1850struct reader;
1851
1852typedef s64 (*reader_cb_t)(struct perf_session *session,
1853 union perf_event *event,
1854 u64 file_offset);
1855
1846struct reader { 1856struct reader {
1847 int fd; 1857 int fd;
1848 u64 data_size; 1858 u64 data_size;
1849 u64 data_offset; 1859 u64 data_offset;
1860 reader_cb_t process;
1850}; 1861};
1851 1862
1852static int 1863static int
@@ -1917,7 +1928,7 @@ more:
1917 size = event->header.size; 1928 size = event->header.size;
1918 1929
1919 if (size < sizeof(struct perf_event_header) || 1930 if (size < sizeof(struct perf_event_header) ||
1920 (skip = perf_session__process_event(session, event, file_pos)) < 0) { 1931 (skip = rd->process(session, event, file_pos)) < 0) {
1921 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", 1932 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1922 file_offset + head, event->header.size, 1933 file_offset + head, event->header.size,
1923 event->header.type); 1934 event->header.type);
@@ -1943,12 +1954,20 @@ out:
1943 return err; 1954 return err;
1944} 1955}
1945 1956
1957static s64 process_simple(struct perf_session *session,
1958 union perf_event *event,
1959 u64 file_offset)
1960{
1961 return perf_session__process_event(session, event, file_offset);
1962}
1963
1946static int __perf_session__process_events(struct perf_session *session) 1964static int __perf_session__process_events(struct perf_session *session)
1947{ 1965{
1948 struct reader rd = { 1966 struct reader rd = {
1949 .fd = perf_data__fd(session->data), 1967 .fd = perf_data__fd(session->data),
1950 .data_size = session->header.data_size, 1968 .data_size = session->header.data_size,
1951 .data_offset = session->header.data_offset, 1969 .data_offset = session->header.data_offset,
1970 .process = process_simple,
1952 }; 1971 };
1953 struct ordered_events *oe = &session->ordered_events; 1972 struct ordered_events *oe = &session->ordered_events;
1954 struct perf_tool *tool = session->tool; 1973 struct perf_tool *tool = session->tool;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index d2299e912e59..bdd30cab51cb 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -3,6 +3,7 @@
3#include <inttypes.h> 3#include <inttypes.h>
4#include <regex.h> 4#include <regex.h>
5#include <linux/mman.h> 5#include <linux/mman.h>
6#include <linux/time64.h>
6#include "sort.h" 7#include "sort.h"
7#include "hist.h" 8#include "hist.h"
8#include "comm.h" 9#include "comm.h"
@@ -15,6 +16,7 @@
15#include <traceevent/event-parse.h> 16#include <traceevent/event-parse.h>
16#include "mem-events.h" 17#include "mem-events.h"
17#include "annotate.h" 18#include "annotate.h"
19#include "time-utils.h"
18#include <linux/kernel.h> 20#include <linux/kernel.h>
19 21
20regex_t parent_regex; 22regex_t parent_regex;
@@ -654,6 +656,42 @@ struct sort_entry sort_socket = {
654 .se_width_idx = HISTC_SOCKET, 656 .se_width_idx = HISTC_SOCKET,
655}; 657};
656 658
659/* --sort time */
660
661static int64_t
662sort__time_cmp(struct hist_entry *left, struct hist_entry *right)
663{
664 return right->time - left->time;
665}
666
667static int hist_entry__time_snprintf(struct hist_entry *he, char *bf,
668 size_t size, unsigned int width)
669{
670 unsigned long secs;
671 unsigned long long nsecs;
672 char he_time[32];
673
674 nsecs = he->time;
675 secs = nsecs / NSEC_PER_SEC;
676 nsecs -= secs * NSEC_PER_SEC;
677
678 if (symbol_conf.nanosecs)
679 snprintf(he_time, sizeof he_time, "%5lu.%09llu: ",
680 secs, nsecs);
681 else
682 timestamp__scnprintf_usec(he->time, he_time,
683 sizeof(he_time));
684
685 return repsep_snprintf(bf, size, "%-.*s", width, he_time);
686}
687
688struct sort_entry sort_time = {
689 .se_header = "Time",
690 .se_cmp = sort__time_cmp,
691 .se_snprintf = hist_entry__time_snprintf,
692 .se_width_idx = HISTC_TIME,
693};
694
657/* --sort trace */ 695/* --sort trace */
658 696
659static char *get_trace_output(struct hist_entry *he) 697static char *get_trace_output(struct hist_entry *he)
@@ -1634,6 +1672,7 @@ static struct sort_dimension common_sort_dimensions[] = {
1634 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size), 1672 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size),
1635 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id), 1673 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
1636 DIM(SORT_SYM_IPC_NULL, "ipc_null", sort_sym_ipc_null), 1674 DIM(SORT_SYM_IPC_NULL, "ipc_null", sort_sym_ipc_null),
1675 DIM(SORT_TIME, "time", sort_time),
1637}; 1676};
1638 1677
1639#undef DIM 1678#undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 2fbee0b1011c..bb9442ab7a0c 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -47,6 +47,12 @@ extern struct sort_entry sort_srcline;
47extern enum sort_type sort__first_dimension; 47extern enum sort_type sort__first_dimension;
48extern const char default_mem_sort_order[]; 48extern const char default_mem_sort_order[];
49 49
50struct res_sample {
51 u64 time;
52 int cpu;
53 int tid;
54};
55
50struct he_stat { 56struct he_stat {
51 u64 period; 57 u64 period;
52 u64 period_sys; 58 u64 period_sys;
@@ -135,10 +141,13 @@ struct hist_entry {
135 char *srcfile; 141 char *srcfile;
136 struct symbol *parent; 142 struct symbol *parent;
137 struct branch_info *branch_info; 143 struct branch_info *branch_info;
144 long time;
138 struct hists *hists; 145 struct hists *hists;
139 struct mem_info *mem_info; 146 struct mem_info *mem_info;
140 void *raw_data; 147 void *raw_data;
141 u32 raw_size; 148 u32 raw_size;
149 int num_res;
150 struct res_sample *res_samples;
142 void *trace_output; 151 void *trace_output;
143 struct perf_hpp_list *hpp_list; 152 struct perf_hpp_list *hpp_list;
144 struct hist_entry *parent_he; 153 struct hist_entry *parent_he;
@@ -231,6 +240,7 @@ enum sort_type {
231 SORT_DSO_SIZE, 240 SORT_DSO_SIZE,
232 SORT_CGROUP_ID, 241 SORT_CGROUP_ID,
233 SORT_SYM_IPC_NULL, 242 SORT_SYM_IPC_NULL,
243 SORT_TIME,
234 244
235 /* branch stack specific sort keys */ 245 /* branch stack specific sort keys */
236 __SORT_BRANCH_STACK, 246 __SORT_BRANCH_STACK,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 758bf5f74e6e..58442ca5e3c4 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -6,6 +6,7 @@
6#include <string.h> 6#include <string.h>
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/mman.h> 8#include <linux/mman.h>
9#include <linux/time64.h>
9#include <sys/types.h> 10#include <sys/types.h>
10#include <sys/stat.h> 11#include <sys/stat.h>
11#include <sys/param.h> 12#include <sys/param.h>
@@ -39,15 +40,18 @@ int vmlinux_path__nr_entries;
39char **vmlinux_path; 40char **vmlinux_path;
40 41
41struct symbol_conf symbol_conf = { 42struct symbol_conf symbol_conf = {
43 .nanosecs = false,
42 .use_modules = true, 44 .use_modules = true,
43 .try_vmlinux_path = true, 45 .try_vmlinux_path = true,
44 .demangle = true, 46 .demangle = true,
45 .demangle_kernel = false, 47 .demangle_kernel = false,
46 .cumulate_callchain = true, 48 .cumulate_callchain = true,
49 .time_quantum = 100 * NSEC_PER_MSEC, /* 100ms */
47 .show_hist_headers = true, 50 .show_hist_headers = true,
48 .symfs = "", 51 .symfs = "",
49 .event_group = true, 52 .event_group = true,
50 .inline_name = true, 53 .inline_name = true,
54 .res_sample = 0,
51}; 55};
52 56
53static enum dso_binary_type binary_type_symtab[] = { 57static enum dso_binary_type binary_type_symtab[] = {
diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h
index fffea68c1203..6c55fa6fccec 100644
--- a/tools/perf/util/symbol_conf.h
+++ b/tools/perf/util/symbol_conf.h
@@ -8,6 +8,7 @@ struct strlist;
8struct intlist; 8struct intlist;
9 9
10struct symbol_conf { 10struct symbol_conf {
11 bool nanosecs;
11 unsigned short priv_size; 12 unsigned short priv_size;
12 bool try_vmlinux_path, 13 bool try_vmlinux_path,
13 init_annotation, 14 init_annotation,
@@ -55,6 +56,7 @@ struct symbol_conf {
55 *sym_list_str, 56 *sym_list_str,
56 *col_width_list_str, 57 *col_width_list_str,
57 *bt_stop_list_str; 58 *bt_stop_list_str;
59 unsigned long time_quantum;
58 struct strlist *dso_list, 60 struct strlist *dso_list,
59 *comm_list, 61 *comm_list,
60 *sym_list, 62 *sym_list,
@@ -66,6 +68,7 @@ struct symbol_conf {
66 struct intlist *pid_list, 68 struct intlist *pid_list,
67 *tid_list; 69 *tid_list;
68 const char *symfs; 70 const char *symfs;
71 int res_sample;
69}; 72};
70 73
71extern struct symbol_conf symbol_conf; 74extern struct symbol_conf symbol_conf;
diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c
index 0f53baec660e..20663a460df3 100644
--- a/tools/perf/util/time-utils.c
+++ b/tools/perf/util/time-utils.c
@@ -453,6 +453,14 @@ int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz)
453 return scnprintf(buf, sz, "%"PRIu64".%06"PRIu64, sec, usec); 453 return scnprintf(buf, sz, "%"PRIu64".%06"PRIu64, sec, usec);
454} 454}
455 455
456int timestamp__scnprintf_nsec(u64 timestamp, char *buf, size_t sz)
457{
458 u64 sec = timestamp / NSEC_PER_SEC,
459 nsec = timestamp % NSEC_PER_SEC;
460
461 return scnprintf(buf, sz, "%" PRIu64 ".%09" PRIu64, sec, nsec);
462}
463
456int fetch_current_timestamp(char *buf, size_t sz) 464int fetch_current_timestamp(char *buf, size_t sz)
457{ 465{
458 struct timeval tv; 466 struct timeval tv;
diff --git a/tools/perf/util/time-utils.h b/tools/perf/util/time-utils.h
index b923de44e36f..72a42ea1d513 100644
--- a/tools/perf/util/time-utils.h
+++ b/tools/perf/util/time-utils.h
@@ -30,6 +30,7 @@ int perf_time__parse_for_ranges(const char *str, struct perf_session *session,
30 int *range_size, int *range_num); 30 int *range_size, int *range_num);
31 31
32int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz); 32int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz);
33int timestamp__scnprintf_nsec(u64 timestamp, char *buf, size_t sz);
33 34
34int fetch_current_timestamp(char *buf, size_t sz); 35int fetch_current_timestamp(char *buf, size_t sz);
35 36