aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2018-10-31 17:53:40 -0400
committerIngo Molnar <mingo@kernel.org>2018-10-31 17:53:40 -0400
commit29995d296e3e9ce4f9767963ecbef143ade26c36 (patch)
treecd351a1f6724d308b7eb932e66891047cac9962c
parent28fa741c27e6d57f6bf594ba3c444ce79e671e09 (diff)
parent5d4f0edaa3ac4f1844ed7c64cd2bae6f1912bac5 (diff)
Merge tag 'perf-urgent-for-mingo-4.20-20181031' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent improvements and fixes from Arnaldo Carvalho de Melo: - Fixes dealing with the removal of the fallback to looking up samples marked as userspace in the kernel maps, done recently: - For intel-pt, that was setting the synthesized header misc field as PERF_RECORD_MISC_USER, depending thus on the fallback to take place, now it sets as USER or KERNEL according to x86 specific knowledge. Also now it inserts the PERF_CONTEXT_{USER,KERNEL} into the PERF_SAMPLE_CALLCHAINs it synthesizes from hw traces (Adrian Hunter) - Similar fixes for the cs-etm ARM HW trace code, that used the Intel PT model as a starting point (Leo Yan) - For the "caller" callchain order, where the callchain returned by the kernel was simply reversed without taking into account the PERF_CONTEXT_{USER,KERNEL,etc} markers from where to define if an entry was for kernel or userspace, working just because the map lookup fallback was in place (David S. Miller) - Allow for selecting if 'overwrite' mode should be used in 'perf top' and make the default for it not to be used. This is due to problems with the current implementation where the pausing used ends up making 'perf top' miss PERF_RECORD_{MMAP,FORK,EXEC,etc} events, which with short lifetime threads workloads leads quickly to many "unknown" maps (and thus symbols) to appear in the UI. Workloads with long thread lifetimes and with few metadata events can still use --overwrite to take advantage of the overwrite mode (Arnaldo Carvalho de Melo) - Start 'perf top''s display thread earlier, so that the screen doesn't remain blank for too long at tool start (David S. Miller) - Don't clone maps from parent when synthesizing forks, to avoid the inevitable flurry of overlapping maps as we process the synthesized MMAP2 events that get delivered shortly thereafter. (David S. Miller) - Take pgoff into account when reporting elf to libdwfl, now the unwinding results are the same with elfutils's libdwfl and libunwind (Milian Wolff) - Update lotsa kernel ABI headers (Arnaldo Carvalho de Melo) - 'perf trace' syscall arg beautification improvements to allow for handling args such as mount's 'flags', where maks have to be ignored before considering what is left, that, if only zeroes, is suppressed like other args without such masks (Arnaldo Carvalho de Melo) - Beautify mount's 'source' and 'flags' args (Arnaldo Carvalho de Melo) - Generate mmap's flags bit constants from linux/mman.h and all the arch specific mman.h files, so that no changes in the main 'perf trace' source files is required when new flags get added (Arnaldo Carvalho de Melo) - Consider syscall aliases, so that 'perf trace -e umount' works and we don't have to use 'umount2' (that works as well, just not required) (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--include/uapi/linux/perf_event.h2
-rw-r--r--tools/arch/arm64/include/uapi/asm/unistd.h1
-rw-r--r--tools/arch/powerpc/include/uapi/asm/kvm.h1
-rw-r--r--tools/arch/s390/include/uapi/asm/kvm.h2
-rw-r--r--tools/arch/x86/include/uapi/asm/kvm.h6
-rw-r--r--tools/include/uapi/asm-generic/unistd.h2
-rw-r--r--tools/include/uapi/linux/fs.h393
-rw-r--r--tools/include/uapi/linux/if_link.h1
-rw-r--r--tools/include/uapi/linux/kvm.h21
-rw-r--r--tools/include/uapi/linux/mman.h2
-rw-r--r--tools/include/uapi/linux/netlink.h1
-rw-r--r--tools/include/uapi/linux/perf_event.h2
-rw-r--r--tools/include/uapi/sound/asound.h2
-rw-r--r--tools/perf/Documentation/perf-top.txt10
-rw-r--r--tools/perf/Makefile.perf19
-rw-r--r--tools/perf/builtin-top.c21
-rw-r--r--tools/perf/builtin-trace.c48
-rwxr-xr-xtools/perf/check-headers.sh1
-rw-r--r--tools/perf/trace/beauty/Build1
-rw-r--r--tools/perf/trace/beauty/beauty.h7
-rw-r--r--tools/perf/trace/beauty/clone.c3
-rwxr-xr-xtools/perf/trace/beauty/drm_ioctl.sh1
-rw-r--r--tools/perf/trace/beauty/eventfd.c2
-rw-r--r--tools/perf/trace/beauty/fcntl.c3
-rw-r--r--tools/perf/trace/beauty/flock.c2
-rw-r--r--tools/perf/trace/beauty/futex_op.c2
-rw-r--r--tools/perf/trace/beauty/futex_val3.c2
-rw-r--r--tools/perf/trace/beauty/ioctl.c3
-rw-r--r--tools/perf/trace/beauty/kcmp.c3
-rwxr-xr-xtools/perf/trace/beauty/kcmp_type.sh1
-rwxr-xr-xtools/perf/trace/beauty/kvm_ioctl.sh1
-rwxr-xr-xtools/perf/trace/beauty/madvise_behavior.sh1
-rw-r--r--tools/perf/trace/beauty/mmap.c50
-rwxr-xr-xtools/perf/trace/beauty/mmap_flags.sh32
-rw-r--r--tools/perf/trace/beauty/mode_t.c2
-rw-r--r--tools/perf/trace/beauty/mount_flags.c43
-rwxr-xr-xtools/perf/trace/beauty/mount_flags.sh15
-rw-r--r--tools/perf/trace/beauty/msg_flags.c2
-rw-r--r--tools/perf/trace/beauty/open_flags.c2
-rw-r--r--tools/perf/trace/beauty/perf_event_open.c2
-rwxr-xr-xtools/perf/trace/beauty/perf_ioctl.sh1
-rw-r--r--tools/perf/trace/beauty/pid.c3
-rw-r--r--tools/perf/trace/beauty/pkey_alloc.c30
-rwxr-xr-xtools/perf/trace/beauty/pkey_alloc_access_rights.sh1
-rw-r--r--tools/perf/trace/beauty/prctl.c3
-rwxr-xr-xtools/perf/trace/beauty/prctl_option.sh1
-rw-r--r--tools/perf/trace/beauty/sched_policy.c2
-rw-r--r--tools/perf/trace/beauty/seccomp.c2
-rw-r--r--tools/perf/trace/beauty/signum.c2
-rwxr-xr-xtools/perf/trace/beauty/sndrv_ctl_ioctl.sh1
-rwxr-xr-xtools/perf/trace/beauty/sndrv_pcm_ioctl.sh1
-rw-r--r--tools/perf/trace/beauty/sockaddr.c2
-rw-r--r--tools/perf/trace/beauty/socket.c2
-rwxr-xr-xtools/perf/trace/beauty/socket_ipproto.sh1
-rw-r--r--tools/perf/trace/beauty/socket_type.c2
-rw-r--r--tools/perf/trace/beauty/statx.c3
-rwxr-xr-xtools/perf/trace/beauty/vhost_virtio_ioctl.sh1
-rw-r--r--tools/perf/trace/beauty/waitid_options.c2
-rw-r--r--tools/perf/util/cs-etm.c39
-rw-r--r--tools/perf/util/event.c1
-rw-r--r--tools/perf/util/intel-bts.c17
-rw-r--r--tools/perf/util/intel-pt.c28
-rw-r--r--tools/perf/util/machine.c54
-rw-r--r--tools/perf/util/thread-stack.c44
-rw-r--r--tools/perf/util/thread-stack.h2
-rw-r--r--tools/perf/util/thread.c13
-rw-r--r--tools/perf/util/thread.h2
-rw-r--r--tools/perf/util/unwind-libdw.c4
68 files changed, 837 insertions, 142 deletions
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index f35eb72739c0..9de8780ac8d9 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -646,10 +646,12 @@ struct perf_event_mmap_page {
646 * 646 *
647 * PERF_RECORD_MISC_MMAP_DATA - PERF_RECORD_MMAP* events 647 * PERF_RECORD_MISC_MMAP_DATA - PERF_RECORD_MMAP* events
648 * PERF_RECORD_MISC_COMM_EXEC - PERF_RECORD_COMM event 648 * PERF_RECORD_MISC_COMM_EXEC - PERF_RECORD_COMM event
649 * PERF_RECORD_MISC_FORK_EXEC - PERF_RECORD_FORK event (perf internal)
649 * PERF_RECORD_MISC_SWITCH_OUT - PERF_RECORD_SWITCH* events 650 * PERF_RECORD_MISC_SWITCH_OUT - PERF_RECORD_SWITCH* events
650 */ 651 */
651#define PERF_RECORD_MISC_MMAP_DATA (1 << 13) 652#define PERF_RECORD_MISC_MMAP_DATA (1 << 13)
652#define PERF_RECORD_MISC_COMM_EXEC (1 << 13) 653#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)
654#define PERF_RECORD_MISC_FORK_EXEC (1 << 13)
653#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13) 655#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)
654/* 656/*
655 * These PERF_RECORD_MISC_* flags below are safely reused 657 * These PERF_RECORD_MISC_* flags below are safely reused
diff --git a/tools/arch/arm64/include/uapi/asm/unistd.h b/tools/arch/arm64/include/uapi/asm/unistd.h
index 5072cbd15c82..dae1584cf017 100644
--- a/tools/arch/arm64/include/uapi/asm/unistd.h
+++ b/tools/arch/arm64/include/uapi/asm/unistd.h
@@ -16,5 +16,6 @@
16 */ 16 */
17 17
18#define __ARCH_WANT_RENAMEAT 18#define __ARCH_WANT_RENAMEAT
19#define __ARCH_WANT_NEW_STAT
19 20
20#include <asm-generic/unistd.h> 21#include <asm-generic/unistd.h>
diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h
index 1b32b56a03d3..8c876c166ef2 100644
--- a/tools/arch/powerpc/include/uapi/asm/kvm.h
+++ b/tools/arch/powerpc/include/uapi/asm/kvm.h
@@ -634,6 +634,7 @@ struct kvm_ppc_cpu_char {
634 634
635#define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe) 635#define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe)
636#define KVM_REG_PPC_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf) 636#define KVM_REG_PPC_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf)
637#define KVM_REG_PPC_PTCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc0)
637 638
638/* Transactional Memory checkpointed state: 639/* Transactional Memory checkpointed state:
639 * This is all GPRs, all VSX regs and a subset of SPRs 640 * This is all GPRs, all VSX regs and a subset of SPRs
diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
index 9a50f02b9894..16511d97e8dc 100644
--- a/tools/arch/s390/include/uapi/asm/kvm.h
+++ b/tools/arch/s390/include/uapi/asm/kvm.h
@@ -160,6 +160,8 @@ struct kvm_s390_vm_cpu_subfunc {
160#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 160#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
161#define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2 161#define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2
162#define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3 162#define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3
163#define KVM_S390_VM_CRYPTO_ENABLE_APIE 4
164#define KVM_S390_VM_CRYPTO_DISABLE_APIE 5
163 165
164/* kvm attributes for migration mode */ 166/* kvm attributes for migration mode */
165#define KVM_S390_VM_MIGRATION_STOP 0 167#define KVM_S390_VM_MIGRATION_STOP 0
diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h
index 8a6eff9c27f3..dabfcf7c3941 100644
--- a/tools/arch/x86/include/uapi/asm/kvm.h
+++ b/tools/arch/x86/include/uapi/asm/kvm.h
@@ -300,10 +300,7 @@ struct kvm_vcpu_events {
300 __u8 injected; 300 __u8 injected;
301 __u8 nr; 301 __u8 nr;
302 __u8 has_error_code; 302 __u8 has_error_code;
303 union { 303 __u8 pending;
304 __u8 pad;
305 __u8 pending;
306 };
307 __u32 error_code; 304 __u32 error_code;
308 } exception; 305 } exception;
309 struct { 306 struct {
@@ -387,6 +384,7 @@ struct kvm_sync_regs {
387 384
388#define KVM_STATE_NESTED_GUEST_MODE 0x00000001 385#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
389#define KVM_STATE_NESTED_RUN_PENDING 0x00000002 386#define KVM_STATE_NESTED_RUN_PENDING 0x00000002
387#define KVM_STATE_NESTED_EVMCS 0x00000004
390 388
391#define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 389#define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001
392#define KVM_STATE_NESTED_SMM_VMXON 0x00000002 390#define KVM_STATE_NESTED_SMM_VMXON 0x00000002
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index df4bedb9b01c..538546edbfbd 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -242,10 +242,12 @@ __SYSCALL(__NR_tee, sys_tee)
242/* fs/stat.c */ 242/* fs/stat.c */
243#define __NR_readlinkat 78 243#define __NR_readlinkat 78
244__SYSCALL(__NR_readlinkat, sys_readlinkat) 244__SYSCALL(__NR_readlinkat, sys_readlinkat)
245#if defined(__ARCH_WANT_NEW_STAT) || defined(__ARCH_WANT_STAT64)
245#define __NR3264_fstatat 79 246#define __NR3264_fstatat 79
246__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat) 247__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
247#define __NR3264_fstat 80 248#define __NR3264_fstat 80
248__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat) 249__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
250#endif
249 251
250/* fs/sync.c */ 252/* fs/sync.c */
251#define __NR_sync 81 253#define __NR_sync 81
diff --git a/tools/include/uapi/linux/fs.h b/tools/include/uapi/linux/fs.h
new file mode 100644
index 000000000000..a441ea1bfe6d
--- /dev/null
+++ b/tools/include/uapi/linux/fs.h
@@ -0,0 +1,393 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2#ifndef _UAPI_LINUX_FS_H
3#define _UAPI_LINUX_FS_H
4
5/*
6 * This file has definitions for some important file table structures
7 * and constants and structures used by various generic file system
8 * ioctl's. Please do not make any changes in this file before
9 * sending patches for review to linux-fsdevel@vger.kernel.org and
10 * linux-api@vger.kernel.org.
11 */
12
13#include <linux/limits.h>
14#include <linux/ioctl.h>
15#include <linux/types.h>
16
17/*
18 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
19 * the file limit at runtime and only root can increase the per-process
20 * nr_file rlimit, so it's safe to set up a ridiculously high absolute
21 * upper limit on files-per-process.
22 *
23 * Some programs (notably those using select()) may have to be
24 * recompiled to take full advantage of the new limits..
25 */
26
27/* Fixed constants first: */
28#undef NR_OPEN
29#define INR_OPEN_CUR 1024 /* Initial setting for nfile rlimits */
30#define INR_OPEN_MAX 4096 /* Hard limit for nfile rlimits */
31
32#define BLOCK_SIZE_BITS 10
33#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
34
35#define SEEK_SET 0 /* seek relative to beginning of file */
36#define SEEK_CUR 1 /* seek relative to current file position */
37#define SEEK_END 2 /* seek relative to end of file */
38#define SEEK_DATA 3 /* seek to the next data */
39#define SEEK_HOLE 4 /* seek to the next hole */
40#define SEEK_MAX SEEK_HOLE
41
42#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
43#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
44#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
45
46struct file_clone_range {
47 __s64 src_fd;
48 __u64 src_offset;
49 __u64 src_length;
50 __u64 dest_offset;
51};
52
53struct fstrim_range {
54 __u64 start;
55 __u64 len;
56 __u64 minlen;
57};
58
59/* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */
60#define FILE_DEDUPE_RANGE_SAME 0
61#define FILE_DEDUPE_RANGE_DIFFERS 1
62
63/* from struct btrfs_ioctl_file_extent_same_info */
64struct file_dedupe_range_info {
65 __s64 dest_fd; /* in - destination file */
66 __u64 dest_offset; /* in - start of extent in destination */
67 __u64 bytes_deduped; /* out - total # of bytes we were able
68 * to dedupe from this file. */
69 /* status of this dedupe operation:
70 * < 0 for error
71 * == FILE_DEDUPE_RANGE_SAME if dedupe succeeds
72 * == FILE_DEDUPE_RANGE_DIFFERS if data differs
73 */
74 __s32 status; /* out - see above description */
75 __u32 reserved; /* must be zero */
76};
77
78/* from struct btrfs_ioctl_file_extent_same_args */
79struct file_dedupe_range {
80 __u64 src_offset; /* in - start of extent in source */
81 __u64 src_length; /* in - length of extent */
82 __u16 dest_count; /* in - total elements in info array */
83 __u16 reserved1; /* must be zero */
84 __u32 reserved2; /* must be zero */
85 struct file_dedupe_range_info info[0];
86};
87
88/* And dynamically-tunable limits and defaults: */
89struct files_stat_struct {
90 unsigned long nr_files; /* read only */
91 unsigned long nr_free_files; /* read only */
92 unsigned long max_files; /* tunable */
93};
94
95struct inodes_stat_t {
96 long nr_inodes;
97 long nr_unused;
98 long dummy[5]; /* padding for sysctl ABI compatibility */
99};
100
101
102#define NR_FILE 8192 /* this can well be larger on a larger system */
103
104
105/*
106 * These are the fs-independent mount-flags: up to 32 flags are supported
107 */
108#define MS_RDONLY 1 /* Mount read-only */
109#define MS_NOSUID 2 /* Ignore suid and sgid bits */
110#define MS_NODEV 4 /* Disallow access to device special files */
111#define MS_NOEXEC 8 /* Disallow program execution */
112#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
113#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
114#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
115#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
116#define MS_NOATIME 1024 /* Do not update access times. */
117#define MS_NODIRATIME 2048 /* Do not update directory access times */
118#define MS_BIND 4096
119#define MS_MOVE 8192
120#define MS_REC 16384
121#define MS_VERBOSE 32768 /* War is peace. Verbosity is silence.
122 MS_VERBOSE is deprecated. */
123#define MS_SILENT 32768
124#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
125#define MS_UNBINDABLE (1<<17) /* change to unbindable */
126#define MS_PRIVATE (1<<18) /* change to private */
127#define MS_SLAVE (1<<19) /* change to slave */
128#define MS_SHARED (1<<20) /* change to shared */
129#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
130#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
131#define MS_I_VERSION (1<<23) /* Update inode I_version field */
132#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
133#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
134
135/* These sb flags are internal to the kernel */
136#define MS_SUBMOUNT (1<<26)
137#define MS_NOREMOTELOCK (1<<27)
138#define MS_NOSEC (1<<28)
139#define MS_BORN (1<<29)
140#define MS_ACTIVE (1<<30)
141#define MS_NOUSER (1<<31)
142
143/*
144 * Superblock flags that can be altered by MS_REMOUNT
145 */
146#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|\
147 MS_LAZYTIME)
148
149/*
150 * Old magic mount flag and mask
151 */
152#define MS_MGC_VAL 0xC0ED0000
153#define MS_MGC_MSK 0xffff0000
154
155/*
156 * Structure for FS_IOC_FSGETXATTR[A] and FS_IOC_FSSETXATTR.
157 */
158struct fsxattr {
159 __u32 fsx_xflags; /* xflags field value (get/set) */
160 __u32 fsx_extsize; /* extsize field value (get/set)*/
161 __u32 fsx_nextents; /* nextents field value (get) */
162 __u32 fsx_projid; /* project identifier (get/set) */
163 __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
164 unsigned char fsx_pad[8];
165};
166
167/*
168 * Flags for the fsx_xflags field
169 */
170#define FS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
171#define FS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
172#define FS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
173#define FS_XFLAG_APPEND 0x00000010 /* all writes append */
174#define FS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
175#define FS_XFLAG_NOATIME 0x00000040 /* do not update access time */
176#define FS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
177#define FS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
178#define FS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
179#define FS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
180#define FS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
181#define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
182#define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
183#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
184#define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */
185#define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size allocator hint */
186#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
187
188/* the read-only stuff doesn't really belong here, but any other place is
189 probably as bad and I don't want to create yet another include file. */
190
191#define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */
192#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */
193#define BLKRRPART _IO(0x12,95) /* re-read partition table */
194#define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */
195#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */
196#define BLKRASET _IO(0x12,98) /* set read ahead for block device */
197#define BLKRAGET _IO(0x12,99) /* get current read ahead setting */
198#define BLKFRASET _IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */
199#define BLKFRAGET _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
200#define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
201#define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
202#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
203#if 0
204#define BLKPG _IO(0x12,105)/* See blkpg.h */
205
206/* Some people are morons. Do not use sizeof! */
207
208#define BLKELVGET _IOR(0x12,106,size_t)/* elevator get */
209#define BLKELVSET _IOW(0x12,107,size_t)/* elevator set */
210/* This was here just to show that the number is taken -
211 probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
212#endif
213/* A jump here: 108-111 have been used for various private purposes. */
214#define BLKBSZGET _IOR(0x12,112,size_t)
215#define BLKBSZSET _IOW(0x12,113,size_t)
216#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
217#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
218#define BLKTRACESTART _IO(0x12,116)
219#define BLKTRACESTOP _IO(0x12,117)
220#define BLKTRACETEARDOWN _IO(0x12,118)
221#define BLKDISCARD _IO(0x12,119)
222#define BLKIOMIN _IO(0x12,120)
223#define BLKIOOPT _IO(0x12,121)
224#define BLKALIGNOFF _IO(0x12,122)
225#define BLKPBSZGET _IO(0x12,123)
226#define BLKDISCARDZEROES _IO(0x12,124)
227#define BLKSECDISCARD _IO(0x12,125)
228#define BLKROTATIONAL _IO(0x12,126)
229#define BLKZEROOUT _IO(0x12,127)
230/*
231 * A jump here: 130-131 are reserved for zoned block devices
232 * (see uapi/linux/blkzoned.h)
233 */
234
235#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
236#define FIBMAP _IO(0x00,1) /* bmap access */
237#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
238#define FIFREEZE _IOWR('X', 119, int) /* Freeze */
239#define FITHAW _IOWR('X', 120, int) /* Thaw */
240#define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */
241#define FICLONE _IOW(0x94, 9, int)
242#define FICLONERANGE _IOW(0x94, 13, struct file_clone_range)
243#define FIDEDUPERANGE _IOWR(0x94, 54, struct file_dedupe_range)
244
245#define FSLABEL_MAX 256 /* Max chars for the interface; each fs may differ */
246
247#define FS_IOC_GETFLAGS _IOR('f', 1, long)
248#define FS_IOC_SETFLAGS _IOW('f', 2, long)
249#define FS_IOC_GETVERSION _IOR('v', 1, long)
250#define FS_IOC_SETVERSION _IOW('v', 2, long)
251#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
252#define FS_IOC32_GETFLAGS _IOR('f', 1, int)
253#define FS_IOC32_SETFLAGS _IOW('f', 2, int)
254#define FS_IOC32_GETVERSION _IOR('v', 1, int)
255#define FS_IOC32_SETVERSION _IOW('v', 2, int)
256#define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
257#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
258#define FS_IOC_GETFSLABEL _IOR(0x94, 49, char[FSLABEL_MAX])
259#define FS_IOC_SETFSLABEL _IOW(0x94, 50, char[FSLABEL_MAX])
260
261/*
262 * File system encryption support
263 */
264/* Policy provided via an ioctl on the topmost directory */
265#define FS_KEY_DESCRIPTOR_SIZE 8
266
267#define FS_POLICY_FLAGS_PAD_4 0x00
268#define FS_POLICY_FLAGS_PAD_8 0x01
269#define FS_POLICY_FLAGS_PAD_16 0x02
270#define FS_POLICY_FLAGS_PAD_32 0x03
271#define FS_POLICY_FLAGS_PAD_MASK 0x03
272#define FS_POLICY_FLAGS_VALID 0x03
273
274/* Encryption algorithms */
275#define FS_ENCRYPTION_MODE_INVALID 0
276#define FS_ENCRYPTION_MODE_AES_256_XTS 1
277#define FS_ENCRYPTION_MODE_AES_256_GCM 2
278#define FS_ENCRYPTION_MODE_AES_256_CBC 3
279#define FS_ENCRYPTION_MODE_AES_256_CTS 4
280#define FS_ENCRYPTION_MODE_AES_128_CBC 5
281#define FS_ENCRYPTION_MODE_AES_128_CTS 6
282#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7 /* Removed, do not use. */
283#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8 /* Removed, do not use. */
284
285struct fscrypt_policy {
286 __u8 version;
287 __u8 contents_encryption_mode;
288 __u8 filenames_encryption_mode;
289 __u8 flags;
290 __u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
291};
292
293#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy)
294#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
295#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy)
296
297/* Parameters for passing an encryption key into the kernel keyring */
298#define FS_KEY_DESC_PREFIX "fscrypt:"
299#define FS_KEY_DESC_PREFIX_SIZE 8
300
301/* Structure that userspace passes to the kernel keyring */
302#define FS_MAX_KEY_SIZE 64
303
304struct fscrypt_key {
305 __u32 mode;
306 __u8 raw[FS_MAX_KEY_SIZE];
307 __u32 size;
308};
309
310/*
311 * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
312 *
313 * Note: for historical reasons, these flags were originally used and
314 * defined for use by ext2/ext3, and then other file systems started
315 * using these flags so they wouldn't need to write their own version
316 * of chattr/lsattr (which was shipped as part of e2fsprogs). You
317 * should think twice before trying to use these flags in new
318 * contexts, or trying to assign these flags, since they are used both
319 * as the UAPI and the on-disk encoding for ext2/3/4. Also, we are
320 * almost out of 32-bit flags. :-)
321 *
322 * We have recently hoisted FS_IOC_FSGETXATTR / FS_IOC_FSSETXATTR from
323 * XFS to the generic FS level interface. This uses a structure that
324 * has padding and hence has more room to grow, so it may be more
325 * appropriate for many new use cases.
326 *
327 * Please do not change these flags or interfaces before checking with
328 * linux-fsdevel@vger.kernel.org and linux-api@vger.kernel.org.
329 */
330#define FS_SECRM_FL 0x00000001 /* Secure deletion */
331#define FS_UNRM_FL 0x00000002 /* Undelete */
332#define FS_COMPR_FL 0x00000004 /* Compress file */
333#define FS_SYNC_FL 0x00000008 /* Synchronous updates */
334#define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
335#define FS_APPEND_FL 0x00000020 /* writes to file may only append */
336#define FS_NODUMP_FL 0x00000040 /* do not dump file */
337#define FS_NOATIME_FL 0x00000080 /* do not update atime */
338/* Reserved for compression usage... */
339#define FS_DIRTY_FL 0x00000100
340#define FS_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
341#define FS_NOCOMP_FL 0x00000400 /* Don't compress */
342/* End compression flags --- maybe not all used */
343#define FS_ENCRYPT_FL 0x00000800 /* Encrypted file */
344#define FS_BTREE_FL 0x00001000 /* btree format dir */
345#define FS_INDEX_FL 0x00001000 /* hash-indexed directory */
346#define FS_IMAGIC_FL 0x00002000 /* AFS directory */
347#define FS_JOURNAL_DATA_FL 0x00004000 /* Reserved for ext3 */
348#define FS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
349#define FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
350#define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
351#define FS_HUGE_FILE_FL 0x00040000 /* Reserved for ext4 */
352#define FS_EXTENT_FL 0x00080000 /* Extents */
353#define FS_EA_INODE_FL 0x00200000 /* Inode used for large EA */
354#define FS_EOFBLOCKS_FL 0x00400000 /* Reserved for ext4 */
355#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
356#define FS_INLINE_DATA_FL 0x10000000 /* Reserved for ext4 */
357#define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
358#define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
359
360#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
361#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
362
363
364#define SYNC_FILE_RANGE_WAIT_BEFORE 1
365#define SYNC_FILE_RANGE_WRITE 2
366#define SYNC_FILE_RANGE_WAIT_AFTER 4
367
368/*
369 * Flags for preadv2/pwritev2:
370 */
371
372typedef int __bitwise __kernel_rwf_t;
373
374/* high priority request, poll if possible */
375#define RWF_HIPRI ((__force __kernel_rwf_t)0x00000001)
376
377/* per-IO O_DSYNC */
378#define RWF_DSYNC ((__force __kernel_rwf_t)0x00000002)
379
380/* per-IO O_SYNC */
381#define RWF_SYNC ((__force __kernel_rwf_t)0x00000004)
382
383/* per-IO, return -EAGAIN if operation would block */
384#define RWF_NOWAIT ((__force __kernel_rwf_t)0x00000008)
385
386/* per-IO O_APPEND */
387#define RWF_APPEND ((__force __kernel_rwf_t)0x00000010)
388
389/* mask of flags supported by the kernel */
390#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\
391 RWF_APPEND)
392
393#endif /* _UAPI_LINUX_FS_H */
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index 58faab897201..1debfa42cba1 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -287,6 +287,7 @@ enum {
287 IFLA_BR_MCAST_STATS_ENABLED, 287 IFLA_BR_MCAST_STATS_ENABLED,
288 IFLA_BR_MCAST_IGMP_VERSION, 288 IFLA_BR_MCAST_IGMP_VERSION,
289 IFLA_BR_MCAST_MLD_VERSION, 289 IFLA_BR_MCAST_MLD_VERSION,
290 IFLA_BR_VLAN_STATS_PER_PORT,
290 __IFLA_BR_MAX, 291 __IFLA_BR_MAX,
291}; 292};
292 293
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 2875ce85b322..2b7a652c9fa4 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -420,13 +420,19 @@ struct kvm_run {
420struct kvm_coalesced_mmio_zone { 420struct kvm_coalesced_mmio_zone {
421 __u64 addr; 421 __u64 addr;
422 __u32 size; 422 __u32 size;
423 __u32 pad; 423 union {
424 __u32 pad;
425 __u32 pio;
426 };
424}; 427};
425 428
426struct kvm_coalesced_mmio { 429struct kvm_coalesced_mmio {
427 __u64 phys_addr; 430 __u64 phys_addr;
428 __u32 len; 431 __u32 len;
429 __u32 pad; 432 union {
433 __u32 pad;
434 __u32 pio;
435 };
430 __u8 data[8]; 436 __u8 data[8];
431}; 437};
432 438
@@ -752,6 +758,15 @@ struct kvm_ppc_resize_hpt {
752#define KVM_S390_SIE_PAGE_OFFSET 1 758#define KVM_S390_SIE_PAGE_OFFSET 1
753 759
754/* 760/*
761 * On arm64, machine type can be used to request the physical
762 * address size for the VM. Bits[7-0] are reserved for the guest
763 * PA size shift (i.e, log2(PA_Size)). For backward compatibility,
764 * value 0 implies the default IPA size, 40bits.
765 */
766#define KVM_VM_TYPE_ARM_IPA_SIZE_MASK 0xffULL
767#define KVM_VM_TYPE_ARM_IPA_SIZE(x) \
768 ((x) & KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
769/*
755 * ioctls for /dev/kvm fds: 770 * ioctls for /dev/kvm fds:
756 */ 771 */
757#define KVM_GET_API_VERSION _IO(KVMIO, 0x00) 772#define KVM_GET_API_VERSION _IO(KVMIO, 0x00)
@@ -958,6 +973,8 @@ struct kvm_ppc_resize_hpt {
958#define KVM_CAP_HYPERV_SEND_IPI 161 973#define KVM_CAP_HYPERV_SEND_IPI 161
959#define KVM_CAP_COALESCED_PIO 162 974#define KVM_CAP_COALESCED_PIO 162
960#define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163 975#define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163
976#define KVM_CAP_EXCEPTION_PAYLOAD 164
977#define KVM_CAP_ARM_VM_IPA_SIZE 165
961 978
962#ifdef KVM_CAP_IRQ_ROUTING 979#ifdef KVM_CAP_IRQ_ROUTING
963 980
diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h
index bfd5938fede6..d0f515d53299 100644
--- a/tools/include/uapi/linux/mman.h
+++ b/tools/include/uapi/linux/mman.h
@@ -28,7 +28,9 @@
28#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB 28#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
29#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB 29#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
30#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB 30#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
31#define MAP_HUGE_32MB HUGETLB_FLAG_ENCODE_32MB
31#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB 32#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
33#define MAP_HUGE_512MB HUGETLB_FLAG_ENCODE_512MB
32#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB 34#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
33#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB 35#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
34#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB 36#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
diff --git a/tools/include/uapi/linux/netlink.h b/tools/include/uapi/linux/netlink.h
index 776bc92e9118..486ed1f0c0bc 100644
--- a/tools/include/uapi/linux/netlink.h
+++ b/tools/include/uapi/linux/netlink.h
@@ -155,6 +155,7 @@ enum nlmsgerr_attrs {
155#define NETLINK_LIST_MEMBERSHIPS 9 155#define NETLINK_LIST_MEMBERSHIPS 9
156#define NETLINK_CAP_ACK 10 156#define NETLINK_CAP_ACK 10
157#define NETLINK_EXT_ACK 11 157#define NETLINK_EXT_ACK 11
158#define NETLINK_DUMP_STRICT_CHK 12
158 159
159struct nl_pktinfo { 160struct nl_pktinfo {
160 __u32 group; 161 __u32 group;
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index f35eb72739c0..9de8780ac8d9 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -646,10 +646,12 @@ struct perf_event_mmap_page {
646 * 646 *
647 * PERF_RECORD_MISC_MMAP_DATA - PERF_RECORD_MMAP* events 647 * PERF_RECORD_MISC_MMAP_DATA - PERF_RECORD_MMAP* events
648 * PERF_RECORD_MISC_COMM_EXEC - PERF_RECORD_COMM event 648 * PERF_RECORD_MISC_COMM_EXEC - PERF_RECORD_COMM event
649 * PERF_RECORD_MISC_FORK_EXEC - PERF_RECORD_FORK event (perf internal)
649 * PERF_RECORD_MISC_SWITCH_OUT - PERF_RECORD_SWITCH* events 650 * PERF_RECORD_MISC_SWITCH_OUT - PERF_RECORD_SWITCH* events
650 */ 651 */
651#define PERF_RECORD_MISC_MMAP_DATA (1 << 13) 652#define PERF_RECORD_MISC_MMAP_DATA (1 << 13)
652#define PERF_RECORD_MISC_COMM_EXEC (1 << 13) 653#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)
654#define PERF_RECORD_MISC_FORK_EXEC (1 << 13)
653#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13) 655#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)
654/* 656/*
655 * These PERF_RECORD_MISC_* flags below are safely reused 657 * These PERF_RECORD_MISC_* flags below are safely reused
diff --git a/tools/include/uapi/sound/asound.h b/tools/include/uapi/sound/asound.h
index ed0a120d4f08..404d4b9ffe76 100644
--- a/tools/include/uapi/sound/asound.h
+++ b/tools/include/uapi/sound/asound.h
@@ -752,7 +752,7 @@ struct snd_timer_info {
752#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2) /* write early event to the poll queue */ 752#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2) /* write early event to the poll queue */
753 753
754struct snd_timer_params { 754struct snd_timer_params {
755 unsigned int flags; /* flags - SNDRV_MIXER_PSFLG_* */ 755 unsigned int flags; /* flags - SNDRV_TIMER_PSFLG_* */
756 unsigned int ticks; /* requested resolution in ticks */ 756 unsigned int ticks; /* requested resolution in ticks */
757 unsigned int queue_size; /* total size of queue (32-1024) */ 757 unsigned int queue_size; /* total size of queue (32-1024) */
758 unsigned int reserved0; /* reserved, was: failure locations */ 758 unsigned int reserved0; /* reserved, was: failure locations */
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 114fda12aa49..808b664343c9 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -242,6 +242,16 @@ Default is to monitor all CPUS.
242--hierarchy:: 242--hierarchy::
243 Enable hierarchy output. 243 Enable hierarchy output.
244 244
245--overwrite::
246 Enable this to use just the most recent records, which helps in high core count
247 machines such as Knights Landing/Mill, but right now is disabled by default as
248 the pausing used in this technique is leading to loss of metadata events such
249 as PERF_RECORD_MMAP which makes 'perf top' unable to resolve samples, leading
250 to lots of unknown samples appearing on the UI. Enable this if you are in such
251 machines and profiling a workload that doesn't creates short lived threads and/or
252 doesn't uses many executable mmap operations. Work is being planed to solve
253 this situation, till then, this will remain disabled by default.
254
245--force:: 255--force::
246 Don't do ownership validation. 256 Don't do ownership validation.
247 257
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 2f3bf025e305..3ccb4f0bf088 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -1,4 +1,5 @@
1include ../scripts/Makefile.include 1include ../scripts/Makefile.include
2include ../scripts/Makefile.arch
2 3
3# The default target of this Makefile is... 4# The default target of this Makefile is...
4all: 5all:
@@ -385,6 +386,8 @@ export INSTALL SHELL_PATH
385SHELL = $(SHELL_PATH) 386SHELL = $(SHELL_PATH)
386 387
387linux_uapi_dir := $(srctree)/tools/include/uapi/linux 388linux_uapi_dir := $(srctree)/tools/include/uapi/linux
389asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic
390arch_asm_uapi_dir := $(srctree)/tools/arch/$(ARCH)/include/uapi/asm/
388 391
389beauty_outdir := $(OUTPUT)trace/beauty/generated 392beauty_outdir := $(OUTPUT)trace/beauty/generated
390beauty_ioctl_outdir := $(beauty_outdir)/ioctl 393beauty_ioctl_outdir := $(beauty_outdir)/ioctl
@@ -460,6 +463,18 @@ madvise_behavior_tbl := $(srctree)/tools/perf/trace/beauty/madvise_behavior.sh
460$(madvise_behavior_array): $(madvise_hdr_dir)/mman-common.h $(madvise_behavior_tbl) 463$(madvise_behavior_array): $(madvise_hdr_dir)/mman-common.h $(madvise_behavior_tbl)
461 $(Q)$(SHELL) '$(madvise_behavior_tbl)' $(madvise_hdr_dir) > $@ 464 $(Q)$(SHELL) '$(madvise_behavior_tbl)' $(madvise_hdr_dir) > $@
462 465
466mmap_flags_array := $(beauty_outdir)/mmap_flags_array.c
467mmap_flags_tbl := $(srctree)/tools/perf/trace/beauty/mmap_flags.sh
468
469$(mmap_flags_array): $(asm_generic_uapi_dir)/mman.h $(asm_generic_uapi_dir)/mman-common.h $(arch_asm_uapi_dir)/mman.h $(mmap_flags_tbl)
470 $(Q)$(SHELL) '$(mmap_flags_tbl)' $(asm_generic_uapi_dir) $(arch_asm_uapi_dir) > $@
471
472mount_flags_array := $(beauty_outdir)/mount_flags_array.c
473mount_flags_tbl := $(srctree)/tools/perf/trace/beauty/mount_flags.sh
474
475$(mount_flags_array): $(linux_uapi_dir)/fs.h $(mount_flags_tbl)
476 $(Q)$(SHELL) '$(mount_flags_tbl)' $(linux_uapi_dir) > $@
477
463prctl_option_array := $(beauty_outdir)/prctl_option_array.c 478prctl_option_array := $(beauty_outdir)/prctl_option_array.c
464prctl_hdr_dir := $(srctree)/tools/include/uapi/linux/ 479prctl_hdr_dir := $(srctree)/tools/include/uapi/linux/
465prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh 480prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh
@@ -577,6 +592,8 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
577 $(socket_ipproto_array) \ 592 $(socket_ipproto_array) \
578 $(vhost_virtio_ioctl_array) \ 593 $(vhost_virtio_ioctl_array) \
579 $(madvise_behavior_array) \ 594 $(madvise_behavior_array) \
595 $(mmap_flags_array) \
596 $(mount_flags_array) \
580 $(perf_ioctl_array) \ 597 $(perf_ioctl_array) \
581 $(prctl_option_array) \ 598 $(prctl_option_array) \
582 $(arch_errno_name_array) 599 $(arch_errno_name_array)
@@ -863,6 +880,8 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
863 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ 880 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \
864 $(OUTPUT)pmu-events/pmu-events.c \ 881 $(OUTPUT)pmu-events/pmu-events.c \
865 $(OUTPUT)$(madvise_behavior_array) \ 882 $(OUTPUT)$(madvise_behavior_array) \
883 $(OUTPUT)$(mmap_flags_array) \
884 $(OUTPUT)$(mount_flags_array) \
866 $(OUTPUT)$(drm_ioctl_array) \ 885 $(OUTPUT)$(drm_ioctl_array) \
867 $(OUTPUT)$(pkey_alloc_access_rights_array) \ 886 $(OUTPUT)$(pkey_alloc_access_rights_array) \
868 $(OUTPUT)$(sndrv_ctl_ioctl_array) \ 887 $(OUTPUT)$(sndrv_ctl_ioctl_array) \
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index d21d8751e749..b2838de13de0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1134,11 +1134,6 @@ static int __cmd_top(struct perf_top *top)
1134 if (!target__none(&opts->target)) 1134 if (!target__none(&opts->target))
1135 perf_evlist__enable(top->evlist); 1135 perf_evlist__enable(top->evlist);
1136 1136
1137 /* Wait for a minimal set of events before starting the snapshot */
1138 perf_evlist__poll(top->evlist, 100);
1139
1140 perf_top__mmap_read(top);
1141
1142 ret = -1; 1137 ret = -1;
1143 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : 1138 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
1144 display_thread), top)) { 1139 display_thread), top)) {
@@ -1156,6 +1151,11 @@ static int __cmd_top(struct perf_top *top)
1156 } 1151 }
1157 } 1152 }
1158 1153
1154 /* Wait for a minimal set of events before starting the snapshot */
1155 perf_evlist__poll(top->evlist, 100);
1156
1157 perf_top__mmap_read(top);
1158
1159 while (!done) { 1159 while (!done) {
1160 u64 hits = top->samples; 1160 u64 hits = top->samples;
1161 1161
@@ -1257,7 +1257,14 @@ int cmd_top(int argc, const char **argv)
1257 .uses_mmap = true, 1257 .uses_mmap = true,
1258 }, 1258 },
1259 .proc_map_timeout = 500, 1259 .proc_map_timeout = 500,
1260 .overwrite = 1, 1260 /*
1261 * FIXME: This will lose PERF_RECORD_MMAP and other metadata
1262 * when we pause, fix that and reenable. Probably using a
1263 * separate evlist with a dummy event, i.e. a non-overwrite
1264 * ring buffer just for metadata events, while PERF_RECORD_SAMPLE
1265 * stays in overwrite mode. -acme
1266 * */
1267 .overwrite = 0,
1261 }, 1268 },
1262 .max_stack = sysctl__max_stack(), 1269 .max_stack = sysctl__max_stack(),
1263 .annotation_opts = annotation__default_options, 1270 .annotation_opts = annotation__default_options,
@@ -1372,6 +1379,8 @@ int cmd_top(int argc, const char **argv)
1372 "Show raw trace event output (do not use print fmt or plugins)"), 1379 "Show raw trace event output (do not use print fmt or plugins)"),
1373 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, 1380 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
1374 "Show entries in a hierarchy"), 1381 "Show entries in a hierarchy"),
1382 OPT_BOOLEAN(0, "overwrite", &top.record_opts.overwrite,
1383 "Use a backward ring buffer, default: no"),
1375 OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"), 1384 OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"),
1376 OPT_UINTEGER(0, "num-thread-synthesize", &top.nr_threads_synthesize, 1385 OPT_UINTEGER(0, "num-thread-synthesize", &top.nr_threads_synthesize,
1377 "number of thread to run event synthesize"), 1386 "number of thread to run event synthesize"),
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7081d7ea12e5..dc8a6c4986ce 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -614,6 +614,7 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size,
614 614
615struct syscall_arg_fmt { 615struct syscall_arg_fmt {
616 size_t (*scnprintf)(char *bf, size_t size, struct syscall_arg *arg); 616 size_t (*scnprintf)(char *bf, size_t size, struct syscall_arg *arg);
617 unsigned long (*mask_val)(struct syscall_arg *arg, unsigned long val);
617 void *parm; 618 void *parm;
618 const char *name; 619 const char *name;
619 bool show_zero; 620 bool show_zero;
@@ -725,6 +726,10 @@ static struct syscall_fmt {
725 .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, 726 .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ },
726 [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, 727 [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ },
727 [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, }, }, 728 [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, }, },
729 { .name = "mount",
730 .arg = { [0] = { .scnprintf = SCA_FILENAME, /* dev_name */ },
731 [3] = { .scnprintf = SCA_MOUNT_FLAGS, /* flags */
732 .mask_val = SCAMV_MOUNT_FLAGS, /* flags */ }, }, },
728 { .name = "mprotect", 733 { .name = "mprotect",
729 .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, 734 .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ },
730 [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, }, }, 735 [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, }, },
@@ -834,7 +839,8 @@ static struct syscall_fmt {
834 .arg = { [2] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, 839 .arg = { [2] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, },
835 { .name = "tkill", 840 { .name = "tkill",
836 .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, 841 .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, },
837 { .name = "umount2", .alias = "umount", }, 842 { .name = "umount2", .alias = "umount",
843 .arg = { [0] = { .scnprintf = SCA_FILENAME, /* name */ }, }, },
838 { .name = "uname", .alias = "newuname", }, 844 { .name = "uname", .alias = "newuname", },
839 { .name = "unlinkat", 845 { .name = "unlinkat",
840 .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, 846 .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, },
@@ -858,6 +864,18 @@ static struct syscall_fmt *syscall_fmt__find(const char *name)
858 return bsearch(name, syscall_fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp); 864 return bsearch(name, syscall_fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp);
859} 865}
860 866
867static struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias)
868{
869 int i, nmemb = ARRAY_SIZE(syscall_fmts);
870
871 for (i = 0; i < nmemb; ++i) {
872 if (syscall_fmts[i].alias && strcmp(syscall_fmts[i].alias, alias) == 0)
873 return &syscall_fmts[i];
874 }
875
876 return NULL;
877}
878
861/* 879/*
862 * is_exit: is this "exit" or "exit_group"? 880 * is_exit: is this "exit" or "exit_group"?
863 * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter. 881 * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter.
@@ -1487,6 +1505,19 @@ static size_t syscall__scnprintf_name(struct syscall *sc, char *bf, size_t size,
1487 return scnprintf(bf, size, "arg%d: ", arg->idx); 1505 return scnprintf(bf, size, "arg%d: ", arg->idx);
1488} 1506}
1489 1507
1508/*
1509 * Check if the value is in fact zero, i.e. mask whatever needs masking, such
1510 * as mount 'flags' argument that needs ignoring some magic flag, see comment
1511 * in tools/perf/trace/beauty/mount_flags.c
1512 */
1513static unsigned long syscall__mask_val(struct syscall *sc, struct syscall_arg *arg, unsigned long val)
1514{
1515 if (sc->arg_fmt && sc->arg_fmt[arg->idx].mask_val)
1516 return sc->arg_fmt[arg->idx].mask_val(arg, val);
1517
1518 return val;
1519}
1520
1490static size_t syscall__scnprintf_val(struct syscall *sc, char *bf, size_t size, 1521static size_t syscall__scnprintf_val(struct syscall *sc, char *bf, size_t size,
1491 struct syscall_arg *arg, unsigned long val) 1522 struct syscall_arg *arg, unsigned long val)
1492{ 1523{
@@ -1535,6 +1566,11 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
1535 continue; 1566 continue;
1536 1567
1537 val = syscall_arg__val(&arg, arg.idx); 1568 val = syscall_arg__val(&arg, arg.idx);
1569 /*
1570 * Some syscall args need some mask, most don't and
1571 * return val untouched.
1572 */
1573 val = syscall__mask_val(sc, &arg, val);
1538 1574
1539 /* 1575 /*
1540 * Suppress this argument if its value is zero and 1576 * Suppress this argument if its value is zero and
@@ -3173,6 +3209,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
3173 int len = strlen(str) + 1, err = -1, list, idx; 3209 int len = strlen(str) + 1, err = -1, list, idx;
3174 char *strace_groups_dir = system_path(STRACE_GROUPS_DIR); 3210 char *strace_groups_dir = system_path(STRACE_GROUPS_DIR);
3175 char group_name[PATH_MAX]; 3211 char group_name[PATH_MAX];
3212 struct syscall_fmt *fmt;
3176 3213
3177 if (strace_groups_dir == NULL) 3214 if (strace_groups_dir == NULL)
3178 return -1; 3215 return -1;
@@ -3190,12 +3227,19 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
3190 if (syscalltbl__id(trace->sctbl, s) >= 0 || 3227 if (syscalltbl__id(trace->sctbl, s) >= 0 ||
3191 syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) { 3228 syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
3192 list = 1; 3229 list = 1;
3230 goto do_concat;
3231 }
3232
3233 fmt = syscall_fmt__find_by_alias(s);
3234 if (fmt != NULL) {
3235 list = 1;
3236 s = fmt->name;
3193 } else { 3237 } else {
3194 path__join(group_name, sizeof(group_name), strace_groups_dir, s); 3238 path__join(group_name, sizeof(group_name), strace_groups_dir, s);
3195 if (access(group_name, R_OK) == 0) 3239 if (access(group_name, R_OK) == 0)
3196 list = 1; 3240 list = 1;
3197 } 3241 }
3198 3242do_concat:
3199 if (lists[list]) { 3243 if (lists[list]) {
3200 sprintf(lists[list] + strlen(lists[list]), ",%s", s); 3244 sprintf(lists[list] + strlen(lists[list]), ",%s", s);
3201 } else { 3245 } else {
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index c72cc73a6b09..9531f7bd7d9b 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -5,6 +5,7 @@ HEADERS='
5include/uapi/drm/drm.h 5include/uapi/drm/drm.h
6include/uapi/drm/i915_drm.h 6include/uapi/drm/i915_drm.h
7include/uapi/linux/fcntl.h 7include/uapi/linux/fcntl.h
8include/uapi/linux/fs.h
8include/uapi/linux/kcmp.h 9include/uapi/linux/kcmp.h
9include/uapi/linux/kvm.h 10include/uapi/linux/kvm.h
10include/uapi/linux/in.h 11include/uapi/linux/in.h
diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build
index c3b0afd67760..304313073242 100644
--- a/tools/perf/trace/beauty/Build
+++ b/tools/perf/trace/beauty/Build
@@ -5,6 +5,7 @@ ifeq ($(SRCARCH),$(filter $(SRCARCH),x86))
5libperf-y += ioctl.o 5libperf-y += ioctl.o
6endif 6endif
7libperf-y += kcmp.o 7libperf-y += kcmp.o
8libperf-y += mount_flags.o
8libperf-y += pkey_alloc.o 9libperf-y += pkey_alloc.o
9libperf-y += prctl.o 10libperf-y += prctl.o
10libperf-y += sockaddr.o 11libperf-y += sockaddr.o
diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h
index 2570152d3909..039c29039b2c 100644
--- a/tools/perf/trace/beauty/beauty.h
+++ b/tools/perf/trace/beauty/beauty.h
@@ -24,6 +24,7 @@ struct strarray {
24} 24}
25 25
26size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val); 26size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val);
27size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, unsigned long flags);
27 28
28struct trace; 29struct trace;
29struct thread; 30struct thread;
@@ -122,6 +123,12 @@ size_t syscall_arg__scnprintf_kcmp_type(char *bf, size_t size, struct syscall_ar
122size_t syscall_arg__scnprintf_kcmp_idx(char *bf, size_t size, struct syscall_arg *arg); 123size_t syscall_arg__scnprintf_kcmp_idx(char *bf, size_t size, struct syscall_arg *arg);
123#define SCA_KCMP_IDX syscall_arg__scnprintf_kcmp_idx 124#define SCA_KCMP_IDX syscall_arg__scnprintf_kcmp_idx
124 125
126unsigned long syscall_arg__mask_val_mount_flags(struct syscall_arg *arg, unsigned long flags);
127#define SCAMV_MOUNT_FLAGS syscall_arg__mask_val_mount_flags
128
129size_t syscall_arg__scnprintf_mount_flags(char *bf, size_t size, struct syscall_arg *arg);
130#define SCA_MOUNT_FLAGS syscall_arg__scnprintf_mount_flags
131
125size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg); 132size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg);
126#define SCA_PKEY_ALLOC_ACCESS_RIGHTS syscall_arg__scnprintf_pkey_alloc_access_rights 133#define SCA_PKEY_ALLOC_ACCESS_RIGHTS syscall_arg__scnprintf_pkey_alloc_access_rights
127 134
diff --git a/tools/perf/trace/beauty/clone.c b/tools/perf/trace/beauty/clone.c
index d64d049ab991..010406500c30 100644
--- a/tools/perf/trace/beauty/clone.c
+++ b/tools/perf/trace/beauty/clone.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/cone.c 3 * trace/beauty/cone.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/drm_ioctl.sh b/tools/perf/trace/beauty/drm_ioctl.sh
index 9d3816815e60..9aa94fd523a9 100755
--- a/tools/perf/trace/beauty/drm_ioctl.sh
+++ b/tools/perf/trace/beauty/drm_ioctl.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/drm/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/drm/
4 5
diff --git a/tools/perf/trace/beauty/eventfd.c b/tools/perf/trace/beauty/eventfd.c
index 5d6a477a6400..db5b9b492113 100644
--- a/tools/perf/trace/beauty/eventfd.c
+++ b/tools/perf/trace/beauty/eventfd.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#ifndef EFD_SEMAPHORE 2#ifndef EFD_SEMAPHORE
3#define EFD_SEMAPHORE 1 3#define EFD_SEMAPHORE 1
4#endif 4#endif
diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c
index 9e8900c13cb1..e6de31674e24 100644
--- a/tools/perf/trace/beauty/fcntl.c
+++ b/tools/perf/trace/beauty/fcntl.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/fcntl.c 3 * trace/beauty/fcntl.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/flock.c b/tools/perf/trace/beauty/flock.c
index c4ff6ad30b06..cf02ae5f0ba6 100644
--- a/tools/perf/trace/beauty/flock.c
+++ b/tools/perf/trace/beauty/flock.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2 2
3#include "trace/beauty/beauty.h" 3#include "trace/beauty/beauty.h"
4#include <linux/kernel.h> 4#include <linux/kernel.h>
diff --git a/tools/perf/trace/beauty/futex_op.c b/tools/perf/trace/beauty/futex_op.c
index 61850fbc85ff..1136bde56406 100644
--- a/tools/perf/trace/beauty/futex_op.c
+++ b/tools/perf/trace/beauty/futex_op.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <linux/futex.h> 2#include <linux/futex.h>
3 3
4#ifndef FUTEX_WAIT_BITSET 4#ifndef FUTEX_WAIT_BITSET
diff --git a/tools/perf/trace/beauty/futex_val3.c b/tools/perf/trace/beauty/futex_val3.c
index 26f6b3253511..138b7d588a70 100644
--- a/tools/perf/trace/beauty/futex_val3.c
+++ b/tools/perf/trace/beauty/futex_val3.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <linux/futex.h> 2#include <linux/futex.h>
3 3
4#ifndef FUTEX_BITSET_MATCH_ANY 4#ifndef FUTEX_BITSET_MATCH_ANY
diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c
index 1be3b4cf0827..5d2a7fd8d407 100644
--- a/tools/perf/trace/beauty/ioctl.c
+++ b/tools/perf/trace/beauty/ioctl.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/ioctl.c 3 * trace/beauty/ioctl.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/kcmp.c b/tools/perf/trace/beauty/kcmp.c
index f62040eb9d5c..b276a274f203 100644
--- a/tools/perf/trace/beauty/kcmp.c
+++ b/tools/perf/trace/beauty/kcmp.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/kcmp.c 3 * trace/beauty/kcmp.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/kcmp_type.sh b/tools/perf/trace/beauty/kcmp_type.sh
index a3c304caa336..df8b17486d57 100755
--- a/tools/perf/trace/beauty/kcmp_type.sh
+++ b/tools/perf/trace/beauty/kcmp_type.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 5
diff --git a/tools/perf/trace/beauty/kvm_ioctl.sh b/tools/perf/trace/beauty/kvm_ioctl.sh
index c4699fd46bb6..4ce54f5bf756 100755
--- a/tools/perf/trace/beauty/kvm_ioctl.sh
+++ b/tools/perf/trace/beauty/kvm_ioctl.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 5
diff --git a/tools/perf/trace/beauty/madvise_behavior.sh b/tools/perf/trace/beauty/madvise_behavior.sh
index 431639eb4d29..4527d290cdfc 100755
--- a/tools/perf/trace/beauty/madvise_behavior.sh
+++ b/tools/perf/trace/beauty/madvise_behavior.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/
4 5
diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c
index 9f68077b241b..c534bd96ef5c 100644
--- a/tools/perf/trace/beauty/mmap.c
+++ b/tools/perf/trace/beauty/mmap.c
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <uapi/linux/mman.h> 2#include <uapi/linux/mman.h>
3#include <linux/log2.h>
3 4
4static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, 5static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
5 struct syscall_arg *arg) 6 struct syscall_arg *arg)
@@ -30,50 +31,23 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
30 31
31#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot 32#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
32 33
34static size_t mmap__scnprintf_flags(unsigned long flags, char *bf, size_t size)
35{
36#include "trace/beauty/generated/mmap_flags_array.c"
37 static DEFINE_STRARRAY(mmap_flags);
38
39 return strarray__scnprintf_flags(&strarray__mmap_flags, bf, size, flags);
40}
41
33static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, 42static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
34 struct syscall_arg *arg) 43 struct syscall_arg *arg)
35{ 44{
36 int printed = 0, flags = arg->val; 45 unsigned long flags = arg->val;
37 46
38 if (flags & MAP_ANONYMOUS) 47 if (flags & MAP_ANONYMOUS)
39 arg->mask |= (1 << 4) | (1 << 5); /* Mask 4th ('fd') and 5th ('offset') args, ignored */ 48 arg->mask |= (1 << 4) | (1 << 5); /* Mask 4th ('fd') and 5th ('offset') args, ignored */
40 49
41#define P_MMAP_FLAG(n) \ 50 return mmap__scnprintf_flags(flags, bf, size);
42 if (flags & MAP_##n) { \
43 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
44 flags &= ~MAP_##n; \
45 }
46
47 P_MMAP_FLAG(SHARED);
48 P_MMAP_FLAG(PRIVATE);
49#ifdef MAP_32BIT
50 P_MMAP_FLAG(32BIT);
51#endif
52 P_MMAP_FLAG(ANONYMOUS);
53 P_MMAP_FLAG(DENYWRITE);
54 P_MMAP_FLAG(EXECUTABLE);
55 P_MMAP_FLAG(FILE);
56 P_MMAP_FLAG(FIXED);
57#ifdef MAP_FIXED_NOREPLACE
58 P_MMAP_FLAG(FIXED_NOREPLACE);
59#endif
60 P_MMAP_FLAG(GROWSDOWN);
61 P_MMAP_FLAG(HUGETLB);
62 P_MMAP_FLAG(LOCKED);
63 P_MMAP_FLAG(NONBLOCK);
64 P_MMAP_FLAG(NORESERVE);
65 P_MMAP_FLAG(POPULATE);
66 P_MMAP_FLAG(STACK);
67 P_MMAP_FLAG(UNINITIALIZED);
68#ifdef MAP_SYNC
69 P_MMAP_FLAG(SYNC);
70#endif
71#undef P_MMAP_FLAG
72
73 if (flags)
74 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
75
76 return printed;
77} 51}
78 52
79#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags 53#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
diff --git a/tools/perf/trace/beauty/mmap_flags.sh b/tools/perf/trace/beauty/mmap_flags.sh
new file mode 100755
index 000000000000..22c3fdca8975
--- /dev/null
+++ b/tools/perf/trace/beauty/mmap_flags.sh
@@ -0,0 +1,32 @@
1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
3
4if [ $# -ne 2 ] ; then
5 [ $# -eq 1 ] && hostarch=$1 || hostarch=`uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/`
6 header_dir=tools/include/uapi/asm-generic
7 arch_header_dir=tools/arch/${hostarch}/include/uapi/asm
8else
9 header_dir=$1
10 arch_header_dir=$2
11fi
12
13arch_mman=${arch_header_dir}/mman.h
14
15# those in egrep -vw are flags, we want just the bits
16
17printf "static const char *mmap_flags[] = {\n"
18regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MAP_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*.*'
19egrep -q $regex ${arch_mman} && \
20(egrep $regex ${arch_mman} | \
21 sed -r "s/$regex/\2 \1/g" | \
22 xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n")
23egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.*' ${arch_mman} &&
24(egrep $regex ${header_dir}/mman-common.h | \
25 egrep -vw 'MAP_(UNINITIALIZED|TYPE|SHARED_VALIDATE)' | \
26 sed -r "s/$regex/\2 \1/g" | \
27 xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n")
28egrep -q '#[[:space:]]*include[[:space:]]+<uapi/asm-generic/mman.h>.*' ${arch_mman} &&
29(egrep $regex ${header_dir}/mman.h | \
30 sed -r "s/$regex/\2 \1/g" | \
31 xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n")
32printf "};\n"
diff --git a/tools/perf/trace/beauty/mode_t.c b/tools/perf/trace/beauty/mode_t.c
index d929ad7dd97b..6879d36d3004 100644
--- a/tools/perf/trace/beauty/mode_t.c
+++ b/tools/perf/trace/beauty/mode_t.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <sys/types.h> 2#include <sys/types.h>
3#include <sys/stat.h> 3#include <sys/stat.h>
4#include <unistd.h> 4#include <unistd.h>
diff --git a/tools/perf/trace/beauty/mount_flags.c b/tools/perf/trace/beauty/mount_flags.c
new file mode 100644
index 000000000000..712935c6620a
--- /dev/null
+++ b/tools/perf/trace/beauty/mount_flags.c
@@ -0,0 +1,43 @@
1// SPDX-License-Identifier: LGPL-2.1
2/*
3 * trace/beauty/mount_flags.c
4 *
5 * Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
6 */
7
8#include "trace/beauty/beauty.h"
9#include <linux/compiler.h>
10#include <linux/kernel.h>
11#include <linux/log2.h>
12#include <sys/mount.h>
13
14static size_t mount__scnprintf_flags(unsigned long flags, char *bf, size_t size)
15{
16#include "trace/beauty/generated/mount_flags_array.c"
17 static DEFINE_STRARRAY(mount_flags);
18
19 return strarray__scnprintf_flags(&strarray__mount_flags, bf, size, flags);
20}
21
22unsigned long syscall_arg__mask_val_mount_flags(struct syscall_arg *arg __maybe_unused, unsigned long flags)
23{
24 // do_mount in fs/namespace.c:
25 /*
26 * Pre-0.97 versions of mount() didn't have a flags word. When the
27 * flags word was introduced its top half was required to have the
28 * magic value 0xC0ED, and this remained so until 2.4.0-test9.
29 * Therefore, if this magic number is present, it carries no
30 * information and must be discarded.
31 */
32 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
33 flags &= ~MS_MGC_MSK;
34
35 return flags;
36}
37
38size_t syscall_arg__scnprintf_mount_flags(char *bf, size_t size, struct syscall_arg *arg)
39{
40 unsigned long flags = arg->val;
41
42 return mount__scnprintf_flags(flags, bf, size);
43}
diff --git a/tools/perf/trace/beauty/mount_flags.sh b/tools/perf/trace/beauty/mount_flags.sh
new file mode 100755
index 000000000000..45547573a1db
--- /dev/null
+++ b/tools/perf/trace/beauty/mount_flags.sh
@@ -0,0 +1,15 @@
1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
3
4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
5
6printf "static const char *mount_flags[] = {\n"
7regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MS_([[:alnum:]_]+)[[:space:]]+([[:digit:]]+)[[:space:]]*.*'
8egrep $regex ${header_dir}/fs.h | egrep -v '(MSK|VERBOSE|MGC_VAL)\>' | \
9 sed -r "s/$regex/\2 \2 \1/g" | sort -n | \
10 xargs printf "\t[%s ? (ilog2(%s) + 1) : 0] = \"%s\",\n"
11regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MS_([[:alnum:]_]+)[[:space:]]+\(1<<([[:digit:]]+)\)[[:space:]]*.*'
12egrep $regex ${header_dir}/fs.h | \
13 sed -r "s/$regex/\2 \1/g" | \
14 xargs printf "\t[%s + 1] = \"%s\",\n"
15printf "};\n"
diff --git a/tools/perf/trace/beauty/msg_flags.c b/tools/perf/trace/beauty/msg_flags.c
index c064d6aae659..1b9d6306d274 100644
--- a/tools/perf/trace/beauty/msg_flags.c
+++ b/tools/perf/trace/beauty/msg_flags.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <sys/types.h> 2#include <sys/types.h>
3#include <sys/socket.h> 3#include <sys/socket.h>
4 4
diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c
index 6aec6178a99d..cc673fec9184 100644
--- a/tools/perf/trace/beauty/open_flags.c
+++ b/tools/perf/trace/beauty/open_flags.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <sys/types.h> 2#include <sys/types.h>
3#include <sys/stat.h> 3#include <sys/stat.h>
4#include <fcntl.h> 4#include <fcntl.h>
diff --git a/tools/perf/trace/beauty/perf_event_open.c b/tools/perf/trace/beauty/perf_event_open.c
index 2bafd7c995ff..981185c1974b 100644
--- a/tools/perf/trace/beauty/perf_event_open.c
+++ b/tools/perf/trace/beauty/perf_event_open.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#ifndef PERF_FLAG_FD_NO_GROUP 2#ifndef PERF_FLAG_FD_NO_GROUP
3# define PERF_FLAG_FD_NO_GROUP (1UL << 0) 3# define PERF_FLAG_FD_NO_GROUP (1UL << 0)
4#endif 4#endif
diff --git a/tools/perf/trace/beauty/perf_ioctl.sh b/tools/perf/trace/beauty/perf_ioctl.sh
index 6492c74df928..9aabd9743ef6 100755
--- a/tools/perf/trace/beauty/perf_ioctl.sh
+++ b/tools/perf/trace/beauty/perf_ioctl.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 5
diff --git a/tools/perf/trace/beauty/pid.c b/tools/perf/trace/beauty/pid.c
index 0313df342830..1a6acc46807b 100644
--- a/tools/perf/trace/beauty/pid.c
+++ b/tools/perf/trace/beauty/pid.c
@@ -1,4 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2
2size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg) 3size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg)
3{ 4{
4 int pid = arg->val; 5 int pid = arg->val;
diff --git a/tools/perf/trace/beauty/pkey_alloc.c b/tools/perf/trace/beauty/pkey_alloc.c
index 2ba784a3734a..1b8ed4cac815 100644
--- a/tools/perf/trace/beauty/pkey_alloc.c
+++ b/tools/perf/trace/beauty/pkey_alloc.c
@@ -1,40 +1,36 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/pkey_alloc.c 3 * trace/beauty/pkey_alloc.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
10#include <linux/kernel.h> 9#include <linux/kernel.h>
11#include <linux/log2.h> 10#include <linux/log2.h>
12 11
13static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size) 12size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, unsigned long flags)
14{ 13{
15 int i, printed = 0; 14 int i, printed = 0;
16 15
17#include "trace/beauty/generated/pkey_alloc_access_rights_array.c" 16 if (flags == 0) {
18 static DEFINE_STRARRAY(pkey_alloc_access_rights); 17 const char *s = sa->entries[0];
19
20 if (access_rights == 0) {
21 const char *s = strarray__pkey_alloc_access_rights.entries[0];
22 if (s) 18 if (s)
23 return scnprintf(bf, size, "%s", s); 19 return scnprintf(bf, size, "%s", s);
24 return scnprintf(bf, size, "%d", 0); 20 return scnprintf(bf, size, "%d", 0);
25 } 21 }
26 22
27 for (i = 1; i < strarray__pkey_alloc_access_rights.nr_entries; ++i) { 23 for (i = 1; i < sa->nr_entries; ++i) {
28 int bit = 1 << (i - 1); 24 unsigned long bit = 1UL << (i - 1);
29 25
30 if (!(access_rights & bit)) 26 if (!(flags & bit))
31 continue; 27 continue;
32 28
33 if (printed != 0) 29 if (printed != 0)
34 printed += scnprintf(bf + printed, size - printed, "|"); 30 printed += scnprintf(bf + printed, size - printed, "|");
35 31
36 if (strarray__pkey_alloc_access_rights.entries[i] != NULL) 32 if (sa->entries[i] != NULL)
37 printed += scnprintf(bf + printed, size - printed, "%s", strarray__pkey_alloc_access_rights.entries[i]); 33 printed += scnprintf(bf + printed, size - printed, "%s", sa->entries[i]);
38 else 34 else
39 printed += scnprintf(bf + printed, size - printed, "0x%#", bit); 35 printed += scnprintf(bf + printed, size - printed, "0x%#", bit);
40 } 36 }
@@ -42,6 +38,14 @@ static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, s
42 return printed; 38 return printed;
43} 39}
44 40
41static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size)
42{
43#include "trace/beauty/generated/pkey_alloc_access_rights_array.c"
44 static DEFINE_STRARRAY(pkey_alloc_access_rights);
45
46 return strarray__scnprintf_flags(&strarray__pkey_alloc_access_rights, bf, size, access_rights);
47}
48
45size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg) 49size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg)
46{ 50{
47 unsigned long cmd = arg->val; 51 unsigned long cmd = arg->val;
diff --git a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh
index e0a51aeb20b2..f8f1b560cf8a 100755
--- a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh
+++ b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/
4 5
diff --git a/tools/perf/trace/beauty/prctl.c b/tools/perf/trace/beauty/prctl.c
index 246130dad6c4..be7a5d395975 100644
--- a/tools/perf/trace/beauty/prctl.c
+++ b/tools/perf/trace/beauty/prctl.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/prctl.c 3 * trace/beauty/prctl.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/prctl_option.sh b/tools/perf/trace/beauty/prctl_option.sh
index f24722146ebe..d32f8f1124af 100755
--- a/tools/perf/trace/beauty/prctl_option.sh
+++ b/tools/perf/trace/beauty/prctl_option.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 5
diff --git a/tools/perf/trace/beauty/sched_policy.c b/tools/perf/trace/beauty/sched_policy.c
index ba5096ae76b6..48f2b5c9aa3e 100644
--- a/tools/perf/trace/beauty/sched_policy.c
+++ b/tools/perf/trace/beauty/sched_policy.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <sched.h> 2#include <sched.h>
3 3
4/* 4/*
diff --git a/tools/perf/trace/beauty/seccomp.c b/tools/perf/trace/beauty/seccomp.c
index b7097fd5fed9..e36156b19c70 100644
--- a/tools/perf/trace/beauty/seccomp.c
+++ b/tools/perf/trace/beauty/seccomp.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#ifndef SECCOMP_SET_MODE_STRICT 2#ifndef SECCOMP_SET_MODE_STRICT
3#define SECCOMP_SET_MODE_STRICT 0 3#define SECCOMP_SET_MODE_STRICT 0
4#endif 4#endif
diff --git a/tools/perf/trace/beauty/signum.c b/tools/perf/trace/beauty/signum.c
index bde18a53f090..587fec545b8a 100644
--- a/tools/perf/trace/beauty/signum.c
+++ b/tools/perf/trace/beauty/signum.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <signal.h> 2#include <signal.h>
3 3
4static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg) 4static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
diff --git a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
index eb511bb5fbd3..e0803b957593 100755
--- a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
+++ b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/
4 5
diff --git a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
index 6818392968b2..7a464a7bf913 100755
--- a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
+++ b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/
4 5
diff --git a/tools/perf/trace/beauty/sockaddr.c b/tools/perf/trace/beauty/sockaddr.c
index 71a79f72d9d9..9410ad230f10 100644
--- a/tools/perf/trace/beauty/sockaddr.c
+++ b/tools/perf/trace/beauty/sockaddr.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 2// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 3
4#include "trace/beauty/beauty.h" 4#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c
index 65227269384b..d971a2596417 100644
--- a/tools/perf/trace/beauty/socket.c
+++ b/tools/perf/trace/beauty/socket.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2/* 2/*
3 * trace/beauty/socket.c 3 * trace/beauty/socket.c
4 * 4 *
diff --git a/tools/perf/trace/beauty/socket_ipproto.sh b/tools/perf/trace/beauty/socket_ipproto.sh
index a3cc24633bec..de0f2f29017f 100755
--- a/tools/perf/trace/beauty/socket_ipproto.sh
+++ b/tools/perf/trace/beauty/socket_ipproto.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 5
diff --git a/tools/perf/trace/beauty/socket_type.c b/tools/perf/trace/beauty/socket_type.c
index bca26aef4a77..a63a9a332aa0 100644
--- a/tools/perf/trace/beauty/socket_type.c
+++ b/tools/perf/trace/beauty/socket_type.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <sys/types.h> 2#include <sys/types.h>
3#include <sys/socket.h> 3#include <sys/socket.h>
4 4
diff --git a/tools/perf/trace/beauty/statx.c b/tools/perf/trace/beauty/statx.c
index 5643b692af4c..630f2760dd66 100644
--- a/tools/perf/trace/beauty/statx.c
+++ b/tools/perf/trace/beauty/statx.c
@@ -1,9 +1,8 @@
1// SPDX-License-Identifier: LGPL-2.1
1/* 2/*
2 * trace/beauty/statx.c 3 * trace/beauty/statx.c
3 * 4 *
4 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
5 *
6 * Released under the GPL v2. (and only v2, not any later version)
7 */ 6 */
8 7
9#include "trace/beauty/beauty.h" 8#include "trace/beauty/beauty.h"
diff --git a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
index 0f6a5197d0be..439773daaf77 100755
--- a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
+++ b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
@@ -1,4 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: LGPL-2.1
2 3
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ 4[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 5
diff --git a/tools/perf/trace/beauty/waitid_options.c b/tools/perf/trace/beauty/waitid_options.c
index 8465281a093d..42ff58ad613b 100644
--- a/tools/perf/trace/beauty/waitid_options.c
+++ b/tools/perf/trace/beauty/waitid_options.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: LGPL-2.1
2#include <sys/types.h> 2#include <sys/types.h>
3#include <sys/wait.h> 3#include <sys/wait.h>
4 4
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 3b37d66dc533..73430b73570d 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -244,6 +244,27 @@ static void cs_etm__free(struct perf_session *session)
244 zfree(&aux); 244 zfree(&aux);
245} 245}
246 246
247static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address)
248{
249 struct machine *machine;
250
251 machine = etmq->etm->machine;
252
253 if (address >= etmq->etm->kernel_start) {
254 if (machine__is_host(machine))
255 return PERF_RECORD_MISC_KERNEL;
256 else
257 return PERF_RECORD_MISC_GUEST_KERNEL;
258 } else {
259 if (machine__is_host(machine))
260 return PERF_RECORD_MISC_USER;
261 else if (perf_guest)
262 return PERF_RECORD_MISC_GUEST_USER;
263 else
264 return PERF_RECORD_MISC_HYPERVISOR;
265 }
266}
267
247static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address, 268static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address,
248 size_t size, u8 *buffer) 269 size_t size, u8 *buffer)
249{ 270{
@@ -258,10 +279,7 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address,
258 return -1; 279 return -1;
259 280
260 machine = etmq->etm->machine; 281 machine = etmq->etm->machine;
261 if (address >= etmq->etm->kernel_start) 282 cpumode = cs_etm__cpu_mode(etmq, address);
262 cpumode = PERF_RECORD_MISC_KERNEL;
263 else
264 cpumode = PERF_RECORD_MISC_USER;
265 283
266 thread = etmq->thread; 284 thread = etmq->thread;
267 if (!thread) { 285 if (!thread) {
@@ -653,7 +671,7 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
653 struct perf_sample sample = {.ip = 0,}; 671 struct perf_sample sample = {.ip = 0,};
654 672
655 event->sample.header.type = PERF_RECORD_SAMPLE; 673 event->sample.header.type = PERF_RECORD_SAMPLE;
656 event->sample.header.misc = PERF_RECORD_MISC_USER; 674 event->sample.header.misc = cs_etm__cpu_mode(etmq, addr);
657 event->sample.header.size = sizeof(struct perf_event_header); 675 event->sample.header.size = sizeof(struct perf_event_header);
658 676
659 sample.ip = addr; 677 sample.ip = addr;
@@ -665,7 +683,7 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
665 sample.cpu = etmq->packet->cpu; 683 sample.cpu = etmq->packet->cpu;
666 sample.flags = 0; 684 sample.flags = 0;
667 sample.insn_len = 1; 685 sample.insn_len = 1;
668 sample.cpumode = event->header.misc; 686 sample.cpumode = event->sample.header.misc;
669 687
670 if (etm->synth_opts.last_branch) { 688 if (etm->synth_opts.last_branch) {
671 cs_etm__copy_last_branch_rb(etmq); 689 cs_etm__copy_last_branch_rb(etmq);
@@ -706,12 +724,15 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq)
706 u64 nr; 724 u64 nr;
707 struct branch_entry entries; 725 struct branch_entry entries;
708 } dummy_bs; 726 } dummy_bs;
727 u64 ip;
728
729 ip = cs_etm__last_executed_instr(etmq->prev_packet);
709 730
710 event->sample.header.type = PERF_RECORD_SAMPLE; 731 event->sample.header.type = PERF_RECORD_SAMPLE;
711 event->sample.header.misc = PERF_RECORD_MISC_USER; 732 event->sample.header.misc = cs_etm__cpu_mode(etmq, ip);
712 event->sample.header.size = sizeof(struct perf_event_header); 733 event->sample.header.size = sizeof(struct perf_event_header);
713 734
714 sample.ip = cs_etm__last_executed_instr(etmq->prev_packet); 735 sample.ip = ip;
715 sample.pid = etmq->pid; 736 sample.pid = etmq->pid;
716 sample.tid = etmq->tid; 737 sample.tid = etmq->tid;
717 sample.addr = cs_etm__first_executed_instr(etmq->packet); 738 sample.addr = cs_etm__first_executed_instr(etmq->packet);
@@ -720,7 +741,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq)
720 sample.period = 1; 741 sample.period = 1;
721 sample.cpu = etmq->packet->cpu; 742 sample.cpu = etmq->packet->cpu;
722 sample.flags = 0; 743 sample.flags = 0;
723 sample.cpumode = PERF_RECORD_MISC_USER; 744 sample.cpumode = event->sample.header.misc;
724 745
725 /* 746 /*
726 * perf report cannot handle events without a branch stack 747 * perf report cannot handle events without a branch stack
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index bc646185f8d9..e9c108a6b1c3 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -308,6 +308,7 @@ static int perf_event__synthesize_fork(struct perf_tool *tool,
308 event->fork.pid = tgid; 308 event->fork.pid = tgid;
309 event->fork.tid = pid; 309 event->fork.tid = pid;
310 event->fork.header.type = PERF_RECORD_FORK; 310 event->fork.header.type = PERF_RECORD_FORK;
311 event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC;
311 312
312 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size); 313 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size);
313 314
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index 3b3a3d55dca1..7b27d77306c2 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -269,6 +269,13 @@ static int intel_bts_do_fix_overlap(struct auxtrace_queue *queue,
269 return 0; 269 return 0;
270} 270}
271 271
272static inline u8 intel_bts_cpumode(struct intel_bts *bts, uint64_t ip)
273{
274 return machine__kernel_ip(bts->machine, ip) ?
275 PERF_RECORD_MISC_KERNEL :
276 PERF_RECORD_MISC_USER;
277}
278
272static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq, 279static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
273 struct branch *branch) 280 struct branch *branch)
274{ 281{
@@ -281,12 +288,8 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
281 bts->num_events++ <= bts->synth_opts.initial_skip) 288 bts->num_events++ <= bts->synth_opts.initial_skip)
282 return 0; 289 return 0;
283 290
284 event.sample.header.type = PERF_RECORD_SAMPLE;
285 event.sample.header.misc = PERF_RECORD_MISC_USER;
286 event.sample.header.size = sizeof(struct perf_event_header);
287
288 sample.cpumode = PERF_RECORD_MISC_USER;
289 sample.ip = le64_to_cpu(branch->from); 291 sample.ip = le64_to_cpu(branch->from);
292 sample.cpumode = intel_bts_cpumode(bts, sample.ip);
290 sample.pid = btsq->pid; 293 sample.pid = btsq->pid;
291 sample.tid = btsq->tid; 294 sample.tid = btsq->tid;
292 sample.addr = le64_to_cpu(branch->to); 295 sample.addr = le64_to_cpu(branch->to);
@@ -298,6 +301,10 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
298 sample.insn_len = btsq->intel_pt_insn.length; 301 sample.insn_len = btsq->intel_pt_insn.length;
299 memcpy(sample.insn, btsq->intel_pt_insn.buf, INTEL_PT_INSN_BUF_SZ); 302 memcpy(sample.insn, btsq->intel_pt_insn.buf, INTEL_PT_INSN_BUF_SZ);
300 303
304 event.sample.header.type = PERF_RECORD_SAMPLE;
305 event.sample.header.misc = sample.cpumode;
306 event.sample.header.size = sizeof(struct perf_event_header);
307
301 if (bts->synth_opts.inject) { 308 if (bts->synth_opts.inject) {
302 event.sample.header.size = bts->branches_event_size; 309 event.sample.header.size = bts->branches_event_size;
303 ret = perf_event__synthesize_sample(&event, 310 ret = perf_event__synthesize_sample(&event,
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index ffa385a029b3..86cc9a64e982 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -407,6 +407,13 @@ intel_pt_cache_lookup(struct dso *dso, struct machine *machine, u64 offset)
407 return auxtrace_cache__lookup(dso->auxtrace_cache, offset); 407 return auxtrace_cache__lookup(dso->auxtrace_cache, offset);
408} 408}
409 409
410static inline u8 intel_pt_cpumode(struct intel_pt *pt, uint64_t ip)
411{
412 return ip >= pt->kernel_start ?
413 PERF_RECORD_MISC_KERNEL :
414 PERF_RECORD_MISC_USER;
415}
416
410static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, 417static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
411 uint64_t *insn_cnt_ptr, uint64_t *ip, 418 uint64_t *insn_cnt_ptr, uint64_t *ip,
412 uint64_t to_ip, uint64_t max_insn_cnt, 419 uint64_t to_ip, uint64_t max_insn_cnt,
@@ -429,10 +436,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
429 if (to_ip && *ip == to_ip) 436 if (to_ip && *ip == to_ip)
430 goto out_no_cache; 437 goto out_no_cache;
431 438
432 if (*ip >= ptq->pt->kernel_start) 439 cpumode = intel_pt_cpumode(ptq->pt, *ip);
433 cpumode = PERF_RECORD_MISC_KERNEL;
434 else
435 cpumode = PERF_RECORD_MISC_USER;
436 440
437 thread = ptq->thread; 441 thread = ptq->thread;
438 if (!thread) { 442 if (!thread) {
@@ -759,7 +763,8 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
759 if (pt->synth_opts.callchain) { 763 if (pt->synth_opts.callchain) {
760 size_t sz = sizeof(struct ip_callchain); 764 size_t sz = sizeof(struct ip_callchain);
761 765
762 sz += pt->synth_opts.callchain_sz * sizeof(u64); 766 /* Add 1 to callchain_sz for callchain context */
767 sz += (pt->synth_opts.callchain_sz + 1) * sizeof(u64);
763 ptq->chain = zalloc(sz); 768 ptq->chain = zalloc(sz);
764 if (!ptq->chain) 769 if (!ptq->chain)
765 goto out_free; 770 goto out_free;
@@ -1058,15 +1063,11 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
1058 union perf_event *event, 1063 union perf_event *event,
1059 struct perf_sample *sample) 1064 struct perf_sample *sample)
1060{ 1065{
1061 event->sample.header.type = PERF_RECORD_SAMPLE;
1062 event->sample.header.misc = PERF_RECORD_MISC_USER;
1063 event->sample.header.size = sizeof(struct perf_event_header);
1064
1065 if (!pt->timeless_decoding) 1066 if (!pt->timeless_decoding)
1066 sample->time = tsc_to_perf_time(ptq->timestamp, &pt->tc); 1067 sample->time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
1067 1068
1068 sample->cpumode = PERF_RECORD_MISC_USER;
1069 sample->ip = ptq->state->from_ip; 1069 sample->ip = ptq->state->from_ip;
1070 sample->cpumode = intel_pt_cpumode(pt, sample->ip);
1070 sample->pid = ptq->pid; 1071 sample->pid = ptq->pid;
1071 sample->tid = ptq->tid; 1072 sample->tid = ptq->tid;
1072 sample->addr = ptq->state->to_ip; 1073 sample->addr = ptq->state->to_ip;
@@ -1075,6 +1076,10 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
1075 sample->flags = ptq->flags; 1076 sample->flags = ptq->flags;
1076 sample->insn_len = ptq->insn_len; 1077 sample->insn_len = ptq->insn_len;
1077 memcpy(sample->insn, ptq->insn, INTEL_PT_INSN_BUF_SZ); 1078 memcpy(sample->insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
1079
1080 event->sample.header.type = PERF_RECORD_SAMPLE;
1081 event->sample.header.misc = sample->cpumode;
1082 event->sample.header.size = sizeof(struct perf_event_header);
1078} 1083}
1079 1084
1080static int intel_pt_inject_event(union perf_event *event, 1085static int intel_pt_inject_event(union perf_event *event,
@@ -1160,7 +1165,8 @@ static void intel_pt_prep_sample(struct intel_pt *pt,
1160 1165
1161 if (pt->synth_opts.callchain) { 1166 if (pt->synth_opts.callchain) {
1162 thread_stack__sample(ptq->thread, ptq->chain, 1167 thread_stack__sample(ptq->thread, ptq->chain,
1163 pt->synth_opts.callchain_sz, sample->ip); 1168 pt->synth_opts.callchain_sz + 1,
1169 sample->ip, pt->kernel_start);
1164 sample->callchain = ptq->chain; 1170 sample->callchain = ptq->chain;
1165 } 1171 }
1166 1172
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 111ae858cbcb..8f36ce813bc5 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1708,6 +1708,7 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
1708 struct thread *parent = machine__findnew_thread(machine, 1708 struct thread *parent = machine__findnew_thread(machine,
1709 event->fork.ppid, 1709 event->fork.ppid,
1710 event->fork.ptid); 1710 event->fork.ptid);
1711 bool do_maps_clone = true;
1711 int err = 0; 1712 int err = 0;
1712 1713
1713 if (dump_trace) 1714 if (dump_trace)
@@ -1736,9 +1737,25 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
1736 1737
1737 thread = machine__findnew_thread(machine, event->fork.pid, 1738 thread = machine__findnew_thread(machine, event->fork.pid,
1738 event->fork.tid); 1739 event->fork.tid);
1740 /*
1741 * When synthesizing FORK events, we are trying to create thread
1742 * objects for the already running tasks on the machine.
1743 *
1744 * Normally, for a kernel FORK event, we want to clone the parent's
1745 * maps because that is what the kernel just did.
1746 *
1747 * But when synthesizing, this should not be done. If we do, we end up
1748 * with overlapping maps as we process the sythesized MMAP2 events that
1749 * get delivered shortly thereafter.
1750 *
1751 * Use the FORK event misc flags in an internal way to signal this
1752 * situation, so we can elide the map clone when appropriate.
1753 */
1754 if (event->fork.header.misc & PERF_RECORD_MISC_FORK_EXEC)
1755 do_maps_clone = false;
1739 1756
1740 if (thread == NULL || parent == NULL || 1757 if (thread == NULL || parent == NULL ||
1741 thread__fork(thread, parent, sample->time) < 0) { 1758 thread__fork(thread, parent, sample->time, do_maps_clone) < 0) {
1742 dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); 1759 dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
1743 err = -1; 1760 err = -1;
1744 } 1761 }
@@ -2140,6 +2157,27 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
2140 return 0; 2157 return 0;
2141} 2158}
2142 2159
2160static int find_prev_cpumode(struct ip_callchain *chain, struct thread *thread,
2161 struct callchain_cursor *cursor,
2162 struct symbol **parent,
2163 struct addr_location *root_al,
2164 u8 *cpumode, int ent)
2165{
2166 int err = 0;
2167
2168 while (--ent >= 0) {
2169 u64 ip = chain->ips[ent];
2170
2171 if (ip >= PERF_CONTEXT_MAX) {
2172 err = add_callchain_ip(thread, cursor, parent,
2173 root_al, cpumode, ip,
2174 false, NULL, NULL, 0);
2175 break;
2176 }
2177 }
2178 return err;
2179}
2180
2143static int thread__resolve_callchain_sample(struct thread *thread, 2181static int thread__resolve_callchain_sample(struct thread *thread,
2144 struct callchain_cursor *cursor, 2182 struct callchain_cursor *cursor,
2145 struct perf_evsel *evsel, 2183 struct perf_evsel *evsel,
@@ -2246,6 +2284,12 @@ static int thread__resolve_callchain_sample(struct thread *thread,
2246 } 2284 }
2247 2285
2248check_calls: 2286check_calls:
2287 if (callchain_param.order != ORDER_CALLEE) {
2288 err = find_prev_cpumode(chain, thread, cursor, parent, root_al,
2289 &cpumode, chain->nr - first_call);
2290 if (err)
2291 return (err < 0) ? err : 0;
2292 }
2249 for (i = first_call, nr_entries = 0; 2293 for (i = first_call, nr_entries = 0;
2250 i < chain_nr && nr_entries < max_stack; i++) { 2294 i < chain_nr && nr_entries < max_stack; i++) {
2251 u64 ip; 2295 u64 ip;
@@ -2260,9 +2304,15 @@ check_calls:
2260 continue; 2304 continue;
2261#endif 2305#endif
2262 ip = chain->ips[j]; 2306 ip = chain->ips[j];
2263
2264 if (ip < PERF_CONTEXT_MAX) 2307 if (ip < PERF_CONTEXT_MAX)
2265 ++nr_entries; 2308 ++nr_entries;
2309 else if (callchain_param.order != ORDER_CALLEE) {
2310 err = find_prev_cpumode(chain, thread, cursor, parent,
2311 root_al, &cpumode, j);
2312 if (err)
2313 return (err < 0) ? err : 0;
2314 continue;
2315 }
2266 2316
2267 err = add_callchain_ip(thread, cursor, parent, 2317 err = add_callchain_ip(thread, cursor, parent,
2268 root_al, &cpumode, ip, 2318 root_al, &cpumode, ip,
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index c091635bf7dc..61a4286a74dc 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -310,20 +310,46 @@ void thread_stack__free(struct thread *thread)
310 } 310 }
311} 311}
312 312
313static inline u64 callchain_context(u64 ip, u64 kernel_start)
314{
315 return ip < kernel_start ? PERF_CONTEXT_USER : PERF_CONTEXT_KERNEL;
316}
317
313void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, 318void thread_stack__sample(struct thread *thread, struct ip_callchain *chain,
314 size_t sz, u64 ip) 319 size_t sz, u64 ip, u64 kernel_start)
315{ 320{
316 size_t i; 321 u64 context = callchain_context(ip, kernel_start);
322 u64 last_context;
323 size_t i, j;
317 324
318 if (!thread || !thread->ts) 325 if (sz < 2) {
319 chain->nr = 1; 326 chain->nr = 0;
320 else 327 return;
321 chain->nr = min(sz, thread->ts->cnt + 1); 328 }
322 329
323 chain->ips[0] = ip; 330 chain->ips[0] = context;
331 chain->ips[1] = ip;
332
333 if (!thread || !thread->ts) {
334 chain->nr = 2;
335 return;
336 }
337
338 last_context = context;
339
340 for (i = 2, j = 1; i < sz && j <= thread->ts->cnt; i++, j++) {
341 ip = thread->ts->stack[thread->ts->cnt - j].ret_addr;
342 context = callchain_context(ip, kernel_start);
343 if (context != last_context) {
344 if (i >= sz - 1)
345 break;
346 chain->ips[i++] = context;
347 last_context = context;
348 }
349 chain->ips[i] = ip;
350 }
324 351
325 for (i = 1; i < chain->nr; i++) 352 chain->nr = i;
326 chain->ips[i] = thread->ts->stack[thread->ts->cnt - i].ret_addr;
327} 353}
328 354
329struct call_return_processor * 355struct call_return_processor *
diff --git a/tools/perf/util/thread-stack.h b/tools/perf/util/thread-stack.h
index b7e41c4ebfdd..f97c00a8c251 100644
--- a/tools/perf/util/thread-stack.h
+++ b/tools/perf/util/thread-stack.h
@@ -84,7 +84,7 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
84 u64 to_ip, u16 insn_len, u64 trace_nr); 84 u64 to_ip, u16 insn_len, u64 trace_nr);
85void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr); 85void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr);
86void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, 86void thread_stack__sample(struct thread *thread, struct ip_callchain *chain,
87 size_t sz, u64 ip); 87 size_t sz, u64 ip, u64 kernel_start);
88int thread_stack__flush(struct thread *thread); 88int thread_stack__flush(struct thread *thread);
89void thread_stack__free(struct thread *thread); 89void thread_stack__free(struct thread *thread);
90size_t thread_stack__depth(struct thread *thread); 90size_t thread_stack__depth(struct thread *thread);
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 2048d393ece6..3d9ed7d0e281 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -330,7 +330,8 @@ static int thread__prepare_access(struct thread *thread)
330} 330}
331 331
332static int thread__clone_map_groups(struct thread *thread, 332static int thread__clone_map_groups(struct thread *thread,
333 struct thread *parent) 333 struct thread *parent,
334 bool do_maps_clone)
334{ 335{
335 /* This is new thread, we share map groups for process. */ 336 /* This is new thread, we share map groups for process. */
336 if (thread->pid_ == parent->pid_) 337 if (thread->pid_ == parent->pid_)
@@ -341,15 +342,11 @@ static int thread__clone_map_groups(struct thread *thread,
341 thread->pid_, thread->tid, parent->pid_, parent->tid); 342 thread->pid_, thread->tid, parent->pid_, parent->tid);
342 return 0; 343 return 0;
343 } 344 }
344
345 /* But this one is new process, copy maps. */ 345 /* But this one is new process, copy maps. */
346 if (map_groups__clone(thread, parent->mg) < 0) 346 return do_maps_clone ? map_groups__clone(thread, parent->mg) : 0;
347 return -ENOMEM;
348
349 return 0;
350} 347}
351 348
352int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) 349int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone)
353{ 350{
354 if (parent->comm_set) { 351 if (parent->comm_set) {
355 const char *comm = thread__comm_str(parent); 352 const char *comm = thread__comm_str(parent);
@@ -362,7 +359,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
362 } 359 }
363 360
364 thread->ppid = parent->tid; 361 thread->ppid = parent->tid;
365 return thread__clone_map_groups(thread, parent); 362 return thread__clone_map_groups(thread, parent, do_maps_clone);
366} 363}
367 364
368void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, 365void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 36c09a9904e6..30e2b4c165fe 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -89,7 +89,7 @@ struct comm *thread__comm(const struct thread *thread);
89struct comm *thread__exec_comm(const struct thread *thread); 89struct comm *thread__exec_comm(const struct thread *thread);
90const char *thread__comm_str(const struct thread *thread); 90const char *thread__comm_str(const struct thread *thread);
91int thread__insert_map(struct thread *thread, struct map *map); 91int thread__insert_map(struct thread *thread, struct map *map);
92int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp); 92int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone);
93size_t thread__fprintf(struct thread *thread, FILE *fp); 93size_t thread__fprintf(struct thread *thread, FILE *fp);
94 94
95struct thread *thread__main_thread(struct machine *machine, struct thread *thread); 95struct thread *thread__main_thread(struct machine *machine, struct thread *thread);
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 6f318b15950e..5eff9bfc5758 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -45,13 +45,13 @@ static int __report_module(struct addr_location *al, u64 ip,
45 Dwarf_Addr s; 45 Dwarf_Addr s;
46 46
47 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); 47 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
48 if (s != al->map->start) 48 if (s != al->map->start - al->map->pgoff)
49 mod = 0; 49 mod = 0;
50 } 50 }
51 51
52 if (!mod) 52 if (!mod)
53 mod = dwfl_report_elf(ui->dwfl, dso->short_name, 53 mod = dwfl_report_elf(ui->dwfl, dso->short_name,
54 (dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start, 54 (dso->symsrc_filename ? dso->symsrc_filename : dso->long_name), -1, al->map->start - al->map->pgoff,
55 false); 55 false);
56 56
57 return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1; 57 return mod && dwfl_addrmodule(ui->dwfl, ip) == mod ? 0 : -1;