aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-10-03 12:30:24 -0400
committerIngo Molnar <mingo@kernel.org>2017-10-03 12:30:24 -0400
commit4b50239a769e78bbe362fc92c3f8bd5415a4a5f5 (patch)
tree951832e213945ede19cd676a04e5218e68afd074
parenta47ba4d77e1236d214e5116b5631bc4c2d6e6369 (diff)
parentf6a9820d572bd8384d982357cbad214b3a6c04bb (diff)
Merge tag 'perf-core-for-mingo-4.15-20171003' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: - Multithread the synthesizing of PERF_RECORD_ events for pre-existing threads in 'perf top', speeding up that phase, greatly improving the user experience in systems such as Intel's Knights Mill (Kan Liang) - 'perf test' fixes for the perf_event_attr test case (Jiri Olsa, Thomas Richter) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/arch/s390/include/uapi/asm/kvm.h6
-rw-r--r--tools/arch/x86/include/asm/cpufeatures.h2
-rw-r--r--tools/arch/x86/include/asm/disabled-features.h4
-rw-r--r--tools/include/asm-generic/hugetlb_encode.h34
-rw-r--r--tools/include/uapi/drm/drm.h22
-rw-r--r--tools/include/uapi/drm/i915_drm.h51
-rw-r--r--tools/include/uapi/linux/bpf.h32
-rw-r--r--tools/include/uapi/linux/kvm.h3
-rw-r--r--tools/include/uapi/linux/mman.h24
-rw-r--r--tools/perf/Documentation/perf-top.txt3
-rw-r--r--tools/perf/arch/s390/util/Build1
-rw-r--r--tools/perf/arch/s390/util/sym-handling.c29
-rw-r--r--tools/perf/builtin-kvm.c3
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-top.c13
-rw-r--r--tools/perf/builtin-trace.c2
-rw-r--r--tools/perf/tests/attr.c2
-rw-r--r--tools/perf/tests/attr.py6
-rw-r--r--tools/perf/tests/attr/base-record2
-rw-r--r--tools/perf/tests/attr/test-record-group1
-rw-r--r--tools/perf/tests/attr/test-record-group-sampling2
-rw-r--r--tools/perf/tests/attr/test-record-group11
-rw-r--r--tools/perf/tests/attr/test-stat-group2
-rw-r--r--tools/perf/tests/attr/test-stat-group12
-rw-r--r--tools/perf/tests/mmap-thread-lookup.c2
-rw-r--r--tools/perf/util/callchain.c35
-rw-r--r--tools/perf/util/comm.c18
-rw-r--r--tools/perf/util/event.c163
-rw-r--r--tools/perf/util/event.h3
-rw-r--r--tools/perf/util/evsel.c7
-rw-r--r--tools/perf/util/machine.c8
-rw-r--r--tools/perf/util/machine.h9
-rw-r--r--tools/perf/util/symbol-elf.c8
-rw-r--r--tools/perf/util/symbol.h3
-rw-r--r--tools/perf/util/syscalltbl.c2
-rw-r--r--tools/perf/util/thread.c53
-rw-r--r--tools/perf/util/thread.h3
-rw-r--r--tools/perf/util/top.h1
38 files changed, 439 insertions, 125 deletions
diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
index 69d09c39bbcd..cd7359e23d86 100644
--- a/tools/arch/s390/include/uapi/asm/kvm.h
+++ b/tools/arch/s390/include/uapi/asm/kvm.h
@@ -88,6 +88,12 @@ struct kvm_s390_io_adapter_req {
88/* kvm attributes for KVM_S390_VM_TOD */ 88/* kvm attributes for KVM_S390_VM_TOD */
89#define KVM_S390_VM_TOD_LOW 0 89#define KVM_S390_VM_TOD_LOW 0
90#define KVM_S390_VM_TOD_HIGH 1 90#define KVM_S390_VM_TOD_HIGH 1
91#define KVM_S390_VM_TOD_EXT 2
92
93struct kvm_s390_vm_tod_clock {
94 __u8 epoch_idx;
95 __u64 tod;
96};
91 97
92/* kvm attributes for KVM_S390_VM_CPU_MODEL */ 98/* kvm attributes for KVM_S390_VM_CPU_MODEL */
93/* processor related attributes are r/w */ 99/* processor related attributes are r/w */
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 8ea315a11fe0..2519c6c801c9 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -196,6 +196,7 @@
196 196
197#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ 197#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
198#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ 198#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
199#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */
199 200
200#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ 201#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */
201#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ 202#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
@@ -287,6 +288,7 @@
287#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ 288#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
288#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ 289#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
289#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ 290#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */
291#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */
290 292
291/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ 293/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
292#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ 294#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
index 5dff775af7cd..c10c9128f54e 100644
--- a/tools/arch/x86/include/asm/disabled-features.h
+++ b/tools/arch/x86/include/asm/disabled-features.h
@@ -21,11 +21,13 @@
21# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) 21# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
22# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) 22# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
23# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) 23# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
24# define DISABLE_PCID 0
24#else 25#else
25# define DISABLE_VME 0 26# define DISABLE_VME 0
26# define DISABLE_K6_MTRR 0 27# define DISABLE_K6_MTRR 0
27# define DISABLE_CYRIX_ARR 0 28# define DISABLE_CYRIX_ARR 0
28# define DISABLE_CENTAUR_MCR 0 29# define DISABLE_CENTAUR_MCR 0
30# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
29#endif /* CONFIG_X86_64 */ 31#endif /* CONFIG_X86_64 */
30 32
31#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS 33#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
@@ -49,7 +51,7 @@
49#define DISABLED_MASK1 0 51#define DISABLED_MASK1 0
50#define DISABLED_MASK2 0 52#define DISABLED_MASK2 0
51#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) 53#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
52#define DISABLED_MASK4 0 54#define DISABLED_MASK4 (DISABLE_PCID)
53#define DISABLED_MASK5 0 55#define DISABLED_MASK5 0
54#define DISABLED_MASK6 0 56#define DISABLED_MASK6 0
55#define DISABLED_MASK7 0 57#define DISABLED_MASK7 0
diff --git a/tools/include/asm-generic/hugetlb_encode.h b/tools/include/asm-generic/hugetlb_encode.h
new file mode 100644
index 000000000000..e4732d3c2998
--- /dev/null
+++ b/tools/include/asm-generic/hugetlb_encode.h
@@ -0,0 +1,34 @@
1#ifndef _ASM_GENERIC_HUGETLB_ENCODE_H_
2#define _ASM_GENERIC_HUGETLB_ENCODE_H_
3
4/*
5 * Several system calls take a flag to request "hugetlb" huge pages.
6 * Without further specification, these system calls will use the
7 * system's default huge page size. If a system supports multiple
8 * huge page sizes, the desired huge page size can be specified in
9 * bits [26:31] of the flag arguments. The value in these 6 bits
10 * will encode the log2 of the huge page size.
11 *
12 * The following definitions are associated with this huge page size
13 * encoding in flag arguments. System call specific header files
14 * that use this encoding should include this file. They can then
15 * provide definitions based on these with their own specific prefix.
16 * for example:
17 * #define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
18 */
19
20#define HUGETLB_FLAG_ENCODE_SHIFT 26
21#define HUGETLB_FLAG_ENCODE_MASK 0x3f
22
23#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT)
24#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT)
25#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT)
26#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT)
27#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT)
28#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT)
29#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT)
30#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT)
31#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT)
32#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT)
33
34#endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */
diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h
index 101593ab10ac..97677cd6964d 100644
--- a/tools/include/uapi/drm/drm.h
+++ b/tools/include/uapi/drm/drm.h
@@ -700,6 +700,7 @@ struct drm_prime_handle {
700 700
701struct drm_syncobj_create { 701struct drm_syncobj_create {
702 __u32 handle; 702 __u32 handle;
703#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
703 __u32 flags; 704 __u32 flags;
704}; 705};
705 706
@@ -718,6 +719,24 @@ struct drm_syncobj_handle {
718 __u32 pad; 719 __u32 pad;
719}; 720};
720 721
722#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
723#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
724struct drm_syncobj_wait {
725 __u64 handles;
726 /* absolute timeout */
727 __s64 timeout_nsec;
728 __u32 count_handles;
729 __u32 flags;
730 __u32 first_signaled; /* only valid when not waiting all */
731 __u32 pad;
732};
733
734struct drm_syncobj_array {
735 __u64 handles;
736 __u32 count_handles;
737 __u32 pad;
738};
739
721#if defined(__cplusplus) 740#if defined(__cplusplus)
722} 741}
723#endif 742#endif
@@ -840,6 +859,9 @@ extern "C" {
840#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) 859#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
841#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) 860#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
842#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) 861#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
862#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
863#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
864#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
843 865
844/** 866/**
845 * Device specific ioctls should only be in their respective headers 867 * Device specific ioctls should only be in their respective headers
diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h
index 7ccbd6a2bbe0..6598fb76d2c2 100644
--- a/tools/include/uapi/drm/i915_drm.h
+++ b/tools/include/uapi/drm/i915_drm.h
@@ -260,6 +260,8 @@ typedef struct _drm_i915_sarea {
260#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 260#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
261#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 261#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
262#define DRM_I915_PERF_OPEN 0x36 262#define DRM_I915_PERF_OPEN 0x36
263#define DRM_I915_PERF_ADD_CONFIG 0x37
264#define DRM_I915_PERF_REMOVE_CONFIG 0x38
263 265
264#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 266#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
265#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) 267#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -315,6 +317,8 @@ typedef struct _drm_i915_sarea {
315#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) 317#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
316#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) 318#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
317#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) 319#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
320#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
321#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
318 322
319/* Allow drivers to submit batchbuffers directly to hardware, relying 323/* Allow drivers to submit batchbuffers directly to hardware, relying
320 * on the security mechanisms provided by hardware. 324 * on the security mechanisms provided by hardware.
@@ -431,6 +435,11 @@ typedef struct drm_i915_irq_wait {
431 */ 435 */
432#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 436#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
433 437
438/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
439 * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY.
440 */
441#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
442
434typedef struct drm_i915_getparam { 443typedef struct drm_i915_getparam {
435 __s32 param; 444 __s32 param;
436 /* 445 /*
@@ -812,6 +821,17 @@ struct drm_i915_gem_exec_object2 {
812 __u64 rsvd2; 821 __u64 rsvd2;
813}; 822};
814 823
824struct drm_i915_gem_exec_fence {
825 /**
826 * User's handle for a drm_syncobj to wait on or signal.
827 */
828 __u32 handle;
829
830#define I915_EXEC_FENCE_WAIT (1<<0)
831#define I915_EXEC_FENCE_SIGNAL (1<<1)
832 __u32 flags;
833};
834
815struct drm_i915_gem_execbuffer2 { 835struct drm_i915_gem_execbuffer2 {
816 /** 836 /**
817 * List of gem_exec_object2 structs 837 * List of gem_exec_object2 structs
@@ -826,7 +846,11 @@ struct drm_i915_gem_execbuffer2 {
826 __u32 DR1; 846 __u32 DR1;
827 __u32 DR4; 847 __u32 DR4;
828 __u32 num_cliprects; 848 __u32 num_cliprects;
829 /** This is a struct drm_clip_rect *cliprects */ 849 /**
850 * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
851 * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
852 * struct drm_i915_gem_exec_fence *fences.
853 */
830 __u64 cliprects_ptr; 854 __u64 cliprects_ptr;
831#define I915_EXEC_RING_MASK (7<<0) 855#define I915_EXEC_RING_MASK (7<<0)
832#define I915_EXEC_DEFAULT (0<<0) 856#define I915_EXEC_DEFAULT (0<<0)
@@ -927,7 +951,14 @@ struct drm_i915_gem_execbuffer2 {
927 * element). 951 * element).
928 */ 952 */
929#define I915_EXEC_BATCH_FIRST (1<<18) 953#define I915_EXEC_BATCH_FIRST (1<<18)
930#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_BATCH_FIRST<<1)) 954
955/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr
956 * define an array of i915_gem_exec_fence structures which specify a set of
957 * dma fences to wait upon or signal.
958 */
959#define I915_EXEC_FENCE_ARRAY (1<<19)
960
961#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1))
931 962
932#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) 963#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
933#define i915_execbuffer2_set_context_id(eb2, context) \ 964#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1467,6 +1498,22 @@ enum drm_i915_perf_record_type {
1467 DRM_I915_PERF_RECORD_MAX /* non-ABI */ 1498 DRM_I915_PERF_RECORD_MAX /* non-ABI */
1468}; 1499};
1469 1500
1501/**
1502 * Structure to upload perf dynamic configuration into the kernel.
1503 */
1504struct drm_i915_perf_oa_config {
1505 /** String formatted like "%08x-%04x-%04x-%04x-%012x" */
1506 char uuid[36];
1507
1508 __u32 n_mux_regs;
1509 __u32 n_boolean_regs;
1510 __u32 n_flex_regs;
1511
1512 __u64 __user mux_regs_ptr;
1513 __u64 __user boolean_regs_ptr;
1514 __u64 __user flex_regs_ptr;
1515};
1516
1470#if defined(__cplusplus) 1517#if defined(__cplusplus)
1471} 1518}
1472#endif 1519#endif
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 461811e57140..43ab5c402f98 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -143,12 +143,6 @@ enum bpf_attach_type {
143 143
144#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE 144#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
145 145
146enum bpf_sockmap_flags {
147 BPF_SOCKMAP_UNSPEC,
148 BPF_SOCKMAP_STRPARSER,
149 __MAX_BPF_SOCKMAP_FLAG
150};
151
152/* If BPF_F_ALLOW_OVERRIDE flag is used in BPF_PROG_ATTACH command 146/* If BPF_F_ALLOW_OVERRIDE flag is used in BPF_PROG_ATTACH command
153 * to the given target_fd cgroup the descendent cgroup will be able to 147 * to the given target_fd cgroup the descendent cgroup will be able to
154 * override effective bpf program that was inherited from this cgroup 148 * override effective bpf program that was inherited from this cgroup
@@ -368,9 +362,20 @@ union bpf_attr {
368 * int bpf_redirect(ifindex, flags) 362 * int bpf_redirect(ifindex, flags)
369 * redirect to another netdev 363 * redirect to another netdev
370 * @ifindex: ifindex of the net device 364 * @ifindex: ifindex of the net device
371 * @flags: bit 0 - if set, redirect to ingress instead of egress 365 * @flags:
372 * other bits - reserved 366 * cls_bpf:
373 * Return: TC_ACT_REDIRECT 367 * bit 0 - if set, redirect to ingress instead of egress
368 * other bits - reserved
369 * xdp_bpf:
370 * all bits - reserved
371 * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error
372 * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error
373 * int bpf_redirect_map(map, key, flags)
374 * redirect to endpoint in map
375 * @map: pointer to dev map
376 * @key: index in map to lookup
377 * @flags: --
378 * Return: XDP_REDIRECT on success or XDP_ABORT on error
374 * 379 *
375 * u32 bpf_get_route_realm(skb) 380 * u32 bpf_get_route_realm(skb)
376 * retrieve a dst's tclassid 381 * retrieve a dst's tclassid
@@ -632,7 +637,7 @@ union bpf_attr {
632 FN(skb_adjust_room), \ 637 FN(skb_adjust_room), \
633 FN(redirect_map), \ 638 FN(redirect_map), \
634 FN(sk_redirect_map), \ 639 FN(sk_redirect_map), \
635 FN(sock_map_update), 640 FN(sock_map_update), \
636 641
637/* integer value in 'imm' field of BPF_CALL instruction selects which helper 642/* integer value in 'imm' field of BPF_CALL instruction selects which helper
638 * function eBPF program intends to call 643 * function eBPF program intends to call
@@ -753,20 +758,23 @@ struct bpf_sock {
753 __u32 family; 758 __u32 family;
754 __u32 type; 759 __u32 type;
755 __u32 protocol; 760 __u32 protocol;
761 __u32 mark;
762 __u32 priority;
756}; 763};
757 764
758#define XDP_PACKET_HEADROOM 256 765#define XDP_PACKET_HEADROOM 256
759 766
760/* User return codes for XDP prog type. 767/* User return codes for XDP prog type.
761 * A valid XDP program must return one of these defined values. All other 768 * A valid XDP program must return one of these defined values. All other
762 * return codes are reserved for future use. Unknown return codes will result 769 * return codes are reserved for future use. Unknown return codes will
763 * in packet drop. 770 * result in packet drops and a warning via bpf_warn_invalid_xdp_action().
764 */ 771 */
765enum xdp_action { 772enum xdp_action {
766 XDP_ABORTED = 0, 773 XDP_ABORTED = 0,
767 XDP_DROP, 774 XDP_DROP,
768 XDP_PASS, 775 XDP_PASS,
769 XDP_TX, 776 XDP_TX,
777 XDP_REDIRECT,
770}; 778};
771 779
772/* user accessible metadata for XDP packet hook 780/* user accessible metadata for XDP packet hook
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 6cd63c18708a..838887587411 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -711,7 +711,8 @@ struct kvm_ppc_one_seg_page_size {
711struct kvm_ppc_smmu_info { 711struct kvm_ppc_smmu_info {
712 __u64 flags; 712 __u64 flags;
713 __u32 slb_size; 713 __u32 slb_size;
714 __u32 pad; 714 __u16 data_keys; /* # storage keys supported for data */
715 __u16 instr_keys; /* # storage keys supported for instructions */
715 struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; 716 struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
716}; 717};
717 718
diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h
index 81d8edf11789..a937480d7cd3 100644
--- a/tools/include/uapi/linux/mman.h
+++ b/tools/include/uapi/linux/mman.h
@@ -1,7 +1,8 @@
1#ifndef _UAPI_LINUX_MMAN_H 1#ifndef _UAPI_LINUX_MMAN_H
2#define _UAPI_LINUX_MMAN_H 2#define _UAPI_LINUX_MMAN_H
3 3
4#include <uapi/asm/mman.h> 4#include <asm/mman.h>
5#include <asm-generic/hugetlb_encode.h>
5 6
6#define MREMAP_MAYMOVE 1 7#define MREMAP_MAYMOVE 1
7#define MREMAP_FIXED 2 8#define MREMAP_FIXED 2
@@ -10,4 +11,25 @@
10#define OVERCOMMIT_ALWAYS 1 11#define OVERCOMMIT_ALWAYS 1
11#define OVERCOMMIT_NEVER 2 12#define OVERCOMMIT_NEVER 2
12 13
14/*
15 * Huge page size encoding when MAP_HUGETLB is specified, and a huge page
16 * size other than the default is desired. See hugetlb_encode.h.
17 * All known huge page size encodings are provided here. It is the
18 * responsibility of the application to know which sizes are supported on
19 * the running system. See mmap(2) man page for details.
20 */
21#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
22#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
23
24#define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
25#define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
26#define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
27#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
28#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
29#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
30#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
31#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
32#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
33#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
34
13#endif /* _UAPI_LINUX_MMAN_H */ 35#endif /* _UAPI_LINUX_MMAN_H */
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index d864ea6fd367..4353262bc462 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -240,6 +240,9 @@ Default is to monitor all CPUS.
240--force:: 240--force::
241 Don't do ownership validation. 241 Don't do ownership validation.
242 242
243--num-thread-synthesize::
244 The number of threads to run when synthesizing events for existing processes.
245 By default, the number of threads equals to the number of online CPUs.
243 246
244INTERACTIVE PROMPTING KEYS 247INTERACTIVE PROMPTING KEYS
245-------------------------- 248--------------------------
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index bd518b623d7a..5bd7b9260cc0 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -1,5 +1,4 @@
1libperf-y += header.o 1libperf-y += header.o
2libperf-y += sym-handling.o
3libperf-y += kvm-stat.o 2libperf-y += kvm-stat.o
4 3
5libperf-$(CONFIG_DWARF) += dwarf-regs.o 4libperf-$(CONFIG_DWARF) += dwarf-regs.o
diff --git a/tools/perf/arch/s390/util/sym-handling.c b/tools/perf/arch/s390/util/sym-handling.c
deleted file mode 100644
index e103f6e46afe..000000000000
--- a/tools/perf/arch/s390/util/sym-handling.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Architecture specific ELF symbol handling and relocation mapping.
3 *
4 * Copyright 2017 IBM Corp.
5 * Author(s): Thomas Richter <tmricht@linux.vnet.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License (version 2 only)
9 * as published by the Free Software Foundation.
10 */
11
12#include "symbol.h"
13
14#ifdef HAVE_LIBELF_SUPPORT
15bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
16{
17 if (ehdr.e_type == ET_EXEC)
18 return false;
19 return ehdr.e_type == ET_REL || ehdr.e_type == ET_DYN;
20}
21
22void arch__adjust_sym_map_offset(GElf_Sym *sym,
23 GElf_Shdr *shdr __maybe_unused,
24 struct map *map)
25{
26 if (map->type == MAP__FUNCTION)
27 sym->st_value += map->start;
28}
29#endif
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index c747a1af49fe..721f4f91291a 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1441,7 +1441,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1441 perf_session__set_id_hdr_size(kvm->session); 1441 perf_session__set_id_hdr_size(kvm->session);
1442 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); 1442 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true);
1443 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1443 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target,
1444 kvm->evlist->threads, false, kvm->opts.proc_map_timeout); 1444 kvm->evlist->threads, false,
1445 kvm->opts.proc_map_timeout, 1);
1445 err = kvm_live_open_events(kvm); 1446 err = kvm_live_open_events(kvm);
1446 if (err) 1447 if (err)
1447 goto out; 1448 goto out;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 9b379f3a3d99..234fdf4734f6 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -863,7 +863,7 @@ static int record__synthesize(struct record *rec, bool tail)
863 863
864 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, 864 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
865 process_synthesized_event, opts->sample_address, 865 process_synthesized_event, opts->sample_address,
866 opts->proc_map_timeout); 866 opts->proc_map_timeout, 1);
867out: 867out:
868 return err; 868 return err;
869} 869}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ee954bde7e3e..477a8699f0b5 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -958,8 +958,16 @@ static int __cmd_top(struct perf_top *top)
958 if (perf_session__register_idle_thread(top->session) < 0) 958 if (perf_session__register_idle_thread(top->session) < 0)
959 goto out_delete; 959 goto out_delete;
960 960
961 if (top->nr_threads_synthesize > 1)
962 perf_set_multithreaded();
963
961 machine__synthesize_threads(&top->session->machines.host, &opts->target, 964 machine__synthesize_threads(&top->session->machines.host, &opts->target,
962 top->evlist->threads, false, opts->proc_map_timeout); 965 top->evlist->threads, false,
966 opts->proc_map_timeout,
967 top->nr_threads_synthesize);
968
969 if (top->nr_threads_synthesize > 1)
970 perf_set_singlethreaded();
963 971
964 if (perf_hpp_list.socket) { 972 if (perf_hpp_list.socket) {
965 ret = perf_env__read_cpu_topology_map(&perf_env); 973 ret = perf_env__read_cpu_topology_map(&perf_env);
@@ -1112,6 +1120,7 @@ int cmd_top(int argc, const char **argv)
1112 }, 1120 },
1113 .max_stack = sysctl_perf_event_max_stack, 1121 .max_stack = sysctl_perf_event_max_stack,
1114 .sym_pcnt_filter = 5, 1122 .sym_pcnt_filter = 5,
1123 .nr_threads_synthesize = UINT_MAX,
1115 }; 1124 };
1116 struct record_opts *opts = &top.record_opts; 1125 struct record_opts *opts = &top.record_opts;
1117 struct target *target = &opts->target; 1126 struct target *target = &opts->target;
@@ -1221,6 +1230,8 @@ int cmd_top(int argc, const char **argv)
1221 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, 1230 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
1222 "Show entries in a hierarchy"), 1231 "Show entries in a hierarchy"),
1223 OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"), 1232 OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"),
1233 OPT_UINTEGER(0, "num-thread-synthesize", &top.nr_threads_synthesize,
1234 "number of thread to run event synthesize"),
1224 OPT_END() 1235 OPT_END()
1225 }; 1236 };
1226 const char * const top_usage[] = { 1237 const char * const top_usage[] = {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 967bd351b58d..afef6fe46c45 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1131,7 +1131,7 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1131 1131
1132 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target, 1132 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
1133 evlist->threads, trace__tool_process, false, 1133 evlist->threads, trace__tool_process, false,
1134 trace->opts.proc_map_timeout); 1134 trace->opts.proc_map_timeout, 1);
1135 if (err) 1135 if (err)
1136 symbol__exit(); 1136 symbol__exit();
1137 1137
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index c9aafed7da15..25ede4472465 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -166,7 +166,7 @@ static int run_dir(const char *d, const char *perf)
166 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s", 166 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s",
167 d, d, perf, vcnt, v); 167 d, d, perf, vcnt, v);
168 168
169 return system(cmd); 169 return system(cmd) ? TEST_FAIL : TEST_OK;
170} 170}
171 171
172int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) 172int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused)
diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py
index 6bb50e82a3e3..a13cd780148e 100644
--- a/tools/perf/tests/attr.py
+++ b/tools/perf/tests/attr.py
@@ -237,6 +237,7 @@ class Test(object):
237 # events in result. Fail if there's not any. 237 # events in result. Fail if there's not any.
238 for exp_name, exp_event in expect.items(): 238 for exp_name, exp_event in expect.items():
239 exp_list = [] 239 exp_list = []
240 res_event = {}
240 log.debug(" matching [%s]" % exp_name) 241 log.debug(" matching [%s]" % exp_name)
241 for res_name, res_event in result.items(): 242 for res_name, res_event in result.items():
242 log.debug(" to [%s]" % res_name) 243 log.debug(" to [%s]" % res_name)
@@ -253,7 +254,10 @@ class Test(object):
253 if exp_event.optional(): 254 if exp_event.optional():
254 log.debug(" %s does not match, but is optional" % exp_name) 255 log.debug(" %s does not match, but is optional" % exp_name)
255 else: 256 else:
256 exp_event.diff(res_event) 257 if not res_event:
258 log.debug(" res_event is empty");
259 else:
260 exp_event.diff(res_event)
257 raise Fail(self, 'match failure'); 261 raise Fail(self, 'match failure');
258 262
259 match[exp_name] = exp_list 263 match[exp_name] = exp_list
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
index 31e0b1da830b..37940665f736 100644
--- a/tools/perf/tests/attr/base-record
+++ b/tools/perf/tests/attr/base-record
@@ -23,7 +23,7 @@ comm=1
23freq=1 23freq=1
24inherit_stat=0 24inherit_stat=0
25enable_on_exec=1 25enable_on_exec=1
26task=0 26task=1
27watermark=0 27watermark=0
28precise_ip=0|1|2|3 28precise_ip=0|1|2|3
29mmap_data=0 29mmap_data=0
diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group
index 6e7961f6f7a5..618ba1c17474 100644
--- a/tools/perf/tests/attr/test-record-group
+++ b/tools/perf/tests/attr/test-record-group
@@ -17,5 +17,6 @@ sample_type=327
17read_format=4 17read_format=4
18mmap=0 18mmap=0
19comm=0 19comm=0
20task=0
20enable_on_exec=0 21enable_on_exec=0
21disabled=0 22disabled=0
diff --git a/tools/perf/tests/attr/test-record-group-sampling b/tools/perf/tests/attr/test-record-group-sampling
index ef59afd6d635..f906b793196f 100644
--- a/tools/perf/tests/attr/test-record-group-sampling
+++ b/tools/perf/tests/attr/test-record-group-sampling
@@ -23,7 +23,7 @@ sample_type=343
23 23
24# PERF_FORMAT_ID | PERF_FORMAT_GROUP 24# PERF_FORMAT_ID | PERF_FORMAT_GROUP
25read_format=12 25read_format=12
26 26task=0
27mmap=0 27mmap=0
28comm=0 28comm=0
29enable_on_exec=0 29enable_on_exec=0
diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1
index 87a222d014d8..48e8bd12fe46 100644
--- a/tools/perf/tests/attr/test-record-group1
+++ b/tools/perf/tests/attr/test-record-group1
@@ -18,5 +18,6 @@ sample_type=327
18read_format=4 18read_format=4
19mmap=0 19mmap=0
20comm=0 20comm=0
21task=0
21enable_on_exec=0 22enable_on_exec=0
22disabled=0 23disabled=0
diff --git a/tools/perf/tests/attr/test-stat-group b/tools/perf/tests/attr/test-stat-group
index fdc1596a8862..e15d6946e9b3 100644
--- a/tools/perf/tests/attr/test-stat-group
+++ b/tools/perf/tests/attr/test-stat-group
@@ -6,6 +6,7 @@ ret = 1
6[event-1:base-stat] 6[event-1:base-stat]
7fd=1 7fd=1
8group_fd=-1 8group_fd=-1
9read_format=3|15
9 10
10[event-2:base-stat] 11[event-2:base-stat]
11fd=2 12fd=2
@@ -13,3 +14,4 @@ group_fd=1
13config=1 14config=1
14disabled=0 15disabled=0
15enable_on_exec=0 16enable_on_exec=0
17read_format=3|15
diff --git a/tools/perf/tests/attr/test-stat-group1 b/tools/perf/tests/attr/test-stat-group1
index 2a1f86e4a904..1746751123dc 100644
--- a/tools/perf/tests/attr/test-stat-group1
+++ b/tools/perf/tests/attr/test-stat-group1
@@ -6,6 +6,7 @@ ret = 1
6[event-1:base-stat] 6[event-1:base-stat]
7fd=1 7fd=1
8group_fd=-1 8group_fd=-1
9read_format=3|15
9 10
10[event-2:base-stat] 11[event-2:base-stat]
11fd=2 12fd=2
@@ -13,3 +14,4 @@ group_fd=1
13config=1 14config=1
14disabled=0 15disabled=0
15enable_on_exec=0 16enable_on_exec=0
17read_format=3|15
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index f94a4196e7c9..2a0068afe3bf 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -131,7 +131,7 @@ static int synth_all(struct machine *machine)
131{ 131{
132 return perf_event__synthesize_threads(NULL, 132 return perf_event__synthesize_threads(NULL,
133 perf_event__process, 133 perf_event__process,
134 machine, 0, 500); 134 machine, 0, 500, 1);
135} 135}
136 136
137static int synth_process(struct machine *machine) 137static int synth_process(struct machine *machine)
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 510b513e0f01..be09d77cade0 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -65,8 +65,6 @@ static int parse_callchain_mode(const char *value)
65 callchain_param.mode = CHAIN_FOLDED; 65 callchain_param.mode = CHAIN_FOLDED;
66 return 0; 66 return 0;
67 } 67 }
68
69 pr_err("Invalid callchain mode: %s\n", value);
70 return -1; 68 return -1;
71} 69}
72 70
@@ -82,8 +80,6 @@ static int parse_callchain_order(const char *value)
82 callchain_param.order_set = true; 80 callchain_param.order_set = true;
83 return 0; 81 return 0;
84 } 82 }
85
86 pr_err("Invalid callchain order: %s\n", value);
87 return -1; 83 return -1;
88} 84}
89 85
@@ -105,8 +101,6 @@ static int parse_callchain_sort_key(const char *value)
105 callchain_param.branch_callstack = 1; 101 callchain_param.branch_callstack = 1;
106 return 0; 102 return 0;
107 } 103 }
108
109 pr_err("Invalid callchain sort key: %s\n", value);
110 return -1; 104 return -1;
111} 105}
112 106
@@ -124,8 +118,6 @@ static int parse_callchain_value(const char *value)
124 callchain_param.value = CCVAL_COUNT; 118 callchain_param.value = CCVAL_COUNT;
125 return 0; 119 return 0;
126 } 120 }
127
128 pr_err("Invalid callchain config key: %s\n", value);
129 return -1; 121 return -1;
130} 122}
131 123
@@ -319,12 +311,27 @@ int perf_callchain_config(const char *var, const char *value)
319 311
320 return ret; 312 return ret;
321 } 313 }
322 if (!strcmp(var, "print-type")) 314 if (!strcmp(var, "print-type")){
323 return parse_callchain_mode(value); 315 int ret;
324 if (!strcmp(var, "order")) 316 ret = parse_callchain_mode(value);
325 return parse_callchain_order(value); 317 if (ret == -1)
326 if (!strcmp(var, "sort-key")) 318 pr_err("Invalid callchain mode: %s\n", value);
327 return parse_callchain_sort_key(value); 319 return ret;
320 }
321 if (!strcmp(var, "order")){
322 int ret;
323 ret = parse_callchain_order(value);
324 if (ret == -1)
325 pr_err("Invalid callchain order: %s\n", value);
326 return ret;
327 }
328 if (!strcmp(var, "sort-key")){
329 int ret;
330 ret = parse_callchain_sort_key(value);
331 if (ret == -1)
332 pr_err("Invalid callchain sort key: %s\n", value);
333 return ret;
334 }
328 if (!strcmp(var, "threshold")) { 335 if (!strcmp(var, "threshold")) {
329 callchain_param.min_percent = strtod(value, &endptr); 336 callchain_param.min_percent = strtod(value, &endptr);
330 if (value == endptr) { 337 if (value == endptr) {
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index 7bc981b6bf29..756a9c14efbb 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -5,6 +5,7 @@
5#include <stdio.h> 5#include <stdio.h>
6#include <string.h> 6#include <string.h>
7#include <linux/refcount.h> 7#include <linux/refcount.h>
8#include "rwsem.h"
8 9
9struct comm_str { 10struct comm_str {
10 char *str; 11 char *str;
@@ -14,6 +15,7 @@ struct comm_str {
14 15
15/* Should perhaps be moved to struct machine */ 16/* Should perhaps be moved to struct machine */
16static struct rb_root comm_str_root; 17static struct rb_root comm_str_root;
18static struct rw_semaphore comm_str_lock = {.lock = PTHREAD_RWLOCK_INITIALIZER,};
17 19
18static struct comm_str *comm_str__get(struct comm_str *cs) 20static struct comm_str *comm_str__get(struct comm_str *cs)
19{ 21{
@@ -25,7 +27,9 @@ static struct comm_str *comm_str__get(struct comm_str *cs)
25static void comm_str__put(struct comm_str *cs) 27static void comm_str__put(struct comm_str *cs)
26{ 28{
27 if (cs && refcount_dec_and_test(&cs->refcnt)) { 29 if (cs && refcount_dec_and_test(&cs->refcnt)) {
30 down_write(&comm_str_lock);
28 rb_erase(&cs->rb_node, &comm_str_root); 31 rb_erase(&cs->rb_node, &comm_str_root);
32 up_write(&comm_str_lock);
29 zfree(&cs->str); 33 zfree(&cs->str);
30 free(cs); 34 free(cs);
31 } 35 }
@@ -50,7 +54,8 @@ static struct comm_str *comm_str__alloc(const char *str)
50 return cs; 54 return cs;
51} 55}
52 56
53static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) 57static
58struct comm_str *__comm_str__findnew(const char *str, struct rb_root *root)
54{ 59{
55 struct rb_node **p = &root->rb_node; 60 struct rb_node **p = &root->rb_node;
56 struct rb_node *parent = NULL; 61 struct rb_node *parent = NULL;
@@ -81,6 +86,17 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
81 return new; 86 return new;
82} 87}
83 88
89static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
90{
91 struct comm_str *cs;
92
93 down_write(&comm_str_lock);
94 cs = __comm_str__findnew(str, root);
95 up_write(&comm_str_lock);
96
97 return cs;
98}
99
84struct comm *comm__new(const char *str, u64 timestamp, bool exec) 100struct comm *comm__new(const char *str, u64 timestamp, bool exec)
85{ 101{
86 struct comm *comm = zalloc(sizeof(*comm)); 102 struct comm *comm = zalloc(sizeof(*comm));
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 10366b87d0b5..47eff4767edb 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -678,23 +678,21 @@ out:
678 return err; 678 return err;
679} 679}
680 680
681int perf_event__synthesize_threads(struct perf_tool *tool, 681static int __perf_event__synthesize_threads(struct perf_tool *tool,
682 perf_event__handler_t process, 682 perf_event__handler_t process,
683 struct machine *machine, 683 struct machine *machine,
684 bool mmap_data, 684 bool mmap_data,
685 unsigned int proc_map_timeout) 685 unsigned int proc_map_timeout,
686 struct dirent **dirent,
687 int start,
688 int num)
686{ 689{
687 union perf_event *comm_event, *mmap_event, *fork_event; 690 union perf_event *comm_event, *mmap_event, *fork_event;
688 union perf_event *namespaces_event; 691 union perf_event *namespaces_event;
689 char proc_path[PATH_MAX];
690 struct dirent **dirent;
691 int err = -1; 692 int err = -1;
692 char *end; 693 char *end;
693 pid_t pid; 694 pid_t pid;
694 int n, i; 695 int i;
695
696 if (machine__is_default_guest(machine))
697 return 0;
698 696
699 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 697 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
700 if (comm_event == NULL) 698 if (comm_event == NULL)
@@ -714,34 +712,25 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
714 if (namespaces_event == NULL) 712 if (namespaces_event == NULL)
715 goto out_free_fork; 713 goto out_free_fork;
716 714
717 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); 715 for (i = start; i < start + num; i++) {
718 n = scandir(proc_path, &dirent, 0, alphasort);
719
720 if (n < 0)
721 goto out_free_namespaces;
722
723 for (i = 0; i < n; i++) {
724 if (!isdigit(dirent[i]->d_name[0])) 716 if (!isdigit(dirent[i]->d_name[0]))
725 continue; 717 continue;
726 718
727 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10); 719 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10);
728 /* only interested in proper numerical dirents */ 720 /* only interested in proper numerical dirents */
729 if (!*end) { 721 if (*end)
730 /* 722 continue;
731 * We may race with exiting thread, so don't stop just because 723 /*
732 * one thread couldn't be synthesized. 724 * We may race with exiting thread, so don't stop just because
733 */ 725 * one thread couldn't be synthesized.
734 __event__synthesize_thread(comm_event, mmap_event, fork_event, 726 */
735 namespaces_event, pid, 1, process, 727 __event__synthesize_thread(comm_event, mmap_event, fork_event,
736 tool, machine, mmap_data, 728 namespaces_event, pid, 1, process,
737 proc_map_timeout); 729 tool, machine, mmap_data,
738 } 730 proc_map_timeout);
739 free(dirent[i]);
740 } 731 }
741 free(dirent);
742 err = 0; 732 err = 0;
743 733
744out_free_namespaces:
745 free(namespaces_event); 734 free(namespaces_event);
746out_free_fork: 735out_free_fork:
747 free(fork_event); 736 free(fork_event);
@@ -753,6 +742,118 @@ out:
753 return err; 742 return err;
754} 743}
755 744
745struct synthesize_threads_arg {
746 struct perf_tool *tool;
747 perf_event__handler_t process;
748 struct machine *machine;
749 bool mmap_data;
750 unsigned int proc_map_timeout;
751 struct dirent **dirent;
752 int num;
753 int start;
754};
755
756static void *synthesize_threads_worker(void *arg)
757{
758 struct synthesize_threads_arg *args = arg;
759
760 __perf_event__synthesize_threads(args->tool, args->process,
761 args->machine, args->mmap_data,
762 args->proc_map_timeout, args->dirent,
763 args->start, args->num);
764 return NULL;
765}
766
767int perf_event__synthesize_threads(struct perf_tool *tool,
768 perf_event__handler_t process,
769 struct machine *machine,
770 bool mmap_data,
771 unsigned int proc_map_timeout,
772 unsigned int nr_threads_synthesize)
773{
774 struct synthesize_threads_arg *args = NULL;
775 pthread_t *synthesize_threads = NULL;
776 char proc_path[PATH_MAX];
777 struct dirent **dirent;
778 int num_per_thread;
779 int m, n, i, j;
780 int thread_nr;
781 int base = 0;
782 int err = -1;
783
784
785 if (machine__is_default_guest(machine))
786 return 0;
787
788 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
789 n = scandir(proc_path, &dirent, 0, alphasort);
790 if (n < 0)
791 return err;
792
793 if (nr_threads_synthesize == UINT_MAX)
794 thread_nr = sysconf(_SC_NPROCESSORS_ONLN);
795 else
796 thread_nr = nr_threads_synthesize;
797
798 if (thread_nr <= 1) {
799 err = __perf_event__synthesize_threads(tool, process,
800 machine, mmap_data,
801 proc_map_timeout,
802 dirent, base, n);
803 goto free_dirent;
804 }
805 if (thread_nr > n)
806 thread_nr = n;
807
808 synthesize_threads = calloc(sizeof(pthread_t), thread_nr);
809 if (synthesize_threads == NULL)
810 goto free_dirent;
811
812 args = calloc(sizeof(*args), thread_nr);
813 if (args == NULL)
814 goto free_threads;
815
816 num_per_thread = n / thread_nr;
817 m = n % thread_nr;
818 for (i = 0; i < thread_nr; i++) {
819 args[i].tool = tool;
820 args[i].process = process;
821 args[i].machine = machine;
822 args[i].mmap_data = mmap_data;
823 args[i].proc_map_timeout = proc_map_timeout;
824 args[i].dirent = dirent;
825 }
826 for (i = 0; i < m; i++) {
827 args[i].num = num_per_thread + 1;
828 args[i].start = i * args[i].num;
829 }
830 if (i != 0)
831 base = args[i-1].start + args[i-1].num;
832 for (j = i; j < thread_nr; j++) {
833 args[j].num = num_per_thread;
834 args[j].start = base + (j - i) * args[i].num;
835 }
836
837 for (i = 0; i < thread_nr; i++) {
838 if (pthread_create(&synthesize_threads[i], NULL,
839 synthesize_threads_worker, &args[i]))
840 goto out_join;
841 }
842 err = 0;
843out_join:
844 for (i = 0; i < thread_nr; i++)
845 pthread_join(synthesize_threads[i], NULL);
846 free(args);
847free_threads:
848 free(synthesize_threads);
849free_dirent:
850 for (i = 0; i < n; i++)
851 free(dirent[i]);
852 free(dirent);
853
854 return err;
855}
856
756struct process_symbol_args { 857struct process_symbol_args {
757 const char *name; 858 const char *name;
758 u64 start; 859 u64 start;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index ee7bcc898d35..d6cbb0a0d919 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -680,7 +680,8 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool,
680int perf_event__synthesize_threads(struct perf_tool *tool, 680int perf_event__synthesize_threads(struct perf_tool *tool,
681 perf_event__handler_t process, 681 perf_event__handler_t process,
682 struct machine *machine, bool mmap_data, 682 struct machine *machine, bool mmap_data,
683 unsigned int proc_map_timeout); 683 unsigned int proc_map_timeout,
684 unsigned int nr_threads_synthesize);
684int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 685int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
685 perf_event__handler_t process, 686 perf_event__handler_t process,
686 struct machine *machine); 687 struct machine *machine);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7389746c0dc4..f894893c203d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -271,12 +271,17 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
271 return evsel; 271 return evsel;
272} 272}
273 273
274static bool perf_event_can_profile_kernel(void)
275{
276 return geteuid() == 0 || perf_event_paranoid() == -1;
277}
278
274struct perf_evsel *perf_evsel__new_cycles(bool precise) 279struct perf_evsel *perf_evsel__new_cycles(bool precise)
275{ 280{
276 struct perf_event_attr attr = { 281 struct perf_event_attr attr = {
277 .type = PERF_TYPE_HARDWARE, 282 .type = PERF_TYPE_HARDWARE,
278 .config = PERF_COUNT_HW_CPU_CYCLES, 283 .config = PERF_COUNT_HW_CPU_CYCLES,
279 .exclude_kernel = geteuid() != 0, 284 .exclude_kernel = !perf_event_can_profile_kernel(),
280 }; 285 };
281 struct perf_evsel *evsel; 286 struct perf_evsel *evsel;
282 287
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 585b4a3d64a4..7c3aa479201a 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2218,12 +2218,16 @@ int machines__for_each_thread(struct machines *machines,
2218int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 2218int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
2219 struct target *target, struct thread_map *threads, 2219 struct target *target, struct thread_map *threads,
2220 perf_event__handler_t process, bool data_mmap, 2220 perf_event__handler_t process, bool data_mmap,
2221 unsigned int proc_map_timeout) 2221 unsigned int proc_map_timeout,
2222 unsigned int nr_threads_synthesize)
2222{ 2223{
2223 if (target__has_task(target)) 2224 if (target__has_task(target))
2224 return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap, proc_map_timeout); 2225 return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap, proc_map_timeout);
2225 else if (target__has_cpu(target)) 2226 else if (target__has_cpu(target))
2226 return perf_event__synthesize_threads(tool, process, machine, data_mmap, proc_map_timeout); 2227 return perf_event__synthesize_threads(tool, process,
2228 machine, data_mmap,
2229 proc_map_timeout,
2230 nr_threads_synthesize);
2227 /* command specified */ 2231 /* command specified */
2228 return 0; 2232 return 0;
2229} 2233}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index b1cd516f2025..c6a299ea506c 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -257,15 +257,18 @@ int machines__for_each_thread(struct machines *machines,
257int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 257int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
258 struct target *target, struct thread_map *threads, 258 struct target *target, struct thread_map *threads,
259 perf_event__handler_t process, bool data_mmap, 259 perf_event__handler_t process, bool data_mmap,
260 unsigned int proc_map_timeout); 260 unsigned int proc_map_timeout,
261 unsigned int nr_threads_synthesize);
261static inline 262static inline
262int machine__synthesize_threads(struct machine *machine, struct target *target, 263int machine__synthesize_threads(struct machine *machine, struct target *target,
263 struct thread_map *threads, bool data_mmap, 264 struct thread_map *threads, bool data_mmap,
264 unsigned int proc_map_timeout) 265 unsigned int proc_map_timeout,
266 unsigned int nr_threads_synthesize)
265{ 267{
266 return __machine__synthesize_threads(machine, NULL, target, threads, 268 return __machine__synthesize_threads(machine, NULL, target, threads,
267 perf_event__process, data_mmap, 269 perf_event__process, data_mmap,
268 proc_map_timeout); 270 proc_map_timeout,
271 nr_threads_synthesize);
269} 272}
270 273
271pid_t machine__get_current_tid(struct machine *machine, int cpu); 274pid_t machine__get_current_tid(struct machine *machine, int cpu);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 5c39f420111e..9cf781f0d8a2 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -810,12 +810,6 @@ static u64 ref_reloc(struct kmap *kmap)
810void __weak arch__sym_update(struct symbol *s __maybe_unused, 810void __weak arch__sym_update(struct symbol *s __maybe_unused,
811 GElf_Sym *sym __maybe_unused) { } 811 GElf_Sym *sym __maybe_unused) { }
812 812
813void __weak arch__adjust_sym_map_offset(GElf_Sym *sym, GElf_Shdr *shdr,
814 struct map *map __maybe_unused)
815{
816 sym->st_value -= shdr->sh_addr - shdr->sh_offset;
817}
818
819int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, 813int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
820 struct symsrc *runtime_ss, int kmodule) 814 struct symsrc *runtime_ss, int kmodule)
821{ 815{
@@ -996,7 +990,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
996 990
997 /* Adjust symbol to map to file offset */ 991 /* Adjust symbol to map to file offset */
998 if (adjust_kernel_syms) 992 if (adjust_kernel_syms)
999 arch__adjust_sym_map_offset(&sym, &shdr, map); 993 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1000 994
1001 if (strcmp(section_name, 995 if (strcmp(section_name,
1002 (curr_dso->short_name + 996 (curr_dso->short_name +
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 2bd6a1f01a1c..aad99e7e179b 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -344,9 +344,6 @@ int setup_intlist(struct intlist **list, const char *list_str,
344#ifdef HAVE_LIBELF_SUPPORT 344#ifdef HAVE_LIBELF_SUPPORT
345bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); 345bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
346void arch__sym_update(struct symbol *s, GElf_Sym *sym); 346void arch__sym_update(struct symbol *s, GElf_Sym *sym);
347void arch__adjust_sym_map_offset(GElf_Sym *sym,
348 GElf_Shdr *shdr __maybe_unused,
349 struct map *map __maybe_unused);
350#endif 347#endif
351 348
352#define SYMBOL_A 0 349#define SYMBOL_A 0
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 19e5db90394c..6eea7cff3d4e 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -15,9 +15,9 @@
15 15
16#include "syscalltbl.h" 16#include "syscalltbl.h"
17#include <stdlib.h> 17#include <stdlib.h>
18#include <linux/compiler.h>
18 19
19#ifdef HAVE_SYSCALL_TABLE 20#ifdef HAVE_SYSCALL_TABLE
20#include <linux/compiler.h>
21#include <string.h> 21#include <string.h>
22#include "string2.h" 22#include "string2.h"
23#include "util.h" 23#include "util.h"
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index c09bdb509d82..bf73117b4822 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -45,6 +45,8 @@ struct thread *thread__new(pid_t pid, pid_t tid)
45 thread->cpu = -1; 45 thread->cpu = -1;
46 INIT_LIST_HEAD(&thread->namespaces_list); 46 INIT_LIST_HEAD(&thread->namespaces_list);
47 INIT_LIST_HEAD(&thread->comm_list); 47 INIT_LIST_HEAD(&thread->comm_list);
48 init_rwsem(&thread->namespaces_lock);
49 init_rwsem(&thread->comm_lock);
48 50
49 comm_str = malloc(32); 51 comm_str = malloc(32);
50 if (!comm_str) 52 if (!comm_str)
@@ -83,18 +85,26 @@ void thread__delete(struct thread *thread)
83 map_groups__put(thread->mg); 85 map_groups__put(thread->mg);
84 thread->mg = NULL; 86 thread->mg = NULL;
85 } 87 }
88 down_write(&thread->namespaces_lock);
86 list_for_each_entry_safe(namespaces, tmp_namespaces, 89 list_for_each_entry_safe(namespaces, tmp_namespaces,
87 &thread->namespaces_list, list) { 90 &thread->namespaces_list, list) {
88 list_del(&namespaces->list); 91 list_del(&namespaces->list);
89 namespaces__free(namespaces); 92 namespaces__free(namespaces);
90 } 93 }
94 up_write(&thread->namespaces_lock);
95
96 down_write(&thread->comm_lock);
91 list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { 97 list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) {
92 list_del(&comm->list); 98 list_del(&comm->list);
93 comm__free(comm); 99 comm__free(comm);
94 } 100 }
101 up_write(&thread->comm_lock);
102
95 unwind__finish_access(thread); 103 unwind__finish_access(thread);
96 nsinfo__zput(thread->nsinfo); 104 nsinfo__zput(thread->nsinfo);
97 105
106 exit_rwsem(&thread->namespaces_lock);
107 exit_rwsem(&thread->comm_lock);
98 free(thread); 108 free(thread);
99} 109}
100 110
@@ -125,8 +135,8 @@ struct namespaces *thread__namespaces(const struct thread *thread)
125 return list_first_entry(&thread->namespaces_list, struct namespaces, list); 135 return list_first_entry(&thread->namespaces_list, struct namespaces, list);
126} 136}
127 137
128int thread__set_namespaces(struct thread *thread, u64 timestamp, 138static int __thread__set_namespaces(struct thread *thread, u64 timestamp,
129 struct namespaces_event *event) 139 struct namespaces_event *event)
130{ 140{
131 struct namespaces *new, *curr = thread__namespaces(thread); 141 struct namespaces *new, *curr = thread__namespaces(thread);
132 142
@@ -149,6 +159,17 @@ int thread__set_namespaces(struct thread *thread, u64 timestamp,
149 return 0; 159 return 0;
150} 160}
151 161
162int thread__set_namespaces(struct thread *thread, u64 timestamp,
163 struct namespaces_event *event)
164{
165 int ret;
166
167 down_write(&thread->namespaces_lock);
168 ret = __thread__set_namespaces(thread, timestamp, event);
169 up_write(&thread->namespaces_lock);
170 return ret;
171}
172
152struct comm *thread__comm(const struct thread *thread) 173struct comm *thread__comm(const struct thread *thread)
153{ 174{
154 if (list_empty(&thread->comm_list)) 175 if (list_empty(&thread->comm_list))
@@ -170,8 +191,8 @@ struct comm *thread__exec_comm(const struct thread *thread)
170 return last; 191 return last;
171} 192}
172 193
173int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, 194static int ____thread__set_comm(struct thread *thread, const char *str,
174 bool exec) 195 u64 timestamp, bool exec)
175{ 196{
176 struct comm *new, *curr = thread__comm(thread); 197 struct comm *new, *curr = thread__comm(thread);
177 198
@@ -195,6 +216,17 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
195 return 0; 216 return 0;
196} 217}
197 218
219int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
220 bool exec)
221{
222 int ret;
223
224 down_write(&thread->comm_lock);
225 ret = ____thread__set_comm(thread, str, timestamp, exec);
226 up_write(&thread->comm_lock);
227 return ret;
228}
229
198int thread__set_comm_from_proc(struct thread *thread) 230int thread__set_comm_from_proc(struct thread *thread)
199{ 231{
200 char path[64]; 232 char path[64];
@@ -212,7 +244,7 @@ int thread__set_comm_from_proc(struct thread *thread)
212 return err; 244 return err;
213} 245}
214 246
215const char *thread__comm_str(const struct thread *thread) 247static const char *__thread__comm_str(const struct thread *thread)
216{ 248{
217 const struct comm *comm = thread__comm(thread); 249 const struct comm *comm = thread__comm(thread);
218 250
@@ -222,6 +254,17 @@ const char *thread__comm_str(const struct thread *thread)
222 return comm__str(comm); 254 return comm__str(comm);
223} 255}
224 256
257const char *thread__comm_str(const struct thread *thread)
258{
259 const char *str;
260
261 down_read((struct rw_semaphore *)&thread->comm_lock);
262 str = __thread__comm_str(thread);
263 up_read((struct rw_semaphore *)&thread->comm_lock);
264
265 return str;
266}
267
225/* CHECKME: it should probably better return the max comm len from its comm list */ 268/* CHECKME: it should probably better return the max comm len from its comm list */
226int thread__comm_len(struct thread *thread) 269int thread__comm_len(struct thread *thread)
227{ 270{
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index cb1a5dd5c2b9..10555d6a0b86 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -9,6 +9,7 @@
9#include "symbol.h" 9#include "symbol.h"
10#include <strlist.h> 10#include <strlist.h>
11#include <intlist.h> 11#include <intlist.h>
12#include "rwsem.h"
12 13
13struct thread_stack; 14struct thread_stack;
14struct unwind_libunwind_ops; 15struct unwind_libunwind_ops;
@@ -29,7 +30,9 @@ struct thread {
29 int comm_len; 30 int comm_len;
30 bool dead; /* if set thread has exited */ 31 bool dead; /* if set thread has exited */
31 struct list_head namespaces_list; 32 struct list_head namespaces_list;
33 struct rw_semaphore namespaces_lock;
32 struct list_head comm_list; 34 struct list_head comm_list;
35 struct rw_semaphore comm_lock;
33 u64 db_id; 36 u64 db_id;
34 37
35 void *priv; 38 void *priv;
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 9bdfb78a9a35..f4296e1e3bb8 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -37,6 +37,7 @@ struct perf_top {
37 int sym_pcnt_filter; 37 int sym_pcnt_filter;
38 const char *sym_filter; 38 const char *sym_filter;
39 float min_percent; 39 float min_percent;
40 unsigned int nr_threads_synthesize;
40}; 41};
41 42
42#define CONSOLE_CLEAR "" 43#define CONSOLE_CLEAR ""