diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-10-03 12:30:24 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-10-03 12:30:24 -0400 |
commit | 4b50239a769e78bbe362fc92c3f8bd5415a4a5f5 (patch) | |
tree | 951832e213945ede19cd676a04e5218e68afd074 | |
parent | a47ba4d77e1236d214e5116b5631bc4c2d6e6369 (diff) | |
parent | f6a9820d572bd8384d982357cbad214b3a6c04bb (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>
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 | |||
93 | struct 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 | ||
701 | struct drm_syncobj_create { | 701 | struct 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) | ||
724 | struct 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 | |||
734 | struct 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 | |||
434 | typedef struct drm_i915_getparam { | 443 | typedef 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 | ||
824 | struct 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 | |||
815 | struct drm_i915_gem_execbuffer2 { | 835 | struct 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 | */ | ||
1504 | struct 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 | ||
146 | enum 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 | */ |
765 | enum xdp_action { | 772 | enum 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 { | |||
711 | struct kvm_ppc_smmu_info { | 711 | struct 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 | ||
244 | INTERACTIVE PROMPTING KEYS | 247 | INTERACTIVE 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 @@ | |||
1 | libperf-y += header.o | 1 | libperf-y += header.o |
2 | libperf-y += sym-handling.o | ||
3 | libperf-y += kvm-stat.o | 2 | libperf-y += kvm-stat.o |
4 | 3 | ||
5 | libperf-$(CONFIG_DWARF) += dwarf-regs.o | 4 | libperf-$(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 | ||
15 | bool 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 | |||
22 | void 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); |
867 | out: | 867 | out: |
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 | ||
172 | int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) | 172 | int 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 | |||
23 | freq=1 | 23 | freq=1 |
24 | inherit_stat=0 | 24 | inherit_stat=0 |
25 | enable_on_exec=1 | 25 | enable_on_exec=1 |
26 | task=0 | 26 | task=1 |
27 | watermark=0 | 27 | watermark=0 |
28 | precise_ip=0|1|2|3 | 28 | precise_ip=0|1|2|3 |
29 | mmap_data=0 | 29 | mmap_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 | |||
17 | read_format=4 | 17 | read_format=4 |
18 | mmap=0 | 18 | mmap=0 |
19 | comm=0 | 19 | comm=0 |
20 | task=0 | ||
20 | enable_on_exec=0 | 21 | enable_on_exec=0 |
21 | disabled=0 | 22 | disabled=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 |
25 | read_format=12 | 25 | read_format=12 |
26 | 26 | task=0 | |
27 | mmap=0 | 27 | mmap=0 |
28 | comm=0 | 28 | comm=0 |
29 | enable_on_exec=0 | 29 | enable_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 | |||
18 | read_format=4 | 18 | read_format=4 |
19 | mmap=0 | 19 | mmap=0 |
20 | comm=0 | 20 | comm=0 |
21 | task=0 | ||
21 | enable_on_exec=0 | 22 | enable_on_exec=0 |
22 | disabled=0 | 23 | disabled=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] |
7 | fd=1 | 7 | fd=1 |
8 | group_fd=-1 | 8 | group_fd=-1 |
9 | read_format=3|15 | ||
9 | 10 | ||
10 | [event-2:base-stat] | 11 | [event-2:base-stat] |
11 | fd=2 | 12 | fd=2 |
@@ -13,3 +14,4 @@ group_fd=1 | |||
13 | config=1 | 14 | config=1 |
14 | disabled=0 | 15 | disabled=0 |
15 | enable_on_exec=0 | 16 | enable_on_exec=0 |
17 | read_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] |
7 | fd=1 | 7 | fd=1 |
8 | group_fd=-1 | 8 | group_fd=-1 |
9 | read_format=3|15 | ||
9 | 10 | ||
10 | [event-2:base-stat] | 11 | [event-2:base-stat] |
11 | fd=2 | 12 | fd=2 |
@@ -13,3 +14,4 @@ group_fd=1 | |||
13 | config=1 | 14 | config=1 |
14 | disabled=0 | 15 | disabled=0 |
15 | enable_on_exec=0 | 16 | enable_on_exec=0 |
17 | read_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 | ||
137 | static int synth_process(struct machine *machine) | 137 | static 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 | ||
9 | struct comm_str { | 10 | struct 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 */ |
16 | static struct rb_root comm_str_root; | 17 | static struct rb_root comm_str_root; |
18 | static struct rw_semaphore comm_str_lock = {.lock = PTHREAD_RWLOCK_INITIALIZER,}; | ||
17 | 19 | ||
18 | static struct comm_str *comm_str__get(struct comm_str *cs) | 20 | static 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) | |||
25 | static void comm_str__put(struct comm_str *cs) | 27 | static 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 | ||
53 | static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) | 57 | static |
58 | struct 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 | ||
89 | static 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 | |||
84 | struct comm *comm__new(const char *str, u64 timestamp, bool exec) | 100 | struct 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 | ||
681 | int perf_event__synthesize_threads(struct perf_tool *tool, | 681 | static 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 | ||
744 | out_free_namespaces: | ||
745 | free(namespaces_event); | 734 | free(namespaces_event); |
746 | out_free_fork: | 735 | out_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 | ||
745 | struct 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 | |||
756 | static 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 | |||
767 | int 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; | ||
843 | out_join: | ||
844 | for (i = 0; i < thread_nr; i++) | ||
845 | pthread_join(synthesize_threads[i], NULL); | ||
846 | free(args); | ||
847 | free_threads: | ||
848 | free(synthesize_threads); | ||
849 | free_dirent: | ||
850 | for (i = 0; i < n; i++) | ||
851 | free(dirent[i]); | ||
852 | free(dirent); | ||
853 | |||
854 | return err; | ||
855 | } | ||
856 | |||
756 | struct process_symbol_args { | 857 | struct 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, | |||
680 | int perf_event__synthesize_threads(struct perf_tool *tool, | 680 | int 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); | ||
684 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, | 685 | int 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 | ||
274 | static bool perf_event_can_profile_kernel(void) | ||
275 | { | ||
276 | return geteuid() == 0 || perf_event_paranoid() == -1; | ||
277 | } | ||
278 | |||
274 | struct perf_evsel *perf_evsel__new_cycles(bool precise) | 279 | struct 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, | |||
2218 | int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, | 2218 | int __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, | |||
257 | int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, | 257 | int __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); | ||
261 | static inline | 262 | static inline |
262 | int machine__synthesize_threads(struct machine *machine, struct target *target, | 263 | int 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 | ||
271 | pid_t machine__get_current_tid(struct machine *machine, int cpu); | 274 | pid_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) | |||
810 | void __weak arch__sym_update(struct symbol *s __maybe_unused, | 810 | void __weak arch__sym_update(struct symbol *s __maybe_unused, |
811 | GElf_Sym *sym __maybe_unused) { } | 811 | GElf_Sym *sym __maybe_unused) { } |
812 | 812 | ||
813 | void __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 | |||
819 | int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, | 813 | int 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 |
345 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); | 345 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); |
346 | void arch__sym_update(struct symbol *s, GElf_Sym *sym); | 346 | void arch__sym_update(struct symbol *s, GElf_Sym *sym); |
347 | void 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 | ||
128 | int thread__set_namespaces(struct thread *thread, u64 timestamp, | 138 | static 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 | ||
162 | int 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 | |||
152 | struct comm *thread__comm(const struct thread *thread) | 173 | struct 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 | ||
173 | int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | 194 | static 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 | ||
219 | int __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 | |||
198 | int thread__set_comm_from_proc(struct thread *thread) | 230 | int 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 | ||
215 | const char *thread__comm_str(const struct thread *thread) | 247 | static 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 | ||
257 | const 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 */ |
226 | int thread__comm_len(struct thread *thread) | 269 | int 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 | ||
13 | struct thread_stack; | 14 | struct thread_stack; |
14 | struct unwind_libunwind_ops; | 15 | struct 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 "[H[2J" | 43 | #define CONSOLE_CLEAR "[H[2J" |