History

Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf updates from Ingo Molnar: "Kernel improvements: - watchdog driver improvements by Li Zefan - Power7 CPI stack events related improvements by Sukadev Bhattiprolu - event multiplexing via hrtimers and other improvements by Stephane Eranian - kernel stack use optimization by Andrew Hunter - AMD IOMMU uncore PMU support by Suravee Suthikulpanit - NMI handling rate-limits by Dave Hansen - various hw_breakpoint fixes by Oleg Nesterov - hw_breakpoint overflow period sampling and related signal handling fixes by Jiri Olsa - Intel Haswell PMU support by Andi Kleen Tooling improvements: - Reset SIGTERM handler in workload child process, fix from David Ahern. - Makefile reorganization, prep work for Kconfig patches, from Jiri Olsa. - Add automated make test suite, from Jiri Olsa. - Add --percent-limit option to 'top' and 'report', from Namhyung Kim. - Sorting improvements, from Namhyung Kim. - Expand definition of sysfs format attribute, from Michael Ellerman. Tooling fixes: - 'perf tests' fixes from Jiri Olsa. - Make Power7 CPI stack events available in sysfs, from Sukadev Bhattiprolu. - Handle death by SIGTERM in 'perf record', fix from David Ahern. - Fix printing of perf_event_paranoid message, from David Ahern. - Handle realloc failures in 'perf kvm', from David Ahern. - Fix divide by 0 in variance, from David Ahern. - Save parent pid in thread struct, from David Ahern. - Handle JITed code in shared memory, from Andi Kleen. - Fixes for 'perf diff', from Jiri Olsa. - Remove some unused struct members, from Jiri Olsa. - Add missing liblk.a dependency for python/perf.so, fix from Jiri Olsa. - Respect CROSS_COMPILE in liblk.a, from Rabin Vincent. - No need to do locking when adding hists in perf report, only 'top' needs that, from Namhyung Kim. - Fix alignment of symbol column in in the hists browser (top, report) when -v is given, from NAmhyung Kim. - Fix 'perf top' -E option behavior, from Namhyung Kim. - Fix bug in isupper() and islower(), from Sukadev Bhattiprolu. - Fix compile errors in bp_signal 'perf test', from Sukadev Bhattiprolu. ... and more things" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (102 commits) perf/x86: Disable PEBS-LL in intel_pmu_pebs_disable() perf/x86: Fix shared register mutual exclusion enforcement perf/x86/intel: Support full width counting x86: Add NMI duration tracepoints perf: Drop sample rate when sampling is too slow x86: Warn when NMI handlers take large amounts of time hw_breakpoint: Introduce "struct bp_cpuinfo" hw_breakpoint: Simplify *register_wide_hw_breakpoint() hw_breakpoint: Introduce cpumask_of_bp() hw_breakpoint: Simplify the "weight" usage in toggle_bp_slot() paths hw_breakpoint: Simplify list/idx mess in toggle_bp_slot() paths perf/x86/intel: Add mem-loads/stores support for Haswell perf/x86/intel: Support Haswell/v4 LBR format perf/x86/intel: Move NMI clearing to end of PMI handler perf/x86/intel: Add Haswell PEBS support perf/x86/intel: Add simple Haswell PMU support perf/x86/intel: Add Haswell PEBS record support perf/x86/intel: Fix sparse warning perf/x86/amd: AMD IOMMU Performance Counter PERF uncore PMU implementation perf/x86/amd: Add IOMMU Performance Counter resource management ...

Linus Torvalds committed 13 years ago

Commit f0bb4c02 parents a4883ef 983433b71 files · +2947 −1053Browse files

Unified · Split

71 files
  1. Documentation/ABI/testing/sysfs-bus-event_source-devices-events +27 −5
  2. Documentation/ABI/testing/sysfs-bus-event_source-devices-format +6 −0
  3. Documentation/sysctl/kernel.txt +40 −10
  4. Documentation/trace/events-nmi.txt +43 −0
  5. arch/metag/kernel/perf/perf_event.c +1 −1
  6. arch/powerpc/perf/power7-pmu.c +73 −0
  7. arch/x86/ia32/ia32_signal.c +0 −2
  8. arch/x86/include/asm/perf_event.h +3 −0
  9. arch/x86/include/asm/sighandling.h +2 −2
  10. arch/x86/include/uapi/asm/msr-index.h +3 −0
  11. arch/x86/kernel/cpu/Makefile +4 −0
  12. arch/x86/kernel/cpu/perf_event.c +53 −16
  13. arch/x86/kernel/cpu/perf_event.h +21 −3
  14. arch/x86/kernel/cpu/perf_event_amd.c +17 −17
  15. arch/x86/kernel/cpu/perf_event_amd_iommu.c +504 −0
  16. arch/x86/kernel/cpu/perf_event_amd_iommu.h +40 −0
  17. arch/x86/kernel/cpu/perf_event_intel.c +122 −14
  18. arch/x86/kernel/cpu/perf_event_intel_ds.c +153 −25
  19. arch/x86/kernel/cpu/perf_event_intel_lbr.c +54 −15
  20. arch/x86/kernel/cpu/perf_event_intel_uncore.c +9 −7
  21. arch/x86/kernel/cpu/perf_event_intel_uncore.h +2 −2
  22. arch/x86/kernel/nmi.c +34 −2
  23. arch/x86/kernel/signal.c +6 −10
  24. drivers/iommu/amd_iommu_init.c +131 −9
  25. drivers/iommu/amd_iommu_proto.h +7 −0
  26. drivers/iommu/amd_iommu_types.h +12 −3
  27. include/linux/perf_event.h +24 −4
  28. include/trace/events/nmi.h +37 −0
  29. include/uapi/linux/perf_event.h +4 −1
  30. init/main.c +1 −1
  31. kernel/events/core.c +257 −21
  32. kernel/events/hw_breakpoint.c +83 −108
  33. kernel/sysctl.c +10 −2
  34. tools/lib/lk/Makefile +3 −0
  35. tools/perf/Documentation/perf-archive.txt +1 −1
  36. tools/perf/Documentation/perf-report.txt +4 −0
  37. tools/perf/Documentation/perf-top.txt +4 −0
  38. tools/perf/Makefile +110 −520
  39. tools/perf/builtin-diff.c +12 −7
  40. tools/perf/builtin-kvm.c +3 −0
  41. tools/perf/builtin-record.c +1 −1
  42. tools/perf/builtin-report.c +54 −48
  43. tools/perf/builtin-top.c +39 −35
  44. tools/perf/config/Makefile +477 −0
  45. tools/perf/tests/attr/base-record +2 −2
  46. tools/perf/tests/attr/base-stat +2 −2
  47. tools/perf/tests/attr/test-record-data +4 −1
  48. tools/perf/tests/bp_signal.c +6 −0
  49. tools/perf/tests/bp_signal_overflow.c +6 −0
  50. tools/perf/tests/builtin-test.c +1 −1
  51. tools/perf/tests/make +138 −0
  52. tools/perf/ui/browsers/hists.c +85 −21
  53. tools/perf/ui/gtk/hists.c +10 −3
  54. tools/perf/ui/stdio/hist.c +6 −1
  55. tools/perf/util/evlist.c +2 −0
  56. tools/perf/util/evsel.c +1 −1
  57. tools/perf/util/header.c +0 −2
  58. tools/perf/util/header.h +0 −1
  59. tools/perf/util/hist.c +42 −54
  60. tools/perf/util/hist.h +8 −8
  61. tools/perf/util/map.c +1 −0
  62. tools/perf/util/session.h +0 −1
  63. tools/perf/util/setup.py +3 −2
  64. tools/perf/util/sort.c +91 −37
  65. tools/perf/util/sort.h +22 −14
  66. tools/perf/util/stat.c +1 −1
  67. tools/perf/util/thread.c +4 −0
  68. tools/perf/util/thread.h +1 −0
  69. tools/perf/util/top.c +17 −6
  70. tools/perf/util/top.h +1 −1
  71. tools/perf/util/util.h +2 −2
Documentation/ABI/testing/sysfs-bus-event_source-devices-events+27−5
@@ -27,14 +27,36 @@ Description: Generic performance monitoring events · 26 unmodified lines
2727 "basename".
2828
2929
30−What: /sys/devices/cpu/events/PM_LD_MISS_L1
31− /sys/devices/cpu/events/PM_LD_REF_L1
32− /sys/devices/cpu/events/PM_CYC
30+What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
3331 /sys/devices/cpu/events/PM_BRU_FIN
34− /sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
3532 /sys/devices/cpu/events/PM_BRU_MPRED
36− /sys/devices/cpu/events/PM_INST_CMPL
3733 /sys/devices/cpu/events/PM_CMPLU_STALL
34+ /sys/devices/cpu/events/PM_CMPLU_STALL_BRU
35+ /sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS
36+ /sys/devices/cpu/events/PM_CMPLU_STALL_DFU
37+ /sys/devices/cpu/events/PM_CMPLU_STALL_DIV
38+ /sys/devices/cpu/events/PM_CMPLU_STALL_ERAT_MISS
39+ /sys/devices/cpu/events/PM_CMPLU_STALL_FXU
40+ /sys/devices/cpu/events/PM_CMPLU_STALL_IFU
41+ /sys/devices/cpu/events/PM_CMPLU_STALL_LSU
42+ /sys/devices/cpu/events/PM_CMPLU_STALL_REJECT
43+ /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR
44+ /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR_LONG
45+ /sys/devices/cpu/events/PM_CMPLU_STALL_STORE
46+ /sys/devices/cpu/events/PM_CMPLU_STALL_THRD
47+ /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR
48+ /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR_LONG
49+ /sys/devices/cpu/events/PM_CYC
50+ /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED
51+ /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED_IC_MISS
52+ /sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
53+ /sys/devices/cpu/events/PM_GCT_NOSLOT_IC_MISS
54+ /sys/devices/cpu/events/PM_GRP_CMPL
55+ /sys/devices/cpu/events/PM_INST_CMPL
56+ /sys/devices/cpu/events/PM_LD_MISS_L1
57+ /sys/devices/cpu/events/PM_LD_REF_L1
58+ /sys/devices/cpu/events/PM_RUN_CYC
59+ /sys/devices/cpu/events/PM_RUN_INST_CMPL
3860
3961 Date: 2013/01/08
4062
Documentation/ABI/testing/sysfs-bus-event_source-devices-format+6−0
@@ -9,6 +9,12 @@ Description: · 8 unmodified lines
99 we want to export, so that userspace can deal with sane
1010 name/value pairs.
1111
12+ Userspace must be prepared for the possibility that attributes
13+ define overlapping bit ranges. For example:
14+ attr1 = 'config:0-23'
15+ attr2 = 'config:0-7'
16+ attr3 = 'config:12-35'
17+
1218 Example: 'config1:1,6-10,44'
1319 Defines contents of attribute that occupies bits 1,6-10,44 of
1420 perf_event_attr::config1.
Documentation/sysctl/kernel.txt+40−10
@@ -70,12 +70,12 @@ show up in /proc/sys/kernel: · 69 unmodified lines
7070 - shmall
7171 - shmmax [ sysv ipc ]
7272 - shmmni
73−- softlockup_thresh
7473 - stop-a [ SPARC only ]
7574 - sysrq ==> Documentation/sysrq.txt
7675 - tainted
7776 - threads-max
7877 - unknown_nmi_panic
78+- watchdog_thresh
7979 - version
8080
8181 ==============================================================
@@ -427,6 +427,32 @@ This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled. · 345 unmodified lines
427427
428428 ==============================================================
429429
430+perf_cpu_time_max_percent:
431+
432+Hints to the kernel how much CPU time it should be allowed to
433+use to handle perf sampling events. If the perf subsystem
434+is informed that its samples are exceeding this limit, it
435+will drop its sampling frequency to attempt to reduce its CPU
436+usage.
437+
438+Some perf sampling happens in NMIs. If these samples
439+unexpectedly take too long to execute, the NMIs can become
440+stacked up next to each other so much that nothing else is
441+allowed to execute.
442+
443+0: disable the mechanism. Do not monitor or correct perf's
444+ sampling rate no matter how CPU time it takes.
445+
446+1-100: attempt to throttle perf's sample rate to this
447+ percentage of CPU. Note: the kernel calculates an
448+ "expected" length of each sample event. 100 here means
449+ 100% of that expected length. Even if this is set to
450+ 100, you may still see sample throttling if this
451+ length is exceeded. Set to 0 if you truly do not care
452+ how much CPU is consumed.
453+
454+==============================================================
455+
430456
431457 pid_max:
432458
@@ -604,15 +630,6 @@ without users and with a dead originative process will be destroyed. · 171 unmodified lines
604630
605631 ==============================================================
606632
607−softlockup_thresh:
608−
609−This value can be used to lower the softlockup tolerance threshold. The
610−default threshold is 60 seconds. If a cpu is locked up for 60 seconds,
611−the kernel complains. Valid values are 1-60 seconds. Setting this
612−tunable to zero will disable the softlockup detection altogether.
613−
614−==============================================================
615−
616633 tainted:
617634
618635 Non-zero if the kernel has been tainted. Numeric values, which
@@ -648,3 +665,16 @@ that time, kernel debugging information is displayed on console. · 29 unmodified lines
648665
649666 NMI switch that most IA32 servers have fires unknown NMI up, for
650667 example. If a system hangs up, try pressing the NMI switch.
668+
669+==============================================================
670+
671+watchdog_thresh:
672+
673+This value can be used to control the frequency of hrtimer and NMI
674+events and the soft and hard lockup thresholds. The default threshold
675+is 10 seconds.
676+
677+The softlockup threshold is (2 * watchdog_thresh). Setting this
678+tunable to zero will disable lockup detection altogether.
679+
680+==============================================================
Documentation/trace/events-nmi.txt+43−0
@@ -0,0 +1,43 @@
1+NMI Trace Events
2+
3+These events normally show up here:
4+
5+ /sys/kernel/debug/tracing/events/nmi
6+
7+--
8+
9+nmi_handler:
10+
11+You might want to use this tracepoint if you suspect that your
12+NMI handlers are hogging large amounts of CPU time. The kernel
13+will warn if it sees long-running handlers:
14+
15+ INFO: NMI handler took too long to run: 9.207 msecs
16+
17+and this tracepoint will allow you to drill down and get some
18+more details.
19+
20+Let's say you suspect that perf_event_nmi_handler() is causing
21+you some problems and you only want to trace that handler
22+specifically. You need to find its address:
23+
24+ $ grep perf_event_nmi_handler /proc/kallsyms
25+ ffffffff81625600 t perf_event_nmi_handler
26+
27+Let's also say you are only interested in when that function is
28+really hogging a lot of CPU time, like a millisecond at a time.
29+Note that the kernel's output is in milliseconds, but the input
30+to the filter is in nanoseconds! You can filter on 'delta_ns':
31+
32+cd /sys/kernel/debug/tracing/events/nmi/nmi_handler
33+echo 'handler==0xffffffff81625600 && delta_ns>1000000' > filter
34+echo 1 > enable
35+
36+Your output would then look like:
37+
38+$ cat /sys/kernel/debug/tracing/trace_pipe
39+<idle>-0 [000] d.h3 505.397558: nmi_handler: perf_event_nmi_handler() delta_ns: 3236765 handled: 1
40+<idle>-0 [000] d.h3 505.805893: nmi_handler: perf_event_nmi_handler() delta_ns: 3174234 handled: 1
41+<idle>-0 [000] d.h3 506.158206: nmi_handler: perf_event_nmi_handler() delta_ns: 3084642 handled: 1
42+<idle>-0 [000] d.h3 506.334346: nmi_handler: perf_event_nmi_handler() delta_ns: 3080351 handled: 1
43+
arch/metag/kernel/perf/perf_event.c+1−1
@@ -882,7 +882,7 @@ static int __init init_hw_perf_events(void) · 881 unmodified lines
882882 }
883883
884884 register_cpu_notifier(&metag_pmu_notifier);
885− ret = perf_pmu_register(&pmu, (char *)metag_pmu->name, PERF_TYPE_RAW);
885+ ret = perf_pmu_register(&pmu, metag_pmu->name, PERF_TYPE_RAW);
886886 out:
887887 return ret;
888888 }
arch/powerpc/perf/power7-pmu.c+73−0
@@ -62,6 +62,29 @@ · 61 unmodified lines
6262 #define PME_PM_BRU_FIN 0x10068
6363 #define PME_PM_BRU_MPRED 0x400f6
6464
65+#define PME_PM_CMPLU_STALL_FXU 0x20014
66+#define PME_PM_CMPLU_STALL_DIV 0x40014
67+#define PME_PM_CMPLU_STALL_SCALAR 0x40012
68+#define PME_PM_CMPLU_STALL_SCALAR_LONG 0x20018
69+#define PME_PM_CMPLU_STALL_VECTOR 0x2001c
70+#define PME_PM_CMPLU_STALL_VECTOR_LONG 0x4004a
71+#define PME_PM_CMPLU_STALL_LSU 0x20012
72+#define PME_PM_CMPLU_STALL_REJECT 0x40016
73+#define PME_PM_CMPLU_STALL_ERAT_MISS 0x40018
74+#define PME_PM_CMPLU_STALL_DCACHE_MISS 0x20016
75+#define PME_PM_CMPLU_STALL_STORE 0x2004a
76+#define PME_PM_CMPLU_STALL_THRD 0x1001c
77+#define PME_PM_CMPLU_STALL_IFU 0x4004c
78+#define PME_PM_CMPLU_STALL_BRU 0x4004e
79+#define PME_PM_GCT_NOSLOT_IC_MISS 0x2001a
80+#define PME_PM_GCT_NOSLOT_BR_MPRED 0x4001a
81+#define PME_PM_GCT_NOSLOT_BR_MPRED_IC_MISS 0x4001c
82+#define PME_PM_GRP_CMPL 0x30004
83+#define PME_PM_1PLUS_PPC_CMPL 0x100f2
84+#define PME_PM_CMPLU_STALL_DFU 0x2003c
85+#define PME_PM_RUN_CYC 0x200f4
86+#define PME_PM_RUN_INST_CMPL 0x400fa
87+
6588 /*
6689 * Layout of constraint bits:
6790 * 6666555555555544444444443333333333222222222211111111110000000000
@@ -393,6 +416,31 @@ POWER_EVENT_ATTR(LD_MISS_L1, LD_MISS_L1); · 325 unmodified lines
393416 POWER_EVENT_ATTR(BRU_FIN, BRU_FIN)
394417 POWER_EVENT_ATTR(BRU_MPRED, BRU_MPRED);
395418
419+POWER_EVENT_ATTR(CMPLU_STALL_FXU, CMPLU_STALL_FXU);
420+POWER_EVENT_ATTR(CMPLU_STALL_DIV, CMPLU_STALL_DIV);
421+POWER_EVENT_ATTR(CMPLU_STALL_SCALAR, CMPLU_STALL_SCALAR);
422+POWER_EVENT_ATTR(CMPLU_STALL_SCALAR_LONG, CMPLU_STALL_SCALAR_LONG);
423+POWER_EVENT_ATTR(CMPLU_STALL_VECTOR, CMPLU_STALL_VECTOR);
424+POWER_EVENT_ATTR(CMPLU_STALL_VECTOR_LONG, CMPLU_STALL_VECTOR_LONG);
425+POWER_EVENT_ATTR(CMPLU_STALL_LSU, CMPLU_STALL_LSU);
426+POWER_EVENT_ATTR(CMPLU_STALL_REJECT, CMPLU_STALL_REJECT);
427+
428+POWER_EVENT_ATTR(CMPLU_STALL_ERAT_MISS, CMPLU_STALL_ERAT_MISS);
429+POWER_EVENT_ATTR(CMPLU_STALL_DCACHE_MISS, CMPLU_STALL_DCACHE_MISS);
430+POWER_EVENT_ATTR(CMPLU_STALL_STORE, CMPLU_STALL_STORE);
431+POWER_EVENT_ATTR(CMPLU_STALL_THRD, CMPLU_STALL_THRD);
432+POWER_EVENT_ATTR(CMPLU_STALL_IFU, CMPLU_STALL_IFU);
433+POWER_EVENT_ATTR(CMPLU_STALL_BRU, CMPLU_STALL_BRU);
434+POWER_EVENT_ATTR(GCT_NOSLOT_IC_MISS, GCT_NOSLOT_IC_MISS);
435+
436+POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED, GCT_NOSLOT_BR_MPRED);
437+POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED_IC_MISS, GCT_NOSLOT_BR_MPRED_IC_MISS);
438+POWER_EVENT_ATTR(GRP_CMPL, GRP_CMPL);
439+POWER_EVENT_ATTR(1PLUS_PPC_CMPL, 1PLUS_PPC_CMPL);
440+POWER_EVENT_ATTR(CMPLU_STALL_DFU, CMPLU_STALL_DFU);
441+POWER_EVENT_ATTR(RUN_CYC, RUN_CYC);
442+POWER_EVENT_ATTR(RUN_INST_CMPL, RUN_INST_CMPL);
443+
396444 static struct attribute *power7_events_attr[] = {
397445 GENERIC_EVENT_PTR(CYC),
398446 GENERIC_EVENT_PTR(GCT_NOSLOT_CYC),
@@ -411,6 +459,31 @@ static struct attribute *power7_events_attr[] = { · 12 unmodified lines
411459 POWER_EVENT_PTR(LD_MISS_L1),
412460 POWER_EVENT_PTR(BRU_FIN),
413461 POWER_EVENT_PTR(BRU_MPRED),
462+
463+ POWER_EVENT_PTR(CMPLU_STALL_FXU),
464+ POWER_EVENT_PTR(CMPLU_STALL_DIV),
465+ POWER_EVENT_PTR(CMPLU_STALL_SCALAR),
466+ POWER_EVENT_PTR(CMPLU_STALL_SCALAR_LONG),
467+ POWER_EVENT_PTR(CMPLU_STALL_VECTOR),
468+ POWER_EVENT_PTR(CMPLU_STALL_VECTOR_LONG),
469+ POWER_EVENT_PTR(CMPLU_STALL_LSU),
470+ POWER_EVENT_PTR(CMPLU_STALL_REJECT),
471+
472+ POWER_EVENT_PTR(CMPLU_STALL_ERAT_MISS),
473+ POWER_EVENT_PTR(CMPLU_STALL_DCACHE_MISS),
474+ POWER_EVENT_PTR(CMPLU_STALL_STORE),
475+ POWER_EVENT_PTR(CMPLU_STALL_THRD),
476+ POWER_EVENT_PTR(CMPLU_STALL_IFU),
477+ POWER_EVENT_PTR(CMPLU_STALL_BRU),
478+ POWER_EVENT_PTR(GCT_NOSLOT_IC_MISS),
479+ POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED),
480+
481+ POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED_IC_MISS),
482+ POWER_EVENT_PTR(GRP_CMPL),
483+ POWER_EVENT_PTR(1PLUS_PPC_CMPL),
484+ POWER_EVENT_PTR(CMPLU_STALL_DFU),
485+ POWER_EVENT_PTR(RUN_CYC),
486+ POWER_EVENT_PTR(RUN_INST_CMPL),
414487 NULL
415488 };
416489
arch/x86/ia32/ia32_signal.c+0−2
@@ -34,8 +34,6 @@ · 33 unmodified lines
3434 #include <asm/sys_ia32.h>
3535 #include <asm/smap.h>
3636
37−#define FIX_EFLAGS __FIX_EFLAGS
38−
3937 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
4038 {
4139 int err = 0;
arch/x86/include/asm/perf_event.h+3−0
@@ -29,6 +29,9 @@ · 28 unmodified lines
2929 #define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
3030 #define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
3131
32+#define HSW_IN_TX (1ULL << 32)
33+#define HSW_IN_TX_CHECKPOINTED (1ULL << 33)
34+
3235 #define AMD64_EVENTSEL_INT_CORE_ENABLE (1ULL << 36)
3336 #define AMD64_EVENTSEL_GUESTONLY (1ULL << 40)
3437 #define AMD64_EVENTSEL_HOSTONLY (1ULL << 41)
arch/x86/include/asm/sighandling.h+2−2
@@ -7,10 +7,10 @@ · 6 unmodified lines
77
88 #include <asm/processor-flags.h>
99
10−#define __FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
10+#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
1111 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
1212 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
13− X86_EFLAGS_CF)
13+ X86_EFLAGS_CF | X86_EFLAGS_RF)
1414
1515 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
1616
arch/x86/include/uapi/asm/msr-index.h+3−0
@@ -170,6 +170,9 @@ · 169 unmodified lines
170170 #define MSR_KNC_EVNTSEL0 0x00000028
171171 #define MSR_KNC_EVNTSEL1 0x00000029
172172
173+/* Alternative perfctr range with full access. */
174+#define MSR_IA32_PMC0 0x000004c1
175+
173176 /* AMD64 MSRs. Not complete. See the architecture manual for a more
174177 complete list. */
175178
arch/x86/kernel/cpu/Makefile+4−0
@@ -31,11 +31,15 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o · 30 unmodified lines
3131
3232 ifdef CONFIG_PERF_EVENTS
3333 obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o perf_event_amd_uncore.o
34+ifdef CONFIG_AMD_IOMMU
35+obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o
36+endif
3437 obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o
3538 obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
3639 obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o
3740 endif
3841
42+
3943 obj-$(CONFIG_X86_MCE) += mcheck/
4044 obj-$(CONFIG_MTRR) += mtrr/
4145
arch/x86/kernel/cpu/perf_event.c+53−16
@@ -403,7 +403,8 @@ int x86_pmu_hw_config(struct perf_event *event) · 402 unmodified lines
403403 * check that PEBS LBR correction does not conflict with
404404 * whatever the user is asking with attr->branch_sample_type
405405 */
406− if (event->attr.precise_ip > 1) {
406+ if (event->attr.precise_ip > 1 &&
407+ x86_pmu.intel_cap.pebs_format < 2) {
407408 u64 *br_type = &event->attr.branch_sample_type;
408409
409410 if (has_branch_stack(event)) {
@@ -568,7 +569,7 @@ struct sched_state { · 158 unmodified lines
568569 struct perf_sched {
569570 int max_weight;
570571 int max_events;
571− struct event_constraint **constraints;
572+ struct perf_event **events;
572573 struct sched_state state;
573574 int saved_states;
574575 struct sched_state saved[SCHED_STATES_MAX];
@@ -577,7 +578,7 @@ struct perf_sched { · 2 unmodified lines
577578 /*
578579 * Initialize interator that runs through all events and counters.
579580 */
580−static void perf_sched_init(struct perf_sched *sched, struct event_constraint **c,
581+static void perf_sched_init(struct perf_sched *sched, struct perf_event **events,
581582 int num, int wmin, int wmax)
582583 {
583584 int idx;
@@ -585,10 +586,10 @@ static void perf_sched_init(struct perf_sched *sched, struct event_constraint ** · 1 unmodified line
585586 memset(sched, 0, sizeof(*sched));
586587 sched->max_events = num;
587588 sched->max_weight = wmax;
588− sched->constraints = c;
589+ sched->events = events;
589590
590591 for (idx = 0; idx < num; idx++) {
591− if (c[idx]->weight == wmin)
592+ if (events[idx]->hw.constraint->weight == wmin)
592593 break;
593594 }
594595
@@ -635,8 +636,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) · 40 unmodified lines
635636 if (sched->state.event >= sched->max_events)
636637 return false;
637638
638− c = sched->constraints[sched->state.event];
639−
639+ c = sched->events[sched->state.event]->hw.constraint;
640640 /* Prefer fixed purpose counters */
641641 if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
642642 idx = INTEL_PMC_IDX_FIXED;
@@ -694,7 +694,7 @@ static bool perf_sched_next_event(struct perf_sched *sched) · 51 unmodified lines
694694 if (sched->state.weight > sched->max_weight)
695695 return false;
696696 }
697− c = sched->constraints[sched->state.event];
697+ c = sched->events[sched->state.event]->hw.constraint;
698698 } while (c->weight != sched->state.weight);
699699
700700 sched->state.counter = 0; /* start with first counter */
@@ -705,12 +705,12 @@ static bool perf_sched_next_event(struct perf_sched *sched) · 4 unmodified lines
705705 /*
706706 * Assign a counter for each event.
707707 */
708−int perf_assign_events(struct event_constraint **constraints, int n,
708+int perf_assign_events(struct perf_event **events, int n,
709709 int wmin, int wmax, int *assign)
710710 {
711711 struct perf_sched sched;
712712
713− perf_sched_init(&sched, constraints, n, wmin, wmax);
713+ perf_sched_init(&sched, events, n, wmin, wmax);
714714
715715 do {
716716 if (!perf_sched_find_counter(&sched))
@@ -724,16 +724,19 @@ int perf_assign_events(struct event_constraint **constraints, int n, · 7 unmodified lines
724724
725725 int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
726726 {
727− struct event_constraint *c, *constraints[X86_PMC_IDX_MAX];
727+ struct event_constraint *c;
728728 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
729+ struct perf_event *e;
729730 int i, wmin, wmax, num = 0;
730731 struct hw_perf_event *hwc;
731732
732733 bitmap_zero(used_mask, X86_PMC_IDX_MAX);
733734
734735 for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
736+ hwc = &cpuc->event_list[i]->hw;
735737 c = x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]);
736− constraints[i] = c;
738+ hwc->constraint = c;
739+
737740 wmin = min(wmin, c->weight);
738741 wmax = max(wmax, c->weight);
739742 }
@@ -743,7 +746,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) · 3 unmodified lines
743746 */
744747 for (i = 0; i < n; i++) {
745748 hwc = &cpuc->event_list[i]->hw;
746− c = constraints[i];
749+ c = hwc->constraint;
747750
748751 /* never assigned */
749752 if (hwc->idx == -1)
@@ -764,16 +767,35 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) · 14 unmodified lines
764767
765768 /* slow path */
766769 if (i != n)
767− num = perf_assign_events(constraints, n, wmin, wmax, assign);
770+ num = perf_assign_events(cpuc->event_list, n, wmin,
771+ wmax, assign);
768772
773+ /*
774+ * Mark the event as committed, so we do not put_constraint()
775+ * in case new events are added and fail scheduling.
776+ */
777+ if (!num && assign) {
778+ for (i = 0; i < n; i++) {
779+ e = cpuc->event_list[i];
780+ e->hw.flags |= PERF_X86_EVENT_COMMITTED;
781+ }
782+ }
769783 /*
770784 * scheduling failed or is just a simulation,
771785 * free resources if necessary
772786 */
773787 if (!assign || num) {
774788 for (i = 0; i < n; i++) {
789+ e = cpuc->event_list[i];
790+ /*
791+ * do not put_constraint() on comitted events,
792+ * because they are good to go
793+ */
794+ if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
795+ continue;
796+
775797 if (x86_pmu.put_event_constraints)
776− x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]);
798+ x86_pmu.put_event_constraints(cpuc, e);
777799 }
778800 }
779801 return num ? -EINVAL : 0;
@@ -1152,6 +1174,11 @@ static void x86_pmu_del(struct perf_event *event, int flags) · 372 unmodified lines
11521174 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
11531175 int i;
11541176
1177+ /*
1178+ * event is descheduled
1179+ */
1180+ event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
1181+
11551182 /*
11561183 * If we're called during a txn, we don't need to do anything.
11571184 * The events never got scheduled and ->cancel_txn will truncate
@@ -1249,10 +1276,20 @@ void perf_events_lapic_init(void) · 91 unmodified lines
12491276 static int __kprobes
12501277 perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
12511278 {
1279+ int ret;
1280+ u64 start_clock;
1281+ u64 finish_clock;
1282+
12521283 if (!atomic_read(&active_events))
12531284 return NMI_DONE;
12541285
1255− return x86_pmu.handle_irq(regs);
1286+ start_clock = local_clock();
1287+ ret = x86_pmu.handle_irq(regs);
1288+ finish_clock = local_clock();
1289+
1290+ perf_sample_event_took(finish_clock - start_clock);
1291+
1292+ return ret;
12561293 }
12571294
12581295 struct event_constraint emptyconstraint;
arch/x86/kernel/cpu/perf_event.h+21−3
@@ -63,10 +63,12 @@ struct event_constraint { · 62 unmodified lines
6363 int flags;
6464 };
6565 /*
66− * struct event_constraint flags
66+ * struct hw_perf_event.flags flags
6767 */
6868 #define PERF_X86_EVENT_PEBS_LDLAT 0x1 /* ld+ldlat data address sampling */
6969 #define PERF_X86_EVENT_PEBS_ST 0x2 /* st data address sampling */
70+#define PERF_X86_EVENT_PEBS_ST_HSW 0x4 /* haswell style st data sampling */
71+#define PERF_X86_EVENT_COMMITTED 0x8 /* event passed commit_txn */
7072
7173 struct amd_nb {
7274 int nb_id; /* NorthBridge id */
@@ -227,11 +229,14 @@ struct cpu_hw_events { · 154 unmodified lines
227229 * - inv
228230 * - edge
229231 * - cnt-mask
232+ * - in_tx
233+ * - in_tx_checkpointed
230234 * The other filters are supported by fixed counters.
231235 * The any-thread option is supported starting with v3.
232236 */
237+#define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)
233238 #define FIXED_EVENT_CONSTRAINT(c, n) \
234− EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
239+ EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS)
235240
236241 /*
237242 * Constraint on the Event code + UMask
@@ -247,6 +252,11 @@ struct cpu_hw_events { · 9 unmodified lines
247252 __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
248253 HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
249254
255+/* DataLA version of store sampling without extra enable bit. */
256+#define INTEL_PST_HSW_CONSTRAINT(c, n) \
257+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
258+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
259+
250260 #define EVENT_CONSTRAINT_END \
251261 EVENT_CONSTRAINT(0, 0, 0)
252262
@@ -301,6 +311,11 @@ union perf_capabilities { · 48 unmodified lines
301311 u64 pebs_arch_reg:1;
302312 u64 pebs_format:4;
303313 u64 smm_freeze:1;
314+ /*
315+ * PMU supports separate counter range for writing
316+ * values > 32bit.
317+ */
318+ u64 full_width_write:1;
304319 };
305320 u64 capabilities;
306321 };
@@ -375,6 +390,7 @@ struct x86_pmu { · 68 unmodified lines
375390 struct event_constraint *event_constraints;
376391 struct x86_pmu_quirk *quirks;
377392 int perfctr_second_write;
393+ bool late_ack;
378394
379395 /*
380396 * sysfs attrs
@@ -528,7 +544,7 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, · 147 unmodified lines
528544
529545 void x86_pmu_enable_all(int added);
530546
531−int perf_assign_events(struct event_constraint **constraints, int n,
547+int perf_assign_events(struct perf_event **events, int n,
532548 int wmin, int wmax, int *assign);
533549 int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
534550
@@ -633,6 +649,8 @@ extern struct event_constraint intel_snb_pebs_event_constraints[]; · 98 unmodified lines
633649
634650 extern struct event_constraint intel_ivb_pebs_event_constraints[];
635651
652+extern struct event_constraint intel_hsw_pebs_event_constraints[];
653+
636654 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
637655
638656 void intel_pmu_pebs_enable(struct perf_event *event);
arch/x86/kernel/cpu/perf_event_amd.c+17−17
@@ -648,48 +648,48 @@ static __initconst const struct x86_pmu amd_pmu = { · 647 unmodified lines
648648 .cpu_dead = amd_pmu_cpu_dead,
649649 };
650650
651−static int setup_event_constraints(void)
651+static int __init amd_core_pmu_init(void)
652652 {
653− if (boot_cpu_data.x86 == 0x15)
653+ if (!cpu_has_perfctr_core)
654+ return 0;
655+
656+ switch (boot_cpu_data.x86) {
657+ case 0x15:
658+ pr_cont("Fam15h ");
654659 x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
655− return 0;
656−}
660+ break;
657661
658−static int setup_perfctr_core(void)
659−{
660− if (!cpu_has_perfctr_core) {
661− WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h,
662− KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!");
662+ default:
663+ pr_err("core perfctr but no constraints; unknown hardware!\n");
663664 return -ENODEV;
664665 }
665666
666− WARN(x86_pmu.get_event_constraints == amd_get_event_constraints,
667− KERN_ERR "hw perf events core counters need constraints handler!");
668−
669667 /*
670668 * If core performance counter extensions exists, we must use
671669 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
672− * x86_pmu_addr_offset().
670+ * amd_pmu_addr_offset().
673671 */
674672 x86_pmu.eventsel = MSR_F15H_PERF_CTL;
675673 x86_pmu.perfctr = MSR_F15H_PERF_CTR;
676674 x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
677675
678− printk(KERN_INFO "perf: AMD core performance counters detected\n");
679−
676+ pr_cont("core perfctr, ");
680677 return 0;
681678 }
682679
683680 __init int amd_pmu_init(void)
684681 {
682+ int ret;
683+
685684 /* Performance-monitoring supported from K7 and later: */
686685 if (boot_cpu_data.x86 < 6)
687686 return -ENODEV;
688687
689688 x86_pmu = amd_pmu;
690689
691− setup_event_constraints();
692− setup_perfctr_core();
690+ ret = amd_core_pmu_init();
691+ if (ret)
692+ return ret;
693693
694694 /* Events are common for all AMDs */
695695 memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
arch/x86/kernel/cpu/perf_event_amd_iommu.c+504−0
@@ -0,0 +1,504 @@
1+/*
2+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
3+ *
4+ * Author: Steven Kinney <Steven.Kinney@amd.com>
5+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
6+ *
7+ * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
8+ *
9+ * This program is free software; you can redistribute it and/or modify
10+ * it under the terms of the GNU General Public License version 2 as
11+ * published by the Free Software Foundation.
12+ */
13+
14+#include <linux/perf_event.h>
15+#include <linux/module.h>
16+#include <linux/cpumask.h>
17+#include <linux/slab.h>
18+
19+#include "perf_event.h"
20+#include "perf_event_amd_iommu.h"
21+
22+#define COUNTER_SHIFT 16
23+
24+#define _GET_BANK(ev) ((u8)(ev->hw.extra_reg.reg >> 8))
25+#define _GET_CNTR(ev) ((u8)(ev->hw.extra_reg.reg))
26+
27+/* iommu pmu config masks */
28+#define _GET_CSOURCE(ev) ((ev->hw.config & 0xFFULL))
29+#define _GET_DEVID(ev) ((ev->hw.config >> 8) & 0xFFFFULL)
30+#define _GET_PASID(ev) ((ev->hw.config >> 24) & 0xFFFFULL)
31+#define _GET_DOMID(ev) ((ev->hw.config >> 40) & 0xFFFFULL)
32+#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config) & 0xFFFFULL)
33+#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
34+#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)
35+
36+static struct perf_amd_iommu __perf_iommu;
37+
38+struct perf_amd_iommu {
39+ struct pmu pmu;
40+ u8 max_banks;
41+ u8 max_counters;
42+ u64 cntr_assign_mask;
43+ raw_spinlock_t lock;
44+ const struct attribute_group *attr_groups[4];
45+};
46+
47+#define format_group attr_groups[0]
48+#define cpumask_group attr_groups[1]
49+#define events_group attr_groups[2]
50+#define null_group attr_groups[3]
51+
52+/*---------------------------------------------
53+ * sysfs format attributes
54+ *---------------------------------------------*/
55+PMU_FORMAT_ATTR(csource, "config:0-7");
56+PMU_FORMAT_ATTR(devid, "config:8-23");
57+PMU_FORMAT_ATTR(pasid, "config:24-39");
58+PMU_FORMAT_ATTR(domid, "config:40-55");
59+PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
60+PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
61+PMU_FORMAT_ATTR(domid_mask, "config1:32-47");
62+
63+static struct attribute *iommu_format_attrs[] = {
64+ &format_attr_csource.attr,
65+ &format_attr_devid.attr,
66+ &format_attr_pasid.attr,
67+ &format_attr_domid.attr,
68+ &format_attr_devid_mask.attr,
69+ &format_attr_pasid_mask.attr,
70+ &format_attr_domid_mask.attr,
71+ NULL,
72+};
73+
74+static struct attribute_group amd_iommu_format_group = {
75+ .name = "format",
76+ .attrs = iommu_format_attrs,
77+};
78+
79+/*---------------------------------------------
80+ * sysfs events attributes
81+ *---------------------------------------------*/
82+struct amd_iommu_event_desc {
83+ struct kobj_attribute attr;
84+ const char *event;
85+};
86+
87+static ssize_t _iommu_event_show(struct kobject *kobj,
88+ struct kobj_attribute *attr, char *buf)
89+{
90+ struct amd_iommu_event_desc *event =
91+ container_of(attr, struct amd_iommu_event_desc, attr);
92+ return sprintf(buf, "%s\n", event->event);
93+}
94+
95+#define AMD_IOMMU_EVENT_DESC(_name, _event) \
96+{ \
97+ .attr = __ATTR(_name, 0444, _iommu_event_show, NULL), \
98+ .event = _event, \
99+}
100+
101+static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
102+ AMD_IOMMU_EVENT_DESC(mem_pass_untrans, "csource=0x01"),
103+ AMD_IOMMU_EVENT_DESC(mem_pass_pretrans, "csource=0x02"),
104+ AMD_IOMMU_EVENT_DESC(mem_pass_excl, "csource=0x03"),
105+ AMD_IOMMU_EVENT_DESC(mem_target_abort, "csource=0x04"),
106+ AMD_IOMMU_EVENT_DESC(mem_trans_total, "csource=0x05"),
107+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit, "csource=0x06"),
108+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis, "csource=0x07"),
109+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit, "csource=0x08"),
110+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis, "csource=0x09"),
111+ AMD_IOMMU_EVENT_DESC(mem_dte_hit, "csource=0x0a"),
112+ AMD_IOMMU_EVENT_DESC(mem_dte_mis, "csource=0x0b"),
113+ AMD_IOMMU_EVENT_DESC(page_tbl_read_tot, "csource=0x0c"),
114+ AMD_IOMMU_EVENT_DESC(page_tbl_read_nst, "csource=0x0d"),
115+ AMD_IOMMU_EVENT_DESC(page_tbl_read_gst, "csource=0x0e"),
116+ AMD_IOMMU_EVENT_DESC(int_dte_hit, "csource=0x0f"),
117+ AMD_IOMMU_EVENT_DESC(int_dte_mis, "csource=0x10"),
118+ AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"),
119+ AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"),
120+ AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"),
121+ { /* end: all zeroes */ },
122+};
123+
124+/*---------------------------------------------
125+ * sysfs cpumask attributes
126+ *---------------------------------------------*/
127+static cpumask_t iommu_cpumask;
128+
129+static ssize_t _iommu_cpumask_show(struct device *dev,
130+ struct device_attribute *attr,
131+ char *buf)
132+{
133+ int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &iommu_cpumask);
134+ buf[n++] = '\n';
135+ buf[n] = '\0';
136+ return n;
137+}
138+static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);
139+
140+static struct attribute *iommu_cpumask_attrs[] = {
141+ &dev_attr_cpumask.attr,
142+ NULL,
143+};
144+
145+static struct attribute_group amd_iommu_cpumask_group = {
146+ .attrs = iommu_cpumask_attrs,
147+};
148+
149+/*---------------------------------------------*/
150+
151+static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
152+{
153+ unsigned long flags;
154+ int shift, bank, cntr, retval;
155+ int max_banks = perf_iommu->max_banks;
156+ int max_cntrs = perf_iommu->max_counters;
157+
158+ raw_spin_lock_irqsave(&perf_iommu->lock, flags);
159+
160+ for (bank = 0, shift = 0; bank < max_banks; bank++) {
161+ for (cntr = 0; cntr < max_cntrs; cntr++) {
162+ shift = bank + (bank*3) + cntr;
163+ if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
164+ continue;
165+ } else {
166+ perf_iommu->cntr_assign_mask |= (1ULL<<shift);
167+ retval = ((u16)((u16)bank<<8) | (u8)(cntr));
168+ goto out;
169+ }
170+ }
171+ }
172+ retval = -ENOSPC;
173+out:
174+ raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
175+ return retval;
176+}
177+
178+static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
179+ u8 bank, u8 cntr)
180+{
181+ unsigned long flags;
182+ int max_banks, max_cntrs;
183+ int shift = 0;
184+
185+ max_banks = perf_iommu->max_banks;
186+ max_cntrs = perf_iommu->max_counters;
187+
188+ if ((bank > max_banks) || (cntr > max_cntrs))
189+ return -EINVAL;
190+
191+ shift = bank + cntr + (bank*3);
192+
193+ raw_spin_lock_irqsave(&perf_iommu->lock, flags);
194+ perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
195+ raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
196+
197+ return 0;
198+}
199+
200+static int perf_iommu_event_init(struct perf_event *event)
201+{
202+ struct hw_perf_event *hwc = &event->hw;
203+ struct perf_amd_iommu *perf_iommu;
204+ u64 config, config1;
205+
206+ /* test the event attr type check for PMU enumeration */
207+ if (event->attr.type != event->pmu->type)
208+ return -ENOENT;
209+
210+ /*
211+ * IOMMU counters are shared across all cores.
212+ * Therefore, it does not support per-process mode.
213+ * Also, it does not support event sampling mode.
214+ */
215+ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
216+ return -EINVAL;
217+
218+ /* IOMMU counters do not have usr/os/guest/host bits */
219+ if (event->attr.exclude_user || event->attr.exclude_kernel ||
220+ event->attr.exclude_host || event->attr.exclude_guest)
221+ return -EINVAL;
222+
223+ if (event->cpu < 0)
224+ return -EINVAL;
225+
226+ perf_iommu = &__perf_iommu;
227+
228+ if (event->pmu != &perf_iommu->pmu)
229+ return -ENOENT;
230+
231+ if (perf_iommu) {
232+ config = event->attr.config;
233+ config1 = event->attr.config1;
234+ } else {
235+ return -EINVAL;
236+ }
237+
238+ /* integrate with iommu base devid (0000), assume one iommu */
239+ perf_iommu->max_banks =
240+ amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
241+ perf_iommu->max_counters =
242+ amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
243+ if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
244+ return -EINVAL;
245+
246+ /* update the hw_perf_event struct with the iommu config data */
247+ hwc->config = config;
248+ hwc->extra_reg.config = config1;
249+
250+ return 0;
251+}
252+
253+static void perf_iommu_enable_event(struct perf_event *ev)
254+{
255+ u8 csource = _GET_CSOURCE(ev);
256+ u16 devid = _GET_DEVID(ev);
257+ u64 reg = 0ULL;
258+
259+ reg = csource;
260+ amd_iommu_pc_get_set_reg_val(devid,
261+ _GET_BANK(ev), _GET_CNTR(ev) ,
262+ IOMMU_PC_COUNTER_SRC_REG, &reg, true);
263+
264+ reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
265+ if (reg)
266+ reg |= (1UL << 31);
267+ amd_iommu_pc_get_set_reg_val(devid,
268+ _GET_BANK(ev), _GET_CNTR(ev) ,
269+ IOMMU_PC_DEVID_MATCH_REG, &reg, true);
270+
271+ reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
272+ if (reg)
273+ reg |= (1UL << 31);
274+ amd_iommu_pc_get_set_reg_val(devid,
275+ _GET_BANK(ev), _GET_CNTR(ev) ,
276+ IOMMU_PC_PASID_MATCH_REG, &reg, true);
277+
278+ reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
279+ if (reg)
280+ reg |= (1UL << 31);
281+ amd_iommu_pc_get_set_reg_val(devid,
282+ _GET_BANK(ev), _GET_CNTR(ev) ,
283+ IOMMU_PC_DOMID_MATCH_REG, &reg, true);
284+}
285+
286+static void perf_iommu_disable_event(struct perf_event *event)
287+{
288+ u64 reg = 0ULL;
289+
290+ amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
291+ _GET_BANK(event), _GET_CNTR(event),
292+ IOMMU_PC_COUNTER_SRC_REG, &reg, true);
293+}
294+
295+static void perf_iommu_start(struct perf_event *event, int flags)
296+{
297+ struct hw_perf_event *hwc = &event->hw;
298+
299+ pr_debug("perf: amd_iommu:perf_iommu_start\n");
300+ if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
301+ return;
302+
303+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
304+ hwc->state = 0;
305+
306+ if (flags & PERF_EF_RELOAD) {
307+ u64 prev_raw_count = local64_read(&hwc->prev_count);
308+ amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
309+ _GET_BANK(event), _GET_CNTR(event),
310+ IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
311+ }
312+
313+ perf_iommu_enable_event(event);
314+ perf_event_update_userpage(event);
315+
316+}
317+
318+static void perf_iommu_read(struct perf_event *event)
319+{
320+ u64 count = 0ULL;
321+ u64 prev_raw_count = 0ULL;
322+ u64 delta = 0ULL;
323+ struct hw_perf_event *hwc = &event->hw;
324+ pr_debug("perf: amd_iommu:perf_iommu_read\n");
325+
326+ amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
327+ _GET_BANK(event), _GET_CNTR(event),
328+ IOMMU_PC_COUNTER_REG, &count, false);
329+
330+ /* IOMMU pc counter register is only 48 bits */
331+ count &= 0xFFFFFFFFFFFFULL;
332+
333+ prev_raw_count = local64_read(&hwc->prev_count);
334+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
335+ count) != prev_raw_count)
336+ return;
337+
338+ /* Handling 48-bit counter overflowing */
339+ delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
340+ delta >>= COUNTER_SHIFT;
341+ local64_add(delta, &event->count);
342+
343+}
344+
345+static void perf_iommu_stop(struct perf_event *event, int flags)
346+{
347+ struct hw_perf_event *hwc = &event->hw;
348+ u64 config;
349+
350+ pr_debug("perf: amd_iommu:perf_iommu_stop\n");
351+
352+ if (hwc->state & PERF_HES_UPTODATE)
353+ return;
354+
355+ perf_iommu_disable_event(event);
356+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
357+ hwc->state |= PERF_HES_STOPPED;
358+
359+ if (hwc->state & PERF_HES_UPTODATE)
360+ return;
361+
362+ config = hwc->config;
363+ perf_iommu_read(event);
364+ hwc->state |= PERF_HES_UPTODATE;
365+}
366+
367+static int perf_iommu_add(struct perf_event *event, int flags)
368+{
369+ int retval;
370+ struct perf_amd_iommu *perf_iommu =
371+ container_of(event->pmu, struct perf_amd_iommu, pmu);
372+
373+ pr_debug("perf: amd_iommu:perf_iommu_add\n");
374+ event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
375+
376+ /* request an iommu bank/counter */
377+ retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
378+ if (retval != -ENOSPC)
379+ event->hw.extra_reg.reg = (u16)retval;
380+ else
381+ return retval;
382+
383+ if (flags & PERF_EF_START)
384+ perf_iommu_start(event, PERF_EF_RELOAD);
385+
386+ return 0;
387+}
388+
389+static void perf_iommu_del(struct perf_event *event, int flags)
390+{
391+ struct perf_amd_iommu *perf_iommu =
392+ container_of(event->pmu, struct perf_amd_iommu, pmu);
393+
394+ pr_debug("perf: amd_iommu:perf_iommu_del\n");
395+ perf_iommu_stop(event, PERF_EF_UPDATE);
396+
397+ /* clear the assigned iommu bank/counter */
398+ clear_avail_iommu_bnk_cntr(perf_iommu,
399+ _GET_BANK(event),
400+ _GET_CNTR(event));
401+
402+ perf_event_update_userpage(event);
403+}
404+
405+static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
406+{
407+ struct attribute **attrs;
408+ struct attribute_group *attr_group;
409+ int i = 0, j;
410+
411+ while (amd_iommu_v2_event_descs[i].attr.attr.name)
412+ i++;
413+
414+ attr_group = kzalloc(sizeof(struct attribute *)
415+ * (i + 1) + sizeof(*attr_group), GFP_KERNEL);
416+ if (!attr_group)
417+ return -ENOMEM;
418+
419+ attrs = (struct attribute **)(attr_group + 1);
420+ for (j = 0; j < i; j++)
421+ attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
422+
423+ attr_group->name = "events";
424+ attr_group->attrs = attrs;
425+ perf_iommu->events_group = attr_group;
426+
427+ return 0;
428+}
429+
430+static __init void amd_iommu_pc_exit(void)
431+{
432+ if (__perf_iommu.events_group != NULL) {
433+ kfree(__perf_iommu.events_group);
434+ __perf_iommu.events_group = NULL;
435+ }
436+}
437+
438+static __init int _init_perf_amd_iommu(
439+ struct perf_amd_iommu *perf_iommu, char *name)
440+{
441+ int ret;
442+
443+ raw_spin_lock_init(&perf_iommu->lock);
444+
445+ /* Init format attributes */
446+ perf_iommu->format_group = &amd_iommu_format_group;
447+
448+ /* Init cpumask attributes to only core 0 */
449+ cpumask_set_cpu(0, &iommu_cpumask);
450+ perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
451+
452+ /* Init events attributes */
453+ if (_init_events_attrs(perf_iommu) != 0)
454+ pr_err("perf: amd_iommu: Only support raw events.\n");
455+
456+ /* Init null attributes */
457+ perf_iommu->null_group = NULL;
458+ perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
459+
460+ ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
461+ if (ret) {
462+ pr_err("perf: amd_iommu: Failed to initialized.\n");
463+ amd_iommu_pc_exit();
464+ } else {
465+ pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
466+ amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
467+ amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
468+ }
469+
470+ return ret;
471+}
472+
473+static struct perf_amd_iommu __perf_iommu = {
474+ .pmu = {
475+ .event_init = perf_iommu_event_init,
476+ .add = perf_iommu_add,
477+ .del = perf_iommu_del,
478+ .start = perf_iommu_start,
479+ .stop = perf_iommu_stop,
480+ .read = perf_iommu_read,
481+ },
482+ .max_banks = 0x00,
483+ .max_counters = 0x00,
484+ .cntr_assign_mask = 0ULL,
485+ .format_group = NULL,
486+ .cpumask_group = NULL,
487+ .events_group = NULL,
488+ .null_group = NULL,
489+};
490+
491+static __init int amd_iommu_pc_init(void)
492+{
493+ /* Make sure the IOMMU PC resource is available */
494+ if (!amd_iommu_pc_supported()) {
495+ pr_err("perf: amd_iommu PMU not installed. No support!\n");
496+ return -ENODEV;
497+ }
498+
499+ _init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
500+
501+ return 0;
502+}
503+
504+device_initcall(amd_iommu_pc_init);
arch/x86/kernel/cpu/perf_event_amd_iommu.h+40−0
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
3+ *
4+ * Author: Steven Kinney <Steven.Kinney@amd.com>
5+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.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 as
9+ * published by the Free Software Foundation.
10+ */
11+
12+#ifndef _PERF_EVENT_AMD_IOMMU_H_
13+#define _PERF_EVENT_AMD_IOMMU_H_
14+
15+/* iommu pc mmio region register indexes */
16+#define IOMMU_PC_COUNTER_REG 0x00
17+#define IOMMU_PC_COUNTER_SRC_REG 0x08
18+#define IOMMU_PC_PASID_MATCH_REG 0x10
19+#define IOMMU_PC_DOMID_MATCH_REG 0x18
20+#define IOMMU_PC_DEVID_MATCH_REG 0x20
21+#define IOMMU_PC_COUNTER_REPORT_REG 0x28
22+
23+/* maximun specified bank/counters */
24+#define PC_MAX_SPEC_BNKS 64
25+#define PC_MAX_SPEC_CNTRS 16
26+
27+/* iommu pc reg masks*/
28+#define IOMMU_BASE_DEVID 0x0000
29+
30+/* amd_iommu_init.c external support functions */
31+extern bool amd_iommu_pc_supported(void);
32+
33+extern u8 amd_iommu_pc_get_max_banks(u16 devid);
34+
35+extern u8 amd_iommu_pc_get_max_counters(u16 devid);
36+
37+extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr,
38+ u8 fxn, u64 *value, bool is_write);
39+
40+#endif /*_PERF_EVENT_AMD_IOMMU_H_*/
arch/x86/kernel/cpu/perf_event_intel.c+122−14
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <linux/slab.h>
1414 #include <linux/export.h>
1515
16+#include <asm/cpufeature.h>
1617 #include <asm/hardirq.h>
1718 #include <asm/apic.h>
1819
@@ -190,6 +191,22 @@ struct attribute *snb_events_attrs[] = { · 171 unmodified lines
190191 NULL,
191192 };
192193
194+static struct event_constraint intel_hsw_event_constraints[] = {
195+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
196+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
197+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
198+ INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.* */
199+ INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
200+ INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
201+ /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
202+ INTEL_EVENT_CONSTRAINT(0x08a3, 0x4),
203+ /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
204+ INTEL_EVENT_CONSTRAINT(0x0ca3, 0x4),
205+ /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
206+ INTEL_EVENT_CONSTRAINT(0x04a3, 0xf),
207+ EVENT_CONSTRAINT_END
208+};
209+
193210 static u64 intel_pmu_event_map(int hw_event)
194211 {
195212 return intel_perfmon_event_map[hw_event];
@@ -872,7 +889,8 @@ static inline bool intel_pmu_needs_lbr_smpl(struct perf_event *event) · 676 unmodified lines
872889 return true;
873890
874891 /* implicit branch sampling to correct PEBS skid */
875− if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
892+ if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1 &&
893+ x86_pmu.intel_cap.pebs_format < 2)
876894 return true;
877895
878896 return false;
@@ -1167,15 +1185,11 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) · 288 unmodified lines
11671185 cpuc = &__get_cpu_var(cpu_hw_events);
11681186
11691187 /*
1170− * Some chipsets need to unmask the LVTPC in a particular spot
1171− * inside the nmi handler. As a result, the unmasking was pushed
1172− * into all the nmi handlers.
1173− *
1174− * This handler doesn't seem to have any issues with the unmasking
1175− * so it was left at the top.
1188+ * No known reason to not always do late ACK,
1189+ * but just in case do it opt-in.
11761190 */
1177− apic_write(APIC_LVTPC, APIC_DM_NMI);
1178−
1191+ if (!x86_pmu.late_ack)
1192+ apic_write(APIC_LVTPC, APIC_DM_NMI);
11791193 intel_pmu_disable_all();
11801194 handled = intel_pmu_drain_bts_buffer();
11811195 status = intel_pmu_get_status();
@@ -1188,8 +1202,12 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) · 6 unmodified lines
11881202 again:
11891203 intel_pmu_ack_status(status);
11901204 if (++loops > 100) {
1191− WARN_ONCE(1, "perfevents: irq loop stuck!\n");
1192− perf_event_print_debug();
1205+ static bool warned = false;
1206+ if (!warned) {
1207+ WARN(1, "perfevents: irq loop stuck!\n");
1208+ perf_event_print_debug();
1209+ warned = true;
1210+ }
11931211 intel_pmu_reset();
11941212 goto done;
11951213 }
@@ -1235,6 +1253,13 @@ again: · 39 unmodified lines
12351253
12361254 done:
12371255 intel_pmu_enable_all(0);
1256+ /*
1257+ * Only unmask the NMI after the overflow counters
1258+ * have been reset. This avoids spurious NMIs on
1259+ * Haswell CPUs.
1260+ */
1261+ if (x86_pmu.late_ack)
1262+ apic_write(APIC_LVTPC, APIC_DM_NMI);
12381263 return handled;
12391264 }
12401265
@@ -1425,7 +1450,6 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) · 184 unmodified lines
14251450 if (x86_pmu.event_constraints) {
14261451 for_each_event_constraint(c, x86_pmu.event_constraints) {
14271452 if ((event->hw.config & c->cmask) == c->code) {
1428− /* hw.flags zeroed at initialization */
14291453 event->hw.flags |= c->flags;
14301454 return c;
14311455 }
@@ -1473,7 +1497,6 @@ intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc, · 41 unmodified lines
14731497 static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
14741498 struct perf_event *event)
14751499 {
1476− event->hw.flags = 0;
14771500 intel_put_shared_regs_event_constraints(cpuc, event);
14781501 }
14791502
@@ -1646,6 +1669,47 @@ static void core_pmu_enable_all(int added) · 166 unmodified lines
16461669 }
16471670 }
16481671
1672+static int hsw_hw_config(struct perf_event *event)
1673+{
1674+ int ret = intel_pmu_hw_config(event);
1675+
1676+ if (ret)
1677+ return ret;
1678+ if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
1679+ return 0;
1680+ event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
1681+
1682+ /*
1683+ * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with
1684+ * PEBS or in ANY thread mode. Since the results are non-sensical forbid
1685+ * this combination.
1686+ */
1687+ if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) &&
1688+ ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) ||
1689+ event->attr.precise_ip > 0))
1690+ return -EOPNOTSUPP;
1691+
1692+ return 0;
1693+}
1694+
1695+static struct event_constraint counter2_constraint =
1696+ EVENT_CONSTRAINT(0, 0x4, 0);
1697+
1698+static struct event_constraint *
1699+hsw_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
1700+{
1701+ struct event_constraint *c = intel_get_event_constraints(cpuc, event);
1702+
1703+ /* Handle special quirk on in_tx_checkpointed only in counter 2 */
1704+ if (event->hw.config & HSW_IN_TX_CHECKPOINTED) {
1705+ if (c->idxmsk64 & (1U << 2))
1706+ return &counter2_constraint;
1707+ return &emptyconstraint;
1708+ }
1709+
1710+ return c;
1711+}
1712+
16491713 PMU_FORMAT_ATTR(event, "config:0-7" );
16501714 PMU_FORMAT_ATTR(umask, "config:8-15" );
16511715 PMU_FORMAT_ATTR(edge, "config:18" );
@@ -1653,6 +1717,8 @@ PMU_FORMAT_ATTR(pc, "config:19" ); · 1 unmodified line
16531717 PMU_FORMAT_ATTR(any, "config:21" ); /* v3 + */
16541718 PMU_FORMAT_ATTR(inv, "config:23" );
16551719 PMU_FORMAT_ATTR(cmask, "config:24-31" );
1720+PMU_FORMAT_ATTR(in_tx, "config:32");
1721+PMU_FORMAT_ATTR(in_tx_cp, "config:33");
16561722
16571723 static struct attribute *intel_arch_formats_attr[] = {
16581724 &format_attr_event.attr,
@@ -1807,6 +1873,8 @@ static struct attribute *intel_arch3_formats_attr[] = { · 148 unmodified lines
18071873 &format_attr_any.attr,
18081874 &format_attr_inv.attr,
18091875 &format_attr_cmask.attr,
1876+ &format_attr_in_tx.attr,
1877+ &format_attr_in_tx_cp.attr,
18101878
18111879 &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */
18121880 &format_attr_ldlat.attr, /* PEBS load latency */
@@ -1966,6 +2034,15 @@ static __init void intel_nehalem_quirk(void) · 153 unmodified lines
19662034 }
19672035 }
19682036
2037+EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3");
2038+EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82")
2039+
2040+static struct attribute *hsw_events_attrs[] = {
2041+ EVENT_PTR(mem_ld_hsw),
2042+ EVENT_PTR(mem_st_hsw),
2043+ NULL
2044+};
2045+
19692046 __init int intel_pmu_init(void)
19702047 {
19712048 union cpuid10_edx edx;
@@ -2189,6 +2266,30 @@ __init int intel_pmu_init(void) · 217 unmodified lines
21892266 break;
21902267
21912268
2269+ case 60: /* Haswell Client */
2270+ case 70:
2271+ case 71:
2272+ case 63:
2273+ x86_pmu.late_ack = true;
2274+ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids));
2275+ memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
2276+
2277+ intel_pmu_lbr_init_snb();
2278+
2279+ x86_pmu.event_constraints = intel_hsw_event_constraints;
2280+ x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
2281+ x86_pmu.extra_regs = intel_snb_extra_regs;
2282+ x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
2283+ /* all extra regs are per-cpu when HT is on */
2284+ x86_pmu.er_flags |= ERF_HAS_RSP_1;
2285+ x86_pmu.er_flags |= ERF_NO_HT_SHARING;
2286+
2287+ x86_pmu.hw_config = hsw_hw_config;
2288+ x86_pmu.get_event_constraints = hsw_get_event_constraints;
2289+ x86_pmu.cpu_events = hsw_events_attrs;
2290+ pr_cont("Haswell events, ");
2291+ break;
2292+
21922293 default:
21932294 switch (x86_pmu.version) {
21942295 case 1:
@@ -2227,7 +2328,7 @@ __init int intel_pmu_init(void) · 32 unmodified lines
22272328 * counter, so do not extend mask to generic counters
22282329 */
22292330 for_each_event_constraint(c, x86_pmu.event_constraints) {
2230− if (c->cmask != X86_RAW_EVENT_MASK
2331+ if (c->cmask != FIXED_EVENT_FLAGS
22312332 || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) {
22322333 continue;
22332334 }
@@ -2237,5 +2338,12 @@ __init int intel_pmu_init(void) · 3 unmodified lines
22372338 }
22382339 }
22392340
2341+ /* Support full width counters using alternative MSR range */
2342+ if (x86_pmu.intel_cap.full_width_write) {
2343+ x86_pmu.max_period = x86_pmu.cntval_mask;
2344+ x86_pmu.perfctr = MSR_IA32_PMC0;
2345+ pr_cont("full-width counters, ");
2346+ }
2347+
22402348 return 0;
22412349 }
arch/x86/kernel/cpu/perf_event_intel_ds.c+153−25
@@ -107,6 +107,19 @@ static u64 precise_store_data(u64 status) · 106 unmodified lines
107107 return val;
108108 }
109109
110+static u64 precise_store_data_hsw(u64 status)
111+{
112+ union perf_mem_data_src dse;
113+
114+ dse.val = 0;
115+ dse.mem_op = PERF_MEM_OP_STORE;
116+ dse.mem_lvl = PERF_MEM_LVL_NA;
117+ if (status & 1)
118+ dse.mem_lvl = PERF_MEM_LVL_L1;
119+ /* Nothing else supported. Sorry. */
120+ return dse.val;
121+}
122+
110123 static u64 load_latency_data(u64 status)
111124 {
112125 union intel_x86_pebs_dse dse;
@@ -165,6 +178,22 @@ struct pebs_record_nhm { · 52 unmodified lines
165178 u64 status, dla, dse, lat;
166179 };
167180
181+/*
182+ * Same as pebs_record_nhm, with two additional fields.
183+ */
184+struct pebs_record_hsw {
185+ struct pebs_record_nhm nhm;
186+ /*
187+ * Real IP of the event. In the Intel documentation this
188+ * is called eventingrip.
189+ */
190+ u64 real_ip;
191+ /*
192+ * TSX tuning information field: abort cycles and abort flags.
193+ */
194+ u64 tsx_tuning;
195+};
196+
168197 void init_debug_store_on_cpu(int cpu)
169198 {
170199 struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
@@ -548,6 +577,42 @@ struct event_constraint intel_ivb_pebs_event_constraints[] = { · 377 unmodified lines
548577 EVENT_CONSTRAINT_END
549578 };
550579
580+struct event_constraint intel_hsw_pebs_event_constraints[] = {
581+ INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
582+ INTEL_PST_HSW_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
583+ INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
584+ INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
585+ INTEL_UEVENT_CONSTRAINT(0x01c5, 0xf), /* BR_MISP_RETIRED.CONDITIONAL */
586+ INTEL_UEVENT_CONSTRAINT(0x04c5, 0xf), /* BR_MISP_RETIRED.ALL_BRANCHES */
587+ INTEL_UEVENT_CONSTRAINT(0x20c5, 0xf), /* BR_MISP_RETIRED.NEAR_TAKEN */
588+ INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.* */
589+ /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
590+ INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf),
591+ /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
592+ INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf),
593+ INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
594+ INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
595+ /* MEM_UOPS_RETIRED.SPLIT_STORES */
596+ INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf),
597+ INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
598+ INTEL_PST_HSW_CONSTRAINT(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
599+ INTEL_UEVENT_CONSTRAINT(0x01d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L1_HIT */
600+ INTEL_UEVENT_CONSTRAINT(0x02d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L2_HIT */
601+ INTEL_UEVENT_CONSTRAINT(0x04d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L3_HIT */
602+ /* MEM_LOAD_UOPS_RETIRED.HIT_LFB */
603+ INTEL_UEVENT_CONSTRAINT(0x40d1, 0xf),
604+ /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS */
605+ INTEL_UEVENT_CONSTRAINT(0x01d2, 0xf),
606+ /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT */
607+ INTEL_UEVENT_CONSTRAINT(0x02d2, 0xf),
608+ /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM */
609+ INTEL_UEVENT_CONSTRAINT(0x01d3, 0xf),
610+ INTEL_UEVENT_CONSTRAINT(0x04c8, 0xf), /* HLE_RETIRED.Abort */
611+ INTEL_UEVENT_CONSTRAINT(0x04c9, 0xf), /* RTM_RETIRED.Abort */
612+
613+ EVENT_CONSTRAINT_END
614+};
615+
551616 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
552617 {
553618 struct event_constraint *c;
@@ -588,6 +653,12 @@ void intel_pmu_pebs_disable(struct perf_event *event) · 34 unmodified lines
588653 struct hw_perf_event *hwc = &event->hw;
589654
590655 cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
656+
657+ if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_LDLAT)
658+ cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
659+ else if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_ST)
660+ cpuc->pebs_enabled &= ~(1ULL << 63);
661+
591662 if (cpuc->enabled)
592663 wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
593664
@@ -697,6 +768,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event, · 103 unmodified lines
697768 */
698769 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
699770 struct pebs_record_nhm *pebs = __pebs;
771+ struct pebs_record_hsw *pebs_hsw = __pebs;
700772 struct perf_sample_data data;
701773 struct pt_regs regs;
702774 u64 sample_type;
@@ -706,7 +778,8 @@ static void __intel_pmu_pebs_event(struct perf_event *event, · 3 unmodified lines
706778 return;
707779
708780 fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT;
709− fst = event->hw.flags & PERF_X86_EVENT_PEBS_ST;
781+ fst = event->hw.flags & (PERF_X86_EVENT_PEBS_ST |
782+ PERF_X86_EVENT_PEBS_ST_HSW);
710783
711784 perf_sample_data_init(&data, 0, event->hw.last_period);
712785
@@ -717,9 +790,6 @@ static void __intel_pmu_pebs_event(struct perf_event *event, · 4 unmodified lines
717790 * if PEBS-LL or PreciseStore
718791 */
719792 if (fll || fst) {
720− if (sample_type & PERF_SAMPLE_ADDR)
721− data.addr = pebs->dla;
722−
723793 /*
724794 * Use latency for weight (only avail with PEBS-LL)
725795 */
@@ -732,6 +802,9 @@ static void __intel_pmu_pebs_event(struct perf_event *event, · 6 unmodified lines
732802 if (sample_type & PERF_SAMPLE_DATA_SRC) {
733803 if (fll)
734804 data.data_src.val = load_latency_data(pebs->dse);
805+ else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
806+ data.data_src.val =
807+ precise_store_data_hsw(pebs->dse);
735808 else
736809 data.data_src.val = precise_store_data(pebs->dse);
737810 }
@@ -753,11 +826,18 @@ static void __intel_pmu_pebs_event(struct perf_event *event, · 15 unmodified lines
753826 regs.bp = pebs->bp;
754827 regs.sp = pebs->sp;
755828
756− if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
829+ if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
830+ regs.ip = pebs_hsw->real_ip;
831+ regs.flags |= PERF_EFLAGS_EXACT;
832+ } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
757833 regs.flags |= PERF_EFLAGS_EXACT;
758834 else
759835 regs.flags &= ~PERF_EFLAGS_EXACT;
760836
837+ if ((event->attr.sample_type & PERF_SAMPLE_ADDR) &&
838+ x86_pmu.intel_cap.pebs_format >= 1)
839+ data.addr = pebs->dla;
840+
761841 if (has_branch_stack(event))
762842 data.br_stack = &cpuc->lbr_stack;
763843
@@ -806,35 +886,22 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) · 42 unmodified lines
806886 __intel_pmu_pebs_event(event, iregs, at);
807887 }
808888
809−static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
889+static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at,
890+ void *top)
810891 {
811892 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
812893 struct debug_store *ds = cpuc->ds;
813− struct pebs_record_nhm *at, *top;
814894 struct perf_event *event = NULL;
815895 u64 status = 0;
816− int bit, n;
817−
818− if (!x86_pmu.pebs_active)
819− return;
820−
821− at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
822− top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
896+ int bit;
823897
824898 ds->pebs_index = ds->pebs_buffer_base;
825899
826− n = top - at;
827− if (n <= 0)
828− return;
829−
830− /*
831− * Should not happen, we program the threshold at 1 and do not
832− * set a reset value.
833− */
834− WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n);
900+ for (; at < top; at += x86_pmu.pebs_record_size) {
901+ struct pebs_record_nhm *p = at;
835902
836− for ( ; at < top; at++) {
837− for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) {
903+ for_each_set_bit(bit, (unsigned long *)&p->status,
904+ x86_pmu.max_pebs_events) {
838905 event = cpuc->events[bit];
839906 if (!test_bit(bit, cpuc->active_mask))
840907 continue;
@@ -857,6 +924,61 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) · 16 unmodified lines
857924 }
858925 }
859926
927+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
928+{
929+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
930+ struct debug_store *ds = cpuc->ds;
931+ struct pebs_record_nhm *at, *top;
932+ int n;
933+
934+ if (!x86_pmu.pebs_active)
935+ return;
936+
937+ at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
938+ top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
939+
940+ ds->pebs_index = ds->pebs_buffer_base;
941+
942+ n = top - at;
943+ if (n <= 0)
944+ return;
945+
946+ /*
947+ * Should not happen, we program the threshold at 1 and do not
948+ * set a reset value.
949+ */
950+ WARN_ONCE(n > x86_pmu.max_pebs_events,
951+ "Unexpected number of pebs records %d\n", n);
952+
953+ return __intel_pmu_drain_pebs_nhm(iregs, at, top);
954+}
955+
956+static void intel_pmu_drain_pebs_hsw(struct pt_regs *iregs)
957+{
958+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
959+ struct debug_store *ds = cpuc->ds;
960+ struct pebs_record_hsw *at, *top;
961+ int n;
962+
963+ if (!x86_pmu.pebs_active)
964+ return;
965+
966+ at = (struct pebs_record_hsw *)(unsigned long)ds->pebs_buffer_base;
967+ top = (struct pebs_record_hsw *)(unsigned long)ds->pebs_index;
968+
969+ n = top - at;
970+ if (n <= 0)
971+ return;
972+ /*
973+ * Should not happen, we program the threshold at 1 and do not
974+ * set a reset value.
975+ */
976+ WARN_ONCE(n > x86_pmu.max_pebs_events,
977+ "Unexpected number of pebs records %d\n", n);
978+
979+ return __intel_pmu_drain_pebs_nhm(iregs, at, top);
980+}
981+
860982 /*
861983 * BTS, PEBS probe and setup
862984 */
@@ -888,6 +1010,12 @@ void intel_ds_init(void) · 25 unmodified lines
8881010 x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
8891011 break;
8901012
1013+ case 2:
1014+ pr_cont("PEBS fmt2%c, ", pebs_type);
1015+ x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
1016+ x86_pmu.drain_pebs = intel_pmu_drain_pebs_hsw;
1017+ break;
1018+
8911019 default:
8921020 printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
8931021 x86_pmu.pebs = 0;
arch/x86/kernel/cpu/perf_event_intel_lbr.c+54−15
@@ -12,6 +12,16 @@ enum { · 11 unmodified lines
1212 LBR_FORMAT_LIP = 0x01,
1313 LBR_FORMAT_EIP = 0x02,
1414 LBR_FORMAT_EIP_FLAGS = 0x03,
15+ LBR_FORMAT_EIP_FLAGS2 = 0x04,
16+ LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_EIP_FLAGS2,
17+};
18+
19+static enum {
20+ LBR_EIP_FLAGS = 1,
21+ LBR_TSX = 2,
22+} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
23+ [LBR_FORMAT_EIP_FLAGS] = LBR_EIP_FLAGS,
24+ [LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
1525 };
1626
1727 /*
@@ -56,6 +66,8 @@ enum { · 38 unmodified lines
5666 LBR_FAR)
5767
5868 #define LBR_FROM_FLAG_MISPRED (1ULL << 63)
69+#define LBR_FROM_FLAG_IN_TX (1ULL << 62)
70+#define LBR_FROM_FLAG_ABORT (1ULL << 61)
5971
6072 #define for_each_branch_sample_type(x) \
6173 for ((x) = PERF_SAMPLE_BRANCH_USER; \
@@ -81,9 +93,13 @@ enum { · 19 unmodified lines
8193 X86_BR_JMP = 1 << 9, /* jump */
8294 X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */
8395 X86_BR_IND_CALL = 1 << 11,/* indirect calls */
96+ X86_BR_ABORT = 1 << 12,/* transaction abort */
97+ X86_BR_IN_TX = 1 << 13,/* in transaction */
98+ X86_BR_NO_TX = 1 << 14,/* not in transaction */
8499 };
85100
86101 #define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
102+#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
87103
88104 #define X86_BR_ANY \
89105 (X86_BR_CALL |\
@@ -95,6 +111,7 @@ enum { · 5 unmodified lines
95111 X86_BR_JCC |\
96112 X86_BR_JMP |\
97113 X86_BR_IRQ |\
114+ X86_BR_ABORT |\
98115 X86_BR_IND_CALL)
99116
100117 #define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
@@ -270,21 +287,31 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) · 169 unmodified lines
270287
271288 for (i = 0; i < x86_pmu.lbr_nr; i++) {
272289 unsigned long lbr_idx = (tos - i) & mask;
273− u64 from, to, mis = 0, pred = 0;
290+ u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
291+ int skip = 0;
292+ int lbr_flags = lbr_desc[lbr_format];
274293
275294 rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
276295 rdmsrl(x86_pmu.lbr_to + lbr_idx, to);
277296
278− if (lbr_format == LBR_FORMAT_EIP_FLAGS) {
297+ if (lbr_flags & LBR_EIP_FLAGS) {
279298 mis = !!(from & LBR_FROM_FLAG_MISPRED);
280299 pred = !mis;
281− from = (u64)((((s64)from) << 1) >> 1);
300+ skip = 1;
301+ }
302+ if (lbr_flags & LBR_TSX) {
303+ in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
304+ abort = !!(from & LBR_FROM_FLAG_ABORT);
305+ skip = 3;
282306 }
307+ from = (u64)((((s64)from) << skip) >> skip);
283308
284309 cpuc->lbr_entries[i].from = from;
285310 cpuc->lbr_entries[i].to = to;
286311 cpuc->lbr_entries[i].mispred = mis;
287312 cpuc->lbr_entries[i].predicted = pred;
313+ cpuc->lbr_entries[i].in_tx = in_tx;
314+ cpuc->lbr_entries[i].abort = abort;
288315 cpuc->lbr_entries[i].reserved = 0;
289316 }
290317 cpuc->lbr_stack.nr = i;
@@ -310,7 +337,7 @@ void intel_pmu_lbr_read(void) · 19 unmodified lines
310337 * - in case there is no HW filter
311338 * - in case the HW filter has errata or limitations
312339 */
313−static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
340+static void intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
314341 {
315342 u64 br_type = event->attr.branch_sample_type;
316343 int mask = 0;
@@ -318,11 +345,8 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event) · 1 unmodified line
318345 if (br_type & PERF_SAMPLE_BRANCH_USER)
319346 mask |= X86_BR_USER;
320347
321− if (br_type & PERF_SAMPLE_BRANCH_KERNEL) {
322− if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
323− return -EACCES;
348+ if (br_type & PERF_SAMPLE_BRANCH_KERNEL)
324349 mask |= X86_BR_KERNEL;
325− }
326350
327351 /* we ignore BRANCH_HV here */
328352
@@ -337,13 +361,21 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event) · 8 unmodified lines
337361
338362 if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
339363 mask |= X86_BR_IND_CALL;
364+
365+ if (br_type & PERF_SAMPLE_BRANCH_ABORT_TX)
366+ mask |= X86_BR_ABORT;
367+
368+ if (br_type & PERF_SAMPLE_BRANCH_IN_TX)
369+ mask |= X86_BR_IN_TX;
370+
371+ if (br_type & PERF_SAMPLE_BRANCH_NO_TX)
372+ mask |= X86_BR_NO_TX;
373+
340374 /*
341375 * stash actual user request into reg, it may
342376 * be used by fixup code for some CPU
343377 */
344378 event->hw.branch_reg.reg = mask;
345−
346− return 0;
347379 }
348380
349381 /*
@@ -391,9 +423,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event) · 41 unmodified lines
391423 /*
392424 * setup SW LBR filter
393425 */
394− ret = intel_pmu_setup_sw_lbr_filter(event);
395− if (ret)
396− return ret;
426+ intel_pmu_setup_sw_lbr_filter(event);
397427
398428 /*
399429 * setup HW LBR filter, if any
@@ -415,7 +445,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event) · 15 unmodified lines
415445 * decoded (e.g., text page not present), then X86_BR_NONE is
416446 * returned.
417447 */
418−static int branch_type(unsigned long from, unsigned long to)
448+static int branch_type(unsigned long from, unsigned long to, int abort)
419449 {
420450 struct insn insn;
421451 void *addr;
@@ -435,6 +465,9 @@ static int branch_type(unsigned long from, unsigned long to) · 13 unmodified lines
435465 if (from == 0 || to == 0)
436466 return X86_BR_NONE;
437467
468+ if (abort)
469+ return X86_BR_ABORT | to_plm;
470+
438471 if (from_plm == X86_BR_USER) {
439472 /*
440473 * can happen if measuring at the user level only
@@ -581,7 +614,13 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc) · 140 unmodified lines
581614 from = cpuc->lbr_entries[i].from;
582615 to = cpuc->lbr_entries[i].to;
583616
584− type = branch_type(from, to);
617+ type = branch_type(from, to, cpuc->lbr_entries[i].abort);
618+ if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
619+ if (cpuc->lbr_entries[i].in_tx)
620+ type |= X86_BR_IN_TX;
621+ else
622+ type |= X86_BR_NO_TX;
623+ }
585624
586625 /* if type does not correspond, then discard */
587626 if (type == X86_BR_NONE || (br_sel & type) != type) {
arch/x86/kernel/cpu/perf_event_intel_uncore.c+9−7
@@ -536,7 +536,7 @@ __snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *eve · 535 unmodified lines
536536 if (!uncore_box_is_fake(box))
537537 reg1->alloc |= alloc;
538538
539− return 0;
539+ return NULL;
540540 fail:
541541 for (; i >= 0; i--) {
542542 if (alloc & (0x1 << i))
@@ -644,7 +644,7 @@ snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event) · 101 unmodified lines
644644 (!uncore_box_is_fake(box) && reg1->alloc))
645645 return NULL;
646646 again:
647− mask = 0xff << (idx * 8);
647+ mask = 0xffULL << (idx * 8);
648648 raw_spin_lock_irqsave(&er->lock, flags);
649649 if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
650650 !((config1 ^ er->config) & mask)) {
@@ -1923,7 +1923,7 @@ static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modif · 1272 unmodified lines
19231923 {
19241924 struct hw_perf_event *hwc = &event->hw;
19251925 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1926− int idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
1926+ u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
19271927 u64 config = reg1->config;
19281928
19291929 /* get the non-shared control bits and shift them */
@@ -2723,15 +2723,16 @@ static void uncore_put_event_constraint(struct intel_uncore_box *box, struct per · 793 unmodified lines
27232723 static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
27242724 {
27252725 unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
2726− struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX];
2726+ struct event_constraint *c;
27272727 int i, wmin, wmax, ret = 0;
27282728 struct hw_perf_event *hwc;
27292729
27302730 bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
27312731
27322732 for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
2733+ hwc = &box->event_list[i]->hw;
27332734 c = uncore_get_event_constraint(box, box->event_list[i]);
2734− constraints[i] = c;
2735+ hwc->constraint = c;
27352736 wmin = min(wmin, c->weight);
27362737 wmax = max(wmax, c->weight);
27372738 }
@@ -2739,7 +2740,7 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int · 1 unmodified line
27392740 /* fastpath, try to reuse previous register */
27402741 for (i = 0; i < n; i++) {
27412742 hwc = &box->event_list[i]->hw;
2742− c = constraints[i];
2743+ c = hwc->constraint;
27432744
27442745 /* never assigned */
27452746 if (hwc->idx == -1)
@@ -2759,7 +2760,8 @@ static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int · 13 unmodified lines
27592760 }
27602761 /* slow path */
27612762 if (i != n)
2762− ret = perf_assign_events(constraints, n, wmin, wmax, assign);
2763+ ret = perf_assign_events(box->event_list, n,
2764+ wmin, wmax, assign);
27632765
27642766 if (!assign || ret) {
27652767 for (i = 0; i < n; i++)
arch/x86/kernel/cpu/perf_event_intel_uncore.h+2−2
@@ -337,10 +337,10 @@ · 336 unmodified lines
337337 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
338338
339339 #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23))
340−#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n)))
340+#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (11 + 3 * (n)))
341341
342342 #define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24))
343−#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (12 + 3 * (n)))
343+#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (12 + 3 * (n)))
344344
345345 /*
346346 * use the 9~13 bits to select event If the 7th bit is not set,
arch/x86/kernel/nmi.c+34−2
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/kprobes.h>
1515 #include <linux/kdebug.h>
1616 #include <linux/nmi.h>
17+#include <linux/debugfs.h>
1718 #include <linux/delay.h>
1819 #include <linux/hardirq.h>
1920 #include <linux/slab.h>
@@ -29,6 +30,9 @@ · 9 unmodified lines
2930 #include <asm/nmi.h>
3031 #include <asm/x86_init.h>
3132
33+#define CREATE_TRACE_POINTS
34+#include <trace/events/nmi.h>
35+
3236 struct nmi_desc {
3337 spinlock_t lock;
3438 struct list_head head;
@@ -82,6 +86,15 @@ __setup("unknown_nmi_panic", setup_unknown_nmi_panic); · 47 unmodified lines
8286
8387 #define nmi_to_desc(type) (&nmi_desc[type])
8488
89+static u64 nmi_longest_ns = 1 * NSEC_PER_MSEC;
90+static int __init nmi_warning_debugfs(void)
91+{
92+ debugfs_create_u64("nmi_longest_ns", 0644,
93+ arch_debugfs_dir, &nmi_longest_ns);
94+ return 0;
95+}
96+fs_initcall(nmi_warning_debugfs);
97+
8598 static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2b)
8699 {
87100 struct nmi_desc *desc = nmi_to_desc(type);
@@ -96,8 +109,27 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2 · 8 unmodified lines
96109 * can be latched at any given time. Walk the whole list
97110 * to handle those situations.
98111 */
99− list_for_each_entry_rcu(a, &desc->head, list)
100− handled += a->handler(type, regs);
112+ list_for_each_entry_rcu(a, &desc->head, list) {
113+ u64 before, delta, whole_msecs;
114+ int decimal_msecs, thishandled;
115+
116+ before = local_clock();
117+ thishandled = a->handler(type, regs);
118+ handled += thishandled;
119+ delta = local_clock() - before;
120+ trace_nmi_handler(a->handler, (int)delta, thishandled);
121+
122+ if (delta < nmi_longest_ns)
123+ continue;
124+
125+ nmi_longest_ns = delta;
126+ whole_msecs = do_div(delta, (1000 * 1000));
127+ decimal_msecs = do_div(delta, 1000) % 1000;
128+ printk_ratelimited(KERN_INFO
129+ "INFO: NMI handler (%ps) took too long to run: "
130+ "%lld.%03d msecs\n", a->handler, whole_msecs,
131+ decimal_msecs);
132+ }
101133
102134 rcu_read_unlock();
103135
arch/x86/kernel/signal.c+6−10
@@ -43,12 +43,6 @@ · 42 unmodified lines
4343
4444 #include <asm/sigframe.h>
4545
46−#ifdef CONFIG_X86_32
47−# define FIX_EFLAGS (__FIX_EFLAGS | X86_EFLAGS_RF)
48−#else
49−# define FIX_EFLAGS __FIX_EFLAGS
50−#endif
51−
5246 #define COPY(x) do { \
5347 get_user_ex(regs->x, &sc->x); \
5448 } while (0)
@@ -668,15 +662,17 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) · 613 unmodified lines
668662 if (!failed) {
669663 /*
670664 * Clear the direction flag as per the ABI for function entry.
671− */
672− regs->flags &= ~X86_EFLAGS_DF;
673− /*
665+ *
666+ * Clear RF when entering the signal handler, because
667+ * it might disable possible debug exception from the
668+ * signal handler.
669+ *
674670 * Clear TF when entering the signal handler, but
675671 * notify any tracer that was single-stepping it.
676672 * The tracer may want to single-step inside the
677673 * handler too.
678674 */
679− regs->flags &= ~X86_EFLAGS_TF;
675+ regs->flags &= ~(X86_EFLAGS_DF|X86_EFLAGS_RF|X86_EFLAGS_TF);
680676 }
681677 signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP));
682678 }
drivers/iommu/amd_iommu_init.c+131−9
@@ -99,7 +99,7 @@ struct ivhd_header { · 98 unmodified lines
9999 u64 mmio_phys;
100100 u16 pci_seg;
101101 u16 info;
102− u32 reserved;
102+ u32 efr;
103103 } __attribute__((packed));
104104
105105 /*
@@ -154,6 +154,7 @@ bool amd_iommu_iotlb_sup __read_mostly = true; · 48 unmodified lines
154154 u32 amd_iommu_max_pasids __read_mostly = ~0;
155155
156156 bool amd_iommu_v2_present __read_mostly;
157+bool amd_iommu_pc_present __read_mostly;
157158
158159 bool amd_iommu_force_isolation __read_mostly;
159160
@@ -369,23 +370,23 @@ static void iommu_disable(struct amd_iommu *iommu) · 209 unmodified lines
369370 * mapping and unmapping functions for the IOMMU MMIO space. Each AMD IOMMU in
370371 * the system has one.
371372 */
372−static u8 __iomem * __init iommu_map_mmio_space(u64 address)
373+static u8 __iomem * __init iommu_map_mmio_space(u64 address, u64 end)
373374 {
374− if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) {
375− pr_err("AMD-Vi: Can not reserve memory region %llx for mmio\n",
376− address);
375+ if (!request_mem_region(address, end, "amd_iommu")) {
376+ pr_err("AMD-Vi: Can not reserve memory region %llx-%llx for mmio\n",
377+ address, end);
377378 pr_err("AMD-Vi: This is a BIOS bug. Please contact your hardware vendor\n");
378379 return NULL;
379380 }
380381
381− return (u8 __iomem *)ioremap_nocache(address, MMIO_REGION_LENGTH);
382+ return (u8 __iomem *)ioremap_nocache(address, end);
382383 }
383384
384385 static void __init iommu_unmap_mmio_space(struct amd_iommu *iommu)
385386 {
386387 if (iommu->mmio_base)
387388 iounmap(iommu->mmio_base);
388− release_mem_region(iommu->mmio_phys, MMIO_REGION_LENGTH);
389+ release_mem_region(iommu->mmio_phys, iommu->mmio_phys_end);
389390 }
390391
391392 /****************************************************************************
@@ -1085,7 +1086,18 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) · 693 unmodified lines
10851086 iommu->cap_ptr = h->cap_ptr;
10861087 iommu->pci_seg = h->pci_seg;
10871088 iommu->mmio_phys = h->mmio_phys;
1088− iommu->mmio_base = iommu_map_mmio_space(h->mmio_phys);
1089+
1090+ /* Check if IVHD EFR contains proper max banks/counters */
1091+ if ((h->efr != 0) &&
1092+ ((h->efr & (0xF << 13)) != 0) &&
1093+ ((h->efr & (0x3F << 17)) != 0)) {
1094+ iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
1095+ } else {
1096+ iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
1097+ }
1098+
1099+ iommu->mmio_base = iommu_map_mmio_space(iommu->mmio_phys,
1100+ iommu->mmio_phys_end);
10891101 if (!iommu->mmio_base)
10901102 return -ENOMEM;
10911103
@@ -1160,6 +1172,33 @@ static int __init init_iommu_all(struct acpi_table_header *table) · 68 unmodified lines
11601172 return 0;
11611173 }
11621174
1175+
1176+static void init_iommu_perf_ctr(struct amd_iommu *iommu)
1177+{
1178+ u64 val = 0xabcd, val2 = 0;
1179+
1180+ if (!iommu_feature(iommu, FEATURE_PC))
1181+ return;
1182+
1183+ amd_iommu_pc_present = true;
1184+
1185+ /* Check if the performance counters can be written to */
1186+ if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) ||
1187+ (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) ||
1188+ (val != val2)) {
1189+ pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n");
1190+ amd_iommu_pc_present = false;
1191+ return;
1192+ }
1193+
1194+ pr_info("AMD-Vi: IOMMU performance counters supported\n");
1195+
1196+ val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET);
1197+ iommu->max_banks = (u8) ((val >> 12) & 0x3f);
1198+ iommu->max_counters = (u8) ((val >> 7) & 0xf);
1199+}
1200+
1201+
11631202 static int iommu_init_pci(struct amd_iommu *iommu)
11641203 {
11651204 int cap_ptr = iommu->cap_ptr;
@@ -1226,6 +1265,8 @@ static int iommu_init_pci(struct amd_iommu *iommu) · 60 unmodified lines
12261265 if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
12271266 amd_iommu_np_cache = true;
12281267
1268+ init_iommu_perf_ctr(iommu);
1269+
12291270 if (is_rd890_iommu(iommu->dev)) {
12301271 int i, j;
12311272
@@ -1278,7 +1319,7 @@ static void print_iommu_info(void) · 46 unmodified lines
12781319 if (iommu_feature(iommu, (1ULL << i)))
12791320 pr_cont(" %s", feat_str[i]);
12801321 }
1281− pr_cont("\n");
1322+ pr_cont("\n");
12821323 }
12831324 }
12841325 if (irq_remapping_enabled)
@@ -2232,3 +2273,84 @@ bool amd_iommu_v2_supported(void) · 947 unmodified lines
22322273 return amd_iommu_v2_present;
22332274 }
22342275 EXPORT_SYMBOL(amd_iommu_v2_supported);
2276+
2277+/****************************************************************************
2278+ *
2279+ * IOMMU EFR Performance Counter support functionality. This code allows
2280+ * access to the IOMMU PC functionality.
2281+ *
2282+ ****************************************************************************/
2283+
2284+u8 amd_iommu_pc_get_max_banks(u16 devid)
2285+{
2286+ struct amd_iommu *iommu;
2287+ u8 ret = 0;
2288+
2289+ /* locate the iommu governing the devid */
2290+ iommu = amd_iommu_rlookup_table[devid];
2291+ if (iommu)
2292+ ret = iommu->max_banks;
2293+
2294+ return ret;
2295+}
2296+EXPORT_SYMBOL(amd_iommu_pc_get_max_banks);
2297+
2298+bool amd_iommu_pc_supported(void)
2299+{
2300+ return amd_iommu_pc_present;
2301+}
2302+EXPORT_SYMBOL(amd_iommu_pc_supported);
2303+
2304+u8 amd_iommu_pc_get_max_counters(u16 devid)
2305+{
2306+ struct amd_iommu *iommu;
2307+ u8 ret = 0;
2308+
2309+ /* locate the iommu governing the devid */
2310+ iommu = amd_iommu_rlookup_table[devid];
2311+ if (iommu)
2312+ ret = iommu->max_counters;
2313+
2314+ return ret;
2315+}
2316+EXPORT_SYMBOL(amd_iommu_pc_get_max_counters);
2317+
2318+int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
2319+ u64 *value, bool is_write)
2320+{
2321+ struct amd_iommu *iommu;
2322+ u32 offset;
2323+ u32 max_offset_lim;
2324+
2325+ /* Make sure the IOMMU PC resource is available */
2326+ if (!amd_iommu_pc_present)
2327+ return -ENODEV;
2328+
2329+ /* Locate the iommu associated with the device ID */
2330+ iommu = amd_iommu_rlookup_table[devid];
2331+
2332+ /* Check for valid iommu and pc register indexing */
2333+ if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7)))
2334+ return -ENODEV;
2335+
2336+ offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn);
2337+
2338+ /* Limit the offset to the hw defined mmio region aperture */
2339+ max_offset_lim = (u32)(((0x40|iommu->max_banks) << 12) |
2340+ (iommu->max_counters << 8) | 0x28);
2341+ if ((offset < MMIO_CNTR_REG_OFFSET) ||
2342+ (offset > max_offset_lim))
2343+ return -EINVAL;
2344+
2345+ if (is_write) {
2346+ writel((u32)*value, iommu->mmio_base + offset);
2347+ writel((*value >> 32), iommu->mmio_base + offset + 4);
2348+ } else {
2349+ *value = readl(iommu->mmio_base + offset + 4);
2350+ *value <<= 32;
2351+ *value = readl(iommu->mmio_base + offset);
2352+ }
2353+
2354+ return 0;
2355+}
2356+EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val);
drivers/iommu/amd_iommu_proto.h+7−0
@@ -56,6 +56,13 @@ extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, · 55 unmodified lines
5656 extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid);
5757 extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev);
5858
59+/* IOMMU Performance Counter functions */
60+extern bool amd_iommu_pc_supported(void);
61+extern u8 amd_iommu_pc_get_max_banks(u16 devid);
62+extern u8 amd_iommu_pc_get_max_counters(u16 devid);
63+extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
64+ u64 *value, bool is_write);
65+
5966 #define PPR_SUCCESS 0x0
6067 #define PPR_INVALID 0x1
6168 #define PPR_FAILURE 0xf
drivers/iommu/amd_iommu_types.h+12−3
@@ -38,9 +38,6 @@ · 37 unmodified lines
3838 #define ALIAS_TABLE_ENTRY_SIZE 2
3939 #define RLOOKUP_TABLE_ENTRY_SIZE (sizeof(void *))
4040
41−/* Length of the MMIO region for the AMD IOMMU */
42−#define MMIO_REGION_LENGTH 0x4000
43−
4441 /* Capability offsets used by the driver */
4542 #define MMIO_CAP_HDR_OFFSET 0x00
4643 #define MMIO_RANGE_OFFSET 0x0c
@@ -78,6 +75,10 @@ · 31 unmodified lines
7875 #define MMIO_STATUS_OFFSET 0x2020
7976 #define MMIO_PPR_HEAD_OFFSET 0x2030
8077 #define MMIO_PPR_TAIL_OFFSET 0x2038
78+#define MMIO_CNTR_CONF_OFFSET 0x4000
79+#define MMIO_CNTR_REG_OFFSET 0x40000
80+#define MMIO_REG_END_OFFSET 0x80000
81+
8182
8283
8384 /* Extended Feature Bits */
@@ -507,6 +508,10 @@ struct amd_iommu { · 423 unmodified lines
507508
508509 /* physical address of MMIO space */
509510 u64 mmio_phys;
511+
512+ /* physical end address of MMIO space */
513+ u64 mmio_phys_end;
514+
510515 /* virtual address of MMIO space */
511516 u8 __iomem *mmio_base;
512517
@@ -584,6 +589,10 @@ struct amd_iommu { · 71 unmodified lines
584589
585590 /* The l2 indirect registers */
586591 u32 stored_l2[0x83];
592+
593+ /* The maximum PC banks and counters/bank (PCSup=1) */
594+ u8 max_banks;
595+ u8 max_counters;
587596 };
588597
589598 struct devid_map {
include/linux/perf_event.h+24−4
@@ -73,13 +73,18 @@ struct perf_raw_record { · 72 unmodified lines
7373 *
7474 * support for mispred, predicted is optional. In case it
7575 * is not supported mispred = predicted = 0.
76+ *
77+ * in_tx: running in a hardware transaction
78+ * abort: aborting a hardware transaction
7679 */
7780 struct perf_branch_entry {
7881 __u64 from;
7982 __u64 to;
8083 __u64 mispred:1, /* target mispredicted */
8184 predicted:1,/* target predicted */
82− reserved:62;
85+ in_tx:1, /* in transaction */
86+ abort:1, /* transaction abort */
87+ reserved:60;
8388 };
8489
8590 /*
@@ -113,6 +118,8 @@ struct hw_perf_event_extra { · 27 unmodified lines
113118 int idx; /* index in shared_regs->regs[] */
114119 };
115120
121+struct event_constraint;
122+
116123 /**
117124 * struct hw_perf_event - performance event hardware details:
118125 */
@@ -131,6 +138,8 @@ struct hw_perf_event { · 12 unmodified lines
131138
132139 struct hw_perf_event_extra extra_reg;
133140 struct hw_perf_event_extra branch_reg;
141+
142+ struct event_constraint *constraint;
134143 };
135144 struct { /* software */
136145 struct hrtimer hrtimer;
@@ -188,12 +197,13 @@ struct pmu { · 51 unmodified lines
188197
189198 struct device *dev;
190199 const struct attribute_group **attr_groups;
191− char *name;
200+ const char *name;
192201 int type;
193202
194203 int * __percpu pmu_disable_count;
195204 struct perf_cpu_context * __percpu pmu_cpu_context;
196205 int task_ctx_nr;
206+ int hrtimer_interval_ms;
197207
198208 /*
199209 * Fully disable/enable this PMU, can be used to protect from the PMI
@@ -500,8 +510,9 @@ struct perf_cpu_context { · 300 unmodified lines
500510 struct perf_event_context *task_ctx;
501511 int active_oncpu;
502512 int exclusive;
513+ struct hrtimer hrtimer;
514+ ktime_t hrtimer_interval;
503515 struct list_head rotation_list;
504− int jiffies_interval;
505516 struct pmu *unique_pmu;
506517 struct perf_cgroup *cgrp;
507518 };
@@ -517,7 +528,7 @@ struct perf_output_handle { · 9 unmodified lines
517528
518529 #ifdef CONFIG_PERF_EVENTS
519530
520−extern int perf_pmu_register(struct pmu *pmu, char *name, int type);
531+extern int perf_pmu_register(struct pmu *pmu, const char *name, int type);
521532 extern void perf_pmu_unregister(struct pmu *pmu);
522533
523534 extern int perf_num_counters(void);
@@ -695,10 +706,17 @@ static inline void perf_callchain_store(struct perf_callchain_entry *entry, u64 · 171 unmodified lines
695706 extern int sysctl_perf_event_paranoid;
696707 extern int sysctl_perf_event_mlock;
697708 extern int sysctl_perf_event_sample_rate;
709+extern int sysctl_perf_cpu_time_max_percent;
710+
711+extern void perf_sample_event_took(u64 sample_len_ns);
698712
699713 extern int perf_proc_update_handler(struct ctl_table *table, int write,
700714 void __user *buffer, size_t *lenp,
701715 loff_t *ppos);
716+extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
717+ void __user *buffer, size_t *lenp,
718+ loff_t *ppos);
719+
702720
703721 static inline bool perf_paranoid_tracepoint_raw(void)
704722 {
@@ -742,6 +760,7 @@ extern unsigned int perf_output_skip(struct perf_output_handle *handle, · 37 unmodified lines
742760 unsigned int len);
743761 extern int perf_swevent_get_recursion_context(void);
744762 extern void perf_swevent_put_recursion_context(int rctx);
763+extern u64 perf_swevent_set_period(struct perf_event *event);
745764 extern void perf_event_enable(struct perf_event *event);
746765 extern void perf_event_disable(struct perf_event *event);
747766 extern int __perf_event_disable(void *info);
@@ -781,6 +800,7 @@ static inline void perf_event_fork(struct task_struct *tsk) { } · 33 unmodified lines
781800 static inline void perf_event_init(void) { }
782801 static inline int perf_swevent_get_recursion_context(void) { return -1; }
783802 static inline void perf_swevent_put_recursion_context(int rctx) { }
803+static inline u64 perf_swevent_set_period(struct perf_event *event) { return 0; }
784804 static inline void perf_event_enable(struct perf_event *event) { }
785805 static inline void perf_event_disable(struct perf_event *event) { }
786806 static inline int __perf_event_disable(void *info) { return -1; }
include/trace/events/nmi.h+37−0
@@ -0,0 +1,37 @@
1+#undef TRACE_SYSTEM
2+#define TRACE_SYSTEM nmi
3+
4+#if !defined(_TRACE_NMI_H) || defined(TRACE_HEADER_MULTI_READ)
5+#define _TRACE_NMI_H
6+
7+#include <linux/ktime.h>
8+#include <linux/tracepoint.h>
9+
10+TRACE_EVENT(nmi_handler,
11+
12+ TP_PROTO(void *handler, s64 delta_ns, int handled),
13+
14+ TP_ARGS(handler, delta_ns, handled),
15+
16+ TP_STRUCT__entry(
17+ __field( void *, handler )
18+ __field( s64, delta_ns)
19+ __field( int, handled )
20+ ),
21+
22+ TP_fast_assign(
23+ __entry->handler = handler;
24+ __entry->delta_ns = delta_ns;
25+ __entry->handled = handled;
26+ ),
27+
28+ TP_printk("%ps() delta_ns: %lld handled: %d",
29+ __entry->handler,
30+ __entry->delta_ns,
31+ __entry->handled)
32+);
33+
34+#endif /* _TRACE_NMI_H */
35+
36+/* This part ust be outside protection */
37+#include <trace/define_trace.h>
include/uapi/linux/perf_event.h+4−1
@@ -157,8 +157,11 @@ enum perf_branch_sample_type { · 156 unmodified lines
157157 PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */
158158 PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */
159159 PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */
160+ PERF_SAMPLE_BRANCH_ABORT_TX = 1U << 7, /* transaction aborts */
161+ PERF_SAMPLE_BRANCH_IN_TX = 1U << 8, /* in transaction */
162+ PERF_SAMPLE_BRANCH_NO_TX = 1U << 9, /* not in transaction */
160163
161− PERF_SAMPLE_BRANCH_MAX = 1U << 7, /* non-ABI */
164+ PERF_SAMPLE_BRANCH_MAX = 1U << 10, /* non-ABI */
162165 };
163166
164167 #define PERF_SAMPLE_BRANCH_PLM_ALL \
init/main.c+1−1
@@ -542,7 +542,6 @@ asmlinkage void __init start_kernel(void) · 541 unmodified lines
542542 if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n"))
543543 local_irq_disable();
544544 idr_init_cache();
545− perf_event_init();
546545 rcu_init();
547546 tick_nohz_init();
548547 radix_tree_init();
@@ -555,6 +554,7 @@ asmlinkage void __init start_kernel(void) · 6 unmodified lines
555554 softirq_init();
556555 timekeeping_init();
557556 time_init();
557+ perf_event_init();
558558 profile_init();
559559 call_function_init();
560560 WARN(!irqs_disabled(), "Interrupts were enabled early\n");
kernel/events/core.c+257−21
@@ -165,10 +165,28 @@ int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' · 164 unmodified lines
165165 /*
166166 * max perf event sample rate
167167 */
168−#define DEFAULT_MAX_SAMPLE_RATE 100000
169−int sysctl_perf_event_sample_rate __read_mostly = DEFAULT_MAX_SAMPLE_RATE;
170−static int max_samples_per_tick __read_mostly =
171− DIV_ROUND_UP(DEFAULT_MAX_SAMPLE_RATE, HZ);
168+#define DEFAULT_MAX_SAMPLE_RATE 100000
169+#define DEFAULT_SAMPLE_PERIOD_NS (NSEC_PER_SEC / DEFAULT_MAX_SAMPLE_RATE)
170+#define DEFAULT_CPU_TIME_MAX_PERCENT 25
171+
172+int sysctl_perf_event_sample_rate __read_mostly = DEFAULT_MAX_SAMPLE_RATE;
173+
174+static int max_samples_per_tick __read_mostly = DIV_ROUND_UP(DEFAULT_MAX_SAMPLE_RATE, HZ);
175+static int perf_sample_period_ns __read_mostly = DEFAULT_SAMPLE_PERIOD_NS;
176+
177+static atomic_t perf_sample_allowed_ns __read_mostly =
178+ ATOMIC_INIT( DEFAULT_SAMPLE_PERIOD_NS * DEFAULT_CPU_TIME_MAX_PERCENT / 100);
179+
180+void update_perf_cpu_limits(void)
181+{
182+ u64 tmp = perf_sample_period_ns;
183+
184+ tmp *= sysctl_perf_cpu_time_max_percent;
185+ tmp = do_div(tmp, 100);
186+ atomic_set(&perf_sample_allowed_ns, tmp);
187+}
188+
189+static int perf_rotate_context(struct perf_cpu_context *cpuctx);
172190
173191 int perf_proc_update_handler(struct ctl_table *table, int write,
174192 void __user *buffer, size_t *lenp,
@@ -180,10 +198,78 @@ int perf_proc_update_handler(struct ctl_table *table, int write, · 5 unmodified lines
180198 return ret;
181199
182200 max_samples_per_tick = DIV_ROUND_UP(sysctl_perf_event_sample_rate, HZ);
201+ perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
202+ update_perf_cpu_limits();
183203
184204 return 0;
185205 }
186206
207+int sysctl_perf_cpu_time_max_percent __read_mostly = DEFAULT_CPU_TIME_MAX_PERCENT;
208+
209+int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
210+ void __user *buffer, size_t *lenp,
211+ loff_t *ppos)
212+{
213+ int ret = proc_dointvec(table, write, buffer, lenp, ppos);
214+
215+ if (ret || !write)
216+ return ret;
217+
218+ update_perf_cpu_limits();
219+
220+ return 0;
221+}
222+
223+/*
224+ * perf samples are done in some very critical code paths (NMIs).
225+ * If they take too much CPU time, the system can lock up and not
226+ * get any real work done. This will drop the sample rate when
227+ * we detect that events are taking too long.
228+ */
229+#define NR_ACCUMULATED_SAMPLES 128
230+DEFINE_PER_CPU(u64, running_sample_length);
231+
232+void perf_sample_event_took(u64 sample_len_ns)
233+{
234+ u64 avg_local_sample_len;
235+ u64 local_samples_len = __get_cpu_var(running_sample_length);
236+
237+ if (atomic_read(&perf_sample_allowed_ns) == 0)
238+ return;
239+
240+ /* decay the counter by 1 average sample */
241+ local_samples_len = __get_cpu_var(running_sample_length);
242+ local_samples_len -= local_samples_len/NR_ACCUMULATED_SAMPLES;
243+ local_samples_len += sample_len_ns;
244+ __get_cpu_var(running_sample_length) = local_samples_len;
245+
246+ /*
247+ * note: this will be biased artifically low until we have
248+ * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us
249+ * from having to maintain a count.
250+ */
251+ avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES;
252+
253+ if (avg_local_sample_len <= atomic_read(&perf_sample_allowed_ns))
254+ return;
255+
256+ if (max_samples_per_tick <= 1)
257+ return;
258+
259+ max_samples_per_tick = DIV_ROUND_UP(max_samples_per_tick, 2);
260+ sysctl_perf_event_sample_rate = max_samples_per_tick * HZ;
261+ perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
262+
263+ printk_ratelimited(KERN_WARNING
264+ "perf samples too long (%lld > %d), lowering "
265+ "kernel.perf_event_max_sample_rate to %d\n",
266+ avg_local_sample_len,
267+ atomic_read(&perf_sample_allowed_ns),
268+ sysctl_perf_event_sample_rate);
269+
270+ update_perf_cpu_limits();
271+}
272+
187273 static atomic64_t perf_event_id;
188274
189275 static void cpu_ctx_sched_out(struct perf_cpu_context *cpuctx,
@@ -655,6 +741,106 @@ perf_cgroup_mark_enabled(struct perf_event *event, · 465 unmodified lines
655741 }
656742 #endif
657743
744+/*
745+ * set default to be dependent on timer tick just
746+ * like original code
747+ */
748+#define PERF_CPU_HRTIMER (1000 / HZ)
749+/*
750+ * function must be called with interrupts disbled
751+ */
752+static enum hrtimer_restart perf_cpu_hrtimer_handler(struct hrtimer *hr)
753+{
754+ struct perf_cpu_context *cpuctx;
755+ enum hrtimer_restart ret = HRTIMER_NORESTART;
756+ int rotations = 0;
757+
758+ WARN_ON(!irqs_disabled());
759+
760+ cpuctx = container_of(hr, struct perf_cpu_context, hrtimer);
761+
762+ rotations = perf_rotate_context(cpuctx);
763+
764+ /*
765+ * arm timer if needed
766+ */
767+ if (rotations) {
768+ hrtimer_forward_now(hr, cpuctx->hrtimer_interval);
769+ ret = HRTIMER_RESTART;
770+ }
771+
772+ return ret;
773+}
774+
775+/* CPU is going down */
776+void perf_cpu_hrtimer_cancel(int cpu)
777+{
778+ struct perf_cpu_context *cpuctx;
779+ struct pmu *pmu;
780+ unsigned long flags;
781+
782+ if (WARN_ON(cpu != smp_processor_id()))
783+ return;
784+
785+ local_irq_save(flags);
786+
787+ rcu_read_lock();
788+
789+ list_for_each_entry_rcu(pmu, &pmus, entry) {
790+ cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
791+
792+ if (pmu->task_ctx_nr == perf_sw_context)
793+ continue;
794+
795+ hrtimer_cancel(&cpuctx->hrtimer);
796+ }
797+
798+ rcu_read_unlock();
799+
800+ local_irq_restore(flags);
801+}
802+
803+static void __perf_cpu_hrtimer_init(struct perf_cpu_context *cpuctx, int cpu)
804+{
805+ struct hrtimer *hr = &cpuctx->hrtimer;
806+ struct pmu *pmu = cpuctx->ctx.pmu;
807+ int timer;
808+
809+ /* no multiplexing needed for SW PMU */
810+ if (pmu->task_ctx_nr == perf_sw_context)
811+ return;
812+
813+ /*
814+ * check default is sane, if not set then force to
815+ * default interval (1/tick)
816+ */
817+ timer = pmu->hrtimer_interval_ms;
818+ if (timer < 1)
819+ timer = pmu->hrtimer_interval_ms = PERF_CPU_HRTIMER;
820+
821+ cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer);
822+
823+ hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
824+ hr->function = perf_cpu_hrtimer_handler;
825+}
826+
827+static void perf_cpu_hrtimer_restart(struct perf_cpu_context *cpuctx)
828+{
829+ struct hrtimer *hr = &cpuctx->hrtimer;
830+ struct pmu *pmu = cpuctx->ctx.pmu;
831+
832+ /* not for SW PMU */
833+ if (pmu->task_ctx_nr == perf_sw_context)
834+ return;
835+
836+ if (hrtimer_active(hr))
837+ return;
838+
839+ if (!hrtimer_callback_running(hr))
840+ __hrtimer_start_range_ns(hr, cpuctx->hrtimer_interval,
841+ 0, HRTIMER_MODE_REL_PINNED, 0);
842+}
843+
658844 void perf_pmu_disable(struct pmu *pmu)
659845 {
660846 int *count = this_cpu_ptr(pmu->pmu_disable_count);
@@ -1503,6 +1689,7 @@ group_sched_in(struct perf_event *group_event, · 842 unmodified lines
15031689
15041690 if (event_sched_in(group_event, cpuctx, ctx)) {
15051691 pmu->cancel_txn(pmu);
1692+ perf_cpu_hrtimer_restart(cpuctx);
15061693 return -EAGAIN;
15071694 }
15081695
@@ -1549,6 +1736,8 @@ group_error: · 40 unmodified lines
15491736
15501737 pmu->cancel_txn(pmu);
15511738
1739+ perf_cpu_hrtimer_restart(cpuctx);
1740+
15521741 return -EAGAIN;
15531742 }
15541743
@@ -1804,8 +1993,10 @@ static int __perf_event_enable(void *info) · 249 unmodified lines
18041993 * If this event can't go on and it's part of a
18051994 * group, then the whole group has to come off.
18061995 */
1807− if (leader != event)
1996+ if (leader != event) {
18081997 group_sched_out(leader, cpuctx, ctx);
1998+ perf_cpu_hrtimer_restart(cpuctx);
1999+ }
18092000 if (leader->attr.pinned) {
18102001 update_group_times(leader);
18112002 leader->state = PERF_EVENT_STATE_ERROR;
@@ -2552,7 +2743,7 @@ static void rotate_ctx(struct perf_event_context *ctx) · 740 unmodified lines
25522743 * because they're strictly cpu affine and rotate_start is called with IRQs
25532744 * disabled, while rotate_context is called from IRQ context.
25542745 */
2555−static void perf_rotate_context(struct perf_cpu_context *cpuctx)
2746+static int perf_rotate_context(struct perf_cpu_context *cpuctx)
25562747 {
25572748 struct perf_event_context *ctx = NULL;
25582749 int rotate = 0, remove = 1;
@@ -2591,6 +2782,8 @@ static void perf_rotate_context(struct perf_cpu_context *cpuctx) · 32 unmodified lines
25912782 done:
25922783 if (remove)
25932784 list_del_init(&cpuctx->rotation_list);
2785+
2786+ return rotate;
25942787 }
25952788
25962789 #ifdef CONFIG_NO_HZ_FULL
@@ -2622,10 +2815,6 @@ void perf_event_task_tick(void) · 25 unmodified lines
26222815 ctx = cpuctx->task_ctx;
26232816 if (ctx)
26242817 perf_adjust_freq_unthr_context(ctx, throttled);
2625−
2626− if (cpuctx->jiffies_interval == 1 ||
2627− !(jiffies % cpuctx->jiffies_interval))
2628− perf_rotate_context(cpuctx);
26292818 }
26302819 }
26312820
@@ -5036,7 +5225,7 @@ static DEFINE_PER_CPU(struct swevent_htable, swevent_htable); · 2404 unmodified lines
50365225 * sign as trigger.
50375226 */
50385227
5039−static u64 perf_swevent_set_period(struct perf_event *event)
5228+u64 perf_swevent_set_period(struct perf_event *event)
50405229 {
50415230 struct hw_perf_event *hwc = &event->hw;
50425231 u64 period = hwc->last_period;
@@ -5979,9 +6168,56 @@ type_show(struct device *dev, struct device_attribute *attr, char *page) · 936 unmodified lines
59796168 return snprintf(page, PAGE_SIZE-1, "%d\n", pmu->type);
59806169 }
59816170
6171+static ssize_t
6172+perf_event_mux_interval_ms_show(struct device *dev,
6173+ struct device_attribute *attr,
6174+ char *page)
6175+{
6176+ struct pmu *pmu = dev_get_drvdata(dev);
6177+
6178+ return snprintf(page, PAGE_SIZE-1, "%d\n", pmu->hrtimer_interval_ms);
6179+}
6180+
6181+static ssize_t
6182+perf_event_mux_interval_ms_store(struct device *dev,
6183+ struct device_attribute *attr,
6184+ const char *buf, size_t count)
6185+{
6186+ struct pmu *pmu = dev_get_drvdata(dev);
6187+ int timer, cpu, ret;
6188+
6189+ ret = kstrtoint(buf, 0, &timer);
6190+ if (ret)
6191+ return ret;
6192+
6193+ if (timer < 1)
6194+ return -EINVAL;
6195+
6196+ /* same value, noting to do */
6197+ if (timer == pmu->hrtimer_interval_ms)
6198+ return count;
6199+
6200+ pmu->hrtimer_interval_ms = timer;
6201+
6202+ /* update all cpuctx for this PMU */
6203+ for_each_possible_cpu(cpu) {
6204+ struct perf_cpu_context *cpuctx;
6205+ cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
6206+ cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer);
6207+
6208+ if (hrtimer_active(&cpuctx->hrtimer))
6209+ hrtimer_forward_now(&cpuctx->hrtimer, cpuctx->hrtimer_interval);
6210+ }
6211+
6212+ return count;
6213+}
6214+
6215+#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
6216+
59826217 static struct device_attribute pmu_dev_attrs[] = {
5983− __ATTR_RO(type),
5984− __ATTR_NULL,
6218+ __ATTR_RO(type),
6219+ __ATTR_RW(perf_event_mux_interval_ms),
6220+ __ATTR_NULL,
59856221 };
59866222
59876223 static int pmu_bus_running;
@@ -6027,7 +6263,7 @@ free_dev: · 39 unmodified lines
60276263 static struct lock_class_key cpuctx_mutex;
60286264 static struct lock_class_key cpuctx_lock;
60296265
6030−int perf_pmu_register(struct pmu *pmu, char *name, int type)
6266+int perf_pmu_register(struct pmu *pmu, const char *name, int type)
60316267 {
60326268 int cpu, ret;
60336269
@@ -6076,7 +6312,9 @@ skip_type: · 42 unmodified lines
60766312 lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock);
60776313 cpuctx->ctx.type = cpu_context;
60786314 cpuctx->ctx.pmu = pmu;
6079− cpuctx->jiffies_interval = 1;
6315+
6316+ __perf_cpu_hrtimer_init(cpuctx, cpu);
6317+
60806318 INIT_LIST_HEAD(&cpuctx->rotation_list);
60816319 cpuctx->unique_pmu = pmu;
60826320 }
@@ -6402,11 +6640,6 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, · 319 unmodified lines
64026640 if (!(mask & ~PERF_SAMPLE_BRANCH_PLM_ALL))
64036641 return -EINVAL;
64046642
6405− /* kernel level capture: check permissions */
6406− if ((mask & PERF_SAMPLE_BRANCH_PERM_PLM)
6407− && perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
6408− return -EACCES;
6409−
64106643 /* propagate priv level, when not set for branch */
64116644 if (!(mask & PERF_SAMPLE_BRANCH_PLM_ALL)) {
64126645
@@ -6424,6 +6657,10 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, · 11 unmodified lines
64246657 */
64256658 attr->branch_sample_type = mask;
64266659 }
6660+ /* privileged levels capture (kernel, hv): check permissions */
6661+ if ((mask & PERF_SAMPLE_BRANCH_PERM_PLM)
6662+ && perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
6663+ return -EACCES;
64276664 }
64286665
64296666 if (attr->sample_type & PERF_SAMPLE_REGS_USER) {
@@ -7476,7 +7713,6 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) · 1046 unmodified lines
74767713 case CPU_DOWN_PREPARE:
74777714 perf_event_exit_cpu(cpu);
74787715 break;
7479−
74807716 default:
74817717 break;
74827718 }
kernel/events/hw_breakpoint.c+83−108
@@ -46,23 +46,26 @@ · 45 unmodified lines
4646 #include <linux/smp.h>
4747
4848 #include <linux/hw_breakpoint.h>
49−
50−
5149 /*
5250 * Constraints data
5351 */
52+struct bp_cpuinfo {
53+ /* Number of pinned cpu breakpoints in a cpu */
54+ unsigned int cpu_pinned;
55+ /* tsk_pinned[n] is the number of tasks having n+1 breakpoints */
56+ unsigned int *tsk_pinned;
57+ /* Number of non-pinned cpu/task breakpoints in a cpu */
58+ unsigned int flexible; /* XXX: placeholder, see fetch_this_slot() */
59+};
5460
55−/* Number of pinned cpu breakpoints in a cpu */
56−static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned[TYPE_MAX]);
57−
58−/* Number of pinned task breakpoints in a cpu */
59−static DEFINE_PER_CPU(unsigned int *, nr_task_bp_pinned[TYPE_MAX]);
60−
61−/* Number of non-pinned cpu/task breakpoints in a cpu */
62−static DEFINE_PER_CPU(unsigned int, nr_bp_flexible[TYPE_MAX]);
63−
61+static DEFINE_PER_CPU(struct bp_cpuinfo, bp_cpuinfo[TYPE_MAX]);
6462 static int nr_slots[TYPE_MAX];
6563
64+static struct bp_cpuinfo *get_bp_info(int cpu, enum bp_type_idx type)
65+{
66+ return per_cpu_ptr(bp_cpuinfo + type, cpu);
67+}
68+
6669 /* Keep track of the breakpoints attached to tasks */
6770 static LIST_HEAD(bp_task_head);
6871
@@ -96,8 +99,8 @@ static inline enum bp_type_idx find_slot_idx(struct perf_event *bp) · 27 unmodified lines
9699 */
97100 static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
98101 {
102+ unsigned int *tsk_pinned = get_bp_info(cpu, type)->tsk_pinned;
99103 int i;
100− unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
101104
102105 for (i = nr_slots[type] - 1; i >= 0; i--) {
103106 if (tsk_pinned[i] > 0)
@@ -127,6 +130,13 @@ static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) · 23 unmodified lines
127130 return count;
128131 }
129132
133+static const struct cpumask *cpumask_of_bp(struct perf_event *bp)
134+{
135+ if (bp->cpu >= 0)
136+ return cpumask_of(bp->cpu);
137+ return cpu_possible_mask;
138+}
139+
130140 /*
131141 * Report the number of pinned/un-pinned breakpoints we have in
132142 * a given cpu (cpu > -1) or in all of them (cpu = -1).
@@ -135,25 +145,15 @@ static void · 2 unmodified lines
135145 fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
136146 enum bp_type_idx type)
137147 {
138− int cpu = bp->cpu;
139− struct task_struct *tsk = bp->hw.bp_target;
140−
141− if (cpu >= 0) {
142− slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu);
143− if (!tsk)
144− slots->pinned += max_task_bp_pinned(cpu, type);
145− else
146− slots->pinned += task_bp_pinned(cpu, bp, type);
147− slots->flexible = per_cpu(nr_bp_flexible[type], cpu);
148−
149− return;
150− }
148+ const struct cpumask *cpumask = cpumask_of_bp(bp);
149+ int cpu;
151150
152− for_each_possible_cpu(cpu) {
153− unsigned int nr;
151+ for_each_cpu(cpu, cpumask) {
152+ struct bp_cpuinfo *info = get_bp_info(cpu, type);
153+ int nr;
154154
155− nr = per_cpu(nr_cpu_bp_pinned[type], cpu);
156− if (!tsk)
155+ nr = info->cpu_pinned;
156+ if (!bp->hw.bp_target)
157157 nr += max_task_bp_pinned(cpu, type);
158158 else
159159 nr += task_bp_pinned(cpu, bp, type);
@@ -161,8 +161,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, · 1 unmodified line
161161 if (nr > slots->pinned)
162162 slots->pinned = nr;
163163
164− nr = per_cpu(nr_bp_flexible[type], cpu);
165−
164+ nr = info->flexible;
166165 if (nr > slots->flexible)
167166 slots->flexible = nr;
168167 }
@@ -182,29 +181,19 @@ fetch_this_slot(struct bp_busy_slots *slots, int weight) · 13 unmodified lines
182181 /*
183182 * Add a pinned breakpoint for the given task in our constraint table
184183 */
185−static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable,
184+static void toggle_bp_task_slot(struct perf_event *bp, int cpu,
186185 enum bp_type_idx type, int weight)
187186 {
188− unsigned int *tsk_pinned;
189− int old_count = 0;
190− int old_idx = 0;
191− int idx = 0;
192−
193− old_count = task_bp_pinned(cpu, bp, type);
194− old_idx = old_count - 1;
195− idx = old_idx + weight;
196−
197− /* tsk_pinned[n] is the number of tasks having n breakpoints */
198− tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
199− if (enable) {
200− tsk_pinned[idx]++;
201− if (old_count > 0)
202− tsk_pinned[old_idx]--;
203− } else {
204− tsk_pinned[idx]--;
205− if (old_count > 0)
206− tsk_pinned[old_idx]++;
207− }
187+ unsigned int *tsk_pinned = get_bp_info(cpu, type)->tsk_pinned;
188+ int old_idx, new_idx;
189+
190+ old_idx = task_bp_pinned(cpu, bp, type) - 1;
191+ new_idx = old_idx + weight;
192+
193+ if (old_idx >= 0)
194+ tsk_pinned[old_idx]--;
195+ if (new_idx >= 0)
196+ tsk_pinned[new_idx]++;
208197 }
209198
210199 /*
@@ -214,33 +203,26 @@ static void · 3 unmodified lines
214203 toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
215204 int weight)
216205 {
217− int cpu = bp->cpu;
218− struct task_struct *tsk = bp->hw.bp_target;
206+ const struct cpumask *cpumask = cpumask_of_bp(bp);
207+ int cpu;
219208
220− /* Pinned counter cpu profiling */
221− if (!tsk) {
209+ if (!enable)
210+ weight = -weight;
222211
223− if (enable)
224− per_cpu(nr_cpu_bp_pinned[type], bp->cpu) += weight;
225− else
226− per_cpu(nr_cpu_bp_pinned[type], bp->cpu) -= weight;
212+ /* Pinned counter cpu profiling */
213+ if (!bp->hw.bp_target) {
214+ get_bp_info(bp->cpu, type)->cpu_pinned += weight;
227215 return;
228216 }
229217
230218 /* Pinned counter task profiling */
231−
232− if (!enable)
233− list_del(&bp->hw.bp_list);
234−
235− if (cpu >= 0) {
236− toggle_bp_task_slot(bp, cpu, enable, type, weight);
237− } else {
238− for_each_possible_cpu(cpu)
239− toggle_bp_task_slot(bp, cpu, enable, type, weight);
240− }
219+ for_each_cpu(cpu, cpumask)
220+ toggle_bp_task_slot(bp, cpu, type, weight);
241221
242222 if (enable)
243223 list_add_tail(&bp->hw.bp_list, &bp_task_head);
224+ else
225+ list_del(&bp->hw.bp_list);
244226 }
245227
246228 /*
@@ -261,8 +243,8 @@ __weak void arch_unregister_hw_breakpoint(struct perf_event *bp) · 14 unmodified lines
261243 *
262244 * - If attached to a single cpu, check:
263245 *
264− * (per_cpu(nr_bp_flexible, cpu) || (per_cpu(nr_cpu_bp_pinned, cpu)
265− * + max(per_cpu(nr_task_bp_pinned, cpu)))) < HBP_NUM
246+ * (per_cpu(info->flexible, cpu) || (per_cpu(info->cpu_pinned, cpu)
247+ * + max(per_cpu(info->tsk_pinned, cpu)))) < HBP_NUM
266248 *
267249 * -> If there are already non-pinned counters in this cpu, it means
268250 * there is already a free slot for them.
@@ -272,8 +254,8 @@ __weak void arch_unregister_hw_breakpoint(struct perf_event *bp) · 3 unmodified lines
272254 *
273255 * - If attached to every cpus, check:
274256 *
275− * (per_cpu(nr_bp_flexible, *) || (max(per_cpu(nr_cpu_bp_pinned, *))
276− * + max(per_cpu(nr_task_bp_pinned, *)))) < HBP_NUM
257+ * (per_cpu(info->flexible, *) || (max(per_cpu(info->cpu_pinned, *))
258+ * + max(per_cpu(info->tsk_pinned, *)))) < HBP_NUM
277259 *
278260 * -> This is roughly the same, except we check the number of per cpu
279261 * bp for every cpu and we keep the max one. Same for the per tasks
@@ -284,16 +266,16 @@ __weak void arch_unregister_hw_breakpoint(struct perf_event *bp) · 4 unmodified lines
284266 *
285267 * - If attached to a single cpu, check:
286268 *
287− * ((per_cpu(nr_bp_flexible, cpu) > 1) + per_cpu(nr_cpu_bp_pinned, cpu)
288− * + max(per_cpu(nr_task_bp_pinned, cpu))) < HBP_NUM
269+ * ((per_cpu(info->flexible, cpu) > 1) + per_cpu(info->cpu_pinned, cpu)
270+ * + max(per_cpu(info->tsk_pinned, cpu))) < HBP_NUM
289271 *
290− * -> Same checks as before. But now the nr_bp_flexible, if any, must keep
272+ * -> Same checks as before. But now the info->flexible, if any, must keep
291273 * one register at least (or they will never be fed).
292274 *
293275 * - If attached to every cpus, check:
294276 *
295− * ((per_cpu(nr_bp_flexible, *) > 1) + max(per_cpu(nr_cpu_bp_pinned, *))
296− * + max(per_cpu(nr_task_bp_pinned, *))) < HBP_NUM
277+ * ((per_cpu(info->flexible, *) > 1) + max(per_cpu(info->cpu_pinned, *))
278+ * + max(per_cpu(info->tsk_pinned, *))) < HBP_NUM
297279 */
298280 static int __reserve_bp_slot(struct perf_event *bp)
299281 {
@@ -518,8 +500,8 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, · 218 unmodified lines
518500 perf_overflow_handler_t triggered,
519501 void *context)
520502 {
521− struct perf_event * __percpu *cpu_events, **pevent, *bp;
522− long err;
503+ struct perf_event * __percpu *cpu_events, *bp;
504+ long err = 0;
523505 int cpu;
524506
525507 cpu_events = alloc_percpu(typeof(*cpu_events));
@@ -528,31 +510,21 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, · 2 unmodified lines
528510
529511 get_online_cpus();
530512 for_each_online_cpu(cpu) {
531− pevent = per_cpu_ptr(cpu_events, cpu);
532513 bp = perf_event_create_kernel_counter(attr, cpu, NULL,
533514 triggered, context);
534−
535− *pevent = bp;
536−
537515 if (IS_ERR(bp)) {
538516 err = PTR_ERR(bp);
539− goto fail;
517+ break;
540518 }
541− }
542− put_online_cpus();
543519
544− return cpu_events;
545−
546−fail:
547− for_each_online_cpu(cpu) {
548− pevent = per_cpu_ptr(cpu_events, cpu);
549− if (IS_ERR(*pevent))
550− break;
551− unregister_hw_breakpoint(*pevent);
520+ per_cpu(*cpu_events, cpu) = bp;
552521 }
553522 put_online_cpus();
554523
555− free_percpu(cpu_events);
524+ if (likely(!err))
525+ return cpu_events;
526+
527+ unregister_wide_hw_breakpoint(cpu_events);
556528 return (void __percpu __force *)ERR_PTR(err);
557529 }
558530 EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint);
@@ -564,12 +536,10 @@ EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); · 5 unmodified lines
564536 void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events)
565537 {
566538 int cpu;
567− struct perf_event **pevent;
568539
569− for_each_possible_cpu(cpu) {
570− pevent = per_cpu_ptr(cpu_events, cpu);
571− unregister_hw_breakpoint(*pevent);
572− }
540+ for_each_possible_cpu(cpu)
541+ unregister_hw_breakpoint(per_cpu(*cpu_events, cpu));
542+
573543 free_percpu(cpu_events);
574544 }
575545 EXPORT_SYMBOL_GPL(unregister_wide_hw_breakpoint);
@@ -612,6 +582,11 @@ static int hw_breakpoint_add(struct perf_event *bp, int flags) · 36 unmodified lines
612582 if (!(flags & PERF_EF_START))
613583 bp->hw.state = PERF_HES_STOPPED;
614584
585+ if (is_sampling_event(bp)) {
586+ bp->hw.last_period = bp->hw.sample_period;
587+ perf_swevent_set_period(bp);
588+ }
589+
615590 return arch_install_hw_breakpoint(bp);
616591 }
617592
@@ -650,7 +625,6 @@ static struct pmu perf_breakpoint = { · 32 unmodified lines
650625
651626 int __init init_hw_breakpoint(void)
652627 {
653− unsigned int **task_bp_pinned;
654628 int cpu, err_cpu;
655629 int i;
656630
@@ -659,10 +633,11 @@ int __init init_hw_breakpoint(void) · 2 unmodified lines
659633
660634 for_each_possible_cpu(cpu) {
661635 for (i = 0; i < TYPE_MAX; i++) {
662− task_bp_pinned = &per_cpu(nr_task_bp_pinned[i], cpu);
663− *task_bp_pinned = kzalloc(sizeof(int) * nr_slots[i],
664− GFP_KERNEL);
665− if (!*task_bp_pinned)
636+ struct bp_cpuinfo *info = get_bp_info(cpu, i);
637+
638+ info->tsk_pinned = kcalloc(nr_slots[i], sizeof(int),
639+ GFP_KERNEL);
640+ if (!info->tsk_pinned)
666641 goto err_alloc;
667642 }
668643 }
@@ -676,7 +651,7 @@ int __init init_hw_breakpoint(void) · 7 unmodified lines
676651 err_alloc:
677652 for_each_possible_cpu(err_cpu) {
678653 for (i = 0; i < TYPE_MAX; i++)
679− kfree(per_cpu(nr_task_bp_pinned[i], err_cpu));
654+ kfree(get_bp_info(err_cpu, i)->tsk_pinned);
680655 if (err_cpu == cpu)
681656 break;
682657 }
kernel/sysctl.c+10−2
@@ -120,7 +120,6 @@ extern int blk_iopoll_enabled; · 119 unmodified lines
120120 /* Constants used for minimum and maximum */
121121 #ifdef CONFIG_LOCKUP_DETECTOR
122122 static int sixty = 60;
123−static int neg_one = -1;
124123 #endif
125124
126125 static int zero;
@@ -814,7 +813,7 @@ static struct ctl_table kern_table[] = { · 687 unmodified lines
814813 .maxlen = sizeof(int),
815814 .mode = 0644,
816815 .proc_handler = proc_dowatchdog,
817− .extra1 = &neg_one,
816+ .extra1 = &zero,
818817 .extra2 = &sixty,
819818 },
820819 {
@@ -1044,6 +1043,15 @@ static struct ctl_table kern_table[] = { · 223 unmodified lines
10441043 .mode = 0644,
10451044 .proc_handler = perf_proc_update_handler,
10461045 },
1046+ {
1047+ .procname = "perf_cpu_time_max_percent",
1048+ .data = &sysctl_perf_cpu_time_max_percent,
1049+ .maxlen = sizeof(sysctl_perf_cpu_time_max_percent),
1050+ .mode = 0644,
1051+ .proc_handler = perf_cpu_time_max_percent_handler,
1052+ .extra1 = &zero,
1053+ .extra2 = &one_hundred,
1054+ },
10471055 #endif
10481056 #ifdef CONFIG_KMEMCHECK
10491057 {
tools/lib/lk/Makefile+3−0
@@ -1,5 +1,8 @@
11 include ../../scripts/Makefile.include
22
3+CC = $(CROSS_COMPILE)gcc
4+AR = $(CROSS_COMPILE)ar
5+
36 # guard against environment variables
47 LIB_H=
58 LIB_OBJS=
tools/perf/Documentation/perf-archive.txt+1−1
@@ -13,7 +13,7 @@ SYNOPSIS · 12 unmodified lines
1313 DESCRIPTION
1414 -----------
1515 This command runs runs perf-buildid-list --with-hits, and collects the files
16−with the buildids found so that analisys of perf.data contents can be possible
16+with the buildids found so that analysis of perf.data contents can be possible
1717 on another machine.
1818
1919
tools/perf/Documentation/perf-report.txt+4−0
@@ -210,6 +210,10 @@ OPTIONS · 209 unmodified lines
210210 Demangle symbol names to human readable form. It's enabled by default,
211211 disable with --no-demangle.
212212
213+--percent-limit::
214+ Do not show entries which have an overhead under that percent.
215+ (Default: 0).
216+
213217 SEE ALSO
214218 --------
215219 linkperf:perf-stat[1], linkperf:perf-annotate[1]
tools/perf/Documentation/perf-top.txt+4−0
@@ -155,6 +155,10 @@ Default is to monitor all CPUS. · 154 unmodified lines
155155
156156 Default: fractal,0.5,callee.
157157
158+--percent-limit::
159+ Do not show entries which have an overhead under that percent.
160+ (Default: 0).
161+
158162 INTERACTIVE PROMPTING KEYS
159163 --------------------------
160164
tools/perf/Makefile+110−520
@@ -51,189 +51,63 @@ include config/utilities.mak · 50 unmodified lines
5151 # Define NO_BACKTRACE if you do not want stack backtrace debug feature
5252 #
5353 # Define NO_LIBNUMA if you do not want numa perf benchmark
54+#
55+# Define NO_LIBAUDIT if you do not want libaudit support
56+#
57+# Define NO_LIBBIONIC if you do not want bionic support
5458
55−$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
56− @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
57−
58−uname_M := $(shell uname -m 2>/dev/null || echo not)
59−
60−ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
61− -e s/arm.*/arm/ -e s/sa110/arm/ \
62− -e s/s390x/s390/ -e s/parisc64/parisc/ \
63− -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
64− -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
65−NO_PERF_REGS := 1
66−
67−CC = $(CROSS_COMPILE)gcc
68−AR = $(CROSS_COMPILE)ar
69−
70−# Additional ARCH settings for x86
71−ifeq ($(ARCH),i386)
72− override ARCH := x86
73− NO_PERF_REGS := 0
74− LIBUNWIND_LIBS = -lunwind -lunwind-x86
75−endif
76−ifeq ($(ARCH),x86_64)
77− override ARCH := x86
78− IS_X86_64 := 0
79− ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
80− IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
81− endif
82− ifeq (${IS_X86_64}, 1)
83− RAW_ARCH := x86_64
84− ARCH_CFLAGS := -DARCH_X86_64
85− ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
86− endif
87− NO_PERF_REGS := 0
88− LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
89−endif
90−
91−# Treat warnings as errors unless directed not to
92−ifneq ($(WERROR),0)
93− CFLAGS_WERROR := -Werror
94−endif
95−
96−ifeq ("$(origin DEBUG)", "command line")
97− PERF_DEBUG = $(DEBUG)
98−endif
99−ifndef PERF_DEBUG
100− CFLAGS_OPTIMIZE = -O6
59+ifeq ($(srctree),)
60+srctree := $(patsubst %/,%,$(dir $(shell pwd)))
61+srctree := $(patsubst %/,%,$(dir $(srctree)))
62+#$(info Determined 'srctree' to be $(srctree))
10163 endif
10264
103−ifdef PARSER_DEBUG
104− PARSER_DEBUG_BISON := -t
105− PARSER_DEBUG_FLEX := -d
106− PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
65+ifneq ($(objtree),)
66+#$(info Determined 'objtree' to be $(objtree))
10767 endif
10868
109−ifdef NO_NEWT
110− NO_SLANG=1
69+ifneq ($(OUTPUT),)
70+#$(info Determined 'OUTPUT' to be $(OUTPUT))
11171 endif
11272
113−CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
114−EXTLIBS = -lpthread -lrt -lelf -lm
115−ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
116−ALL_LDFLAGS = $(LDFLAGS)
117−STRIP ?= strip
118−
119−# Among the variables below, these:
120−# perfexecdir
121−# template_dir
122−# mandir
123−# infodir
124−# htmldir
125−# ETC_PERFCONFIG (but not sysconfdir)
126−# can be specified as a relative path some/where/else;
127−# this is interpreted as relative to $(prefix) and "perf" at
128−# runtime figures out where they are based on the path to the executable.
129−# This can help installing the suite in a relocatable way.
130−
131−# Make the path relative to DESTDIR, not to prefix
132−ifndef DESTDIR
133−prefix = $(HOME)
134−endif
135−bindir_relative = bin
136−bindir = $(prefix)/$(bindir_relative)
137−mandir = share/man
138−infodir = share/info
139−perfexecdir = libexec/perf-core
140−sharedir = $(prefix)/share
141−template_dir = share/perf-core/templates
142−htmldir = share/doc/perf-doc
143−ifeq ($(prefix),/usr)
144−sysconfdir = /etc
145−ETC_PERFCONFIG = $(sysconfdir)/perfconfig
146−else
147−sysconfdir = $(prefix)/etc
148−ETC_PERFCONFIG = etc/perfconfig
149−endif
150−lib = lib
73+$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
74+ @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
15175
152−export prefix bindir sharedir sysconfdir
76+CC = $(CROSS_COMPILE)gcc
77+AR = $(CROSS_COMPILE)ar
15378
154−RM = rm -f
155−MKDIR = mkdir
156−FIND = find
79+RM = rm -f
80+MKDIR = mkdir
81+FIND = find
15782 INSTALL = install
158−FLEX = flex
159−BISON= bison
160−
161−# sparse is architecture-neutral, which means that we need to tell it
162−# explicitly what architecture to check for. Fix this up for yours..
163−SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
164−
165−ifneq ($(MAKECMDGOALS),clean)
166−ifneq ($(MAKECMDGOALS),tags)
167−-include config/feature-tests.mak
168−
169−ifeq ($(call get-executable,$(FLEX)),)
170− dummy := $(error Error: $(FLEX) is missing on this system, please install it)
171−endif
172−
173−ifeq ($(call get-executable,$(BISON)),)
174− dummy := $(error Error: $(BISON) is missing on this system, please install it)
175−endif
83+FLEX = flex
84+BISON = bison
85+STRIP = strip
17686
177−ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
178− CFLAGS := $(CFLAGS) -fstack-protector-all
179−endif
87+LK_DIR = $(srctree)/tools/lib/lk/
88+TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
18089
181−ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
182− CFLAGS := $(CFLAGS) -Wstack-protector
183−endif
90+# include config/Makefile by default and rule out
91+# non-config cases
92+config := 1
18493
185−ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
186− CFLAGS := $(CFLAGS) -Wvolatile-register-var
187−endif
94+NON_CONFIG_TARGETS := clean TAGS tags cscope help
18895
189−ifndef PERF_DEBUG
190− ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
191− CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
192− endif
96+ifdef MAKECMDGOALS
97+ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
98+ config := 0
19399 endif
194−
195−### --- END CONFIGURATION SECTION ---
196−
197−ifeq ($(srctree),)
198−srctree := $(patsubst %/,%,$(dir $(shell pwd)))
199−srctree := $(patsubst %/,%,$(dir $(srctree)))
200−#$(info Determined 'srctree' to be $(srctree))
201100 endif
202101
203−ifneq ($(objtree),)
204−#$(info Determined 'objtree' to be $(objtree))
102+ifeq ($(config),1)
103+include config/Makefile
205104 endif
206105
207−ifneq ($(OUTPUT),)
208−#$(info Determined 'OUTPUT' to be $(OUTPUT))
209−endif
106+export prefix bindir sharedir sysconfdir
210107
211−BASIC_CFLAGS = \
212− -Iutil/include \
213− -Iarch/$(ARCH)/include \
214− $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
215− -I$(srctree)/arch/$(ARCH)/include/uapi \
216− -I$(srctree)/arch/$(ARCH)/include \
217− $(if $(objtree),-I$(objtree)/include/generated/uapi) \
218− -I$(srctree)/include/uapi \
219− -I$(srctree)/include \
220− -I$(OUTPUT)util \
221− -Iutil \
222− -I. \
223− -I$(TRACE_EVENT_DIR) \
224− -I../lib/ \
225− -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
226−
227−BASIC_LDFLAGS =
228−
229−ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
230− BIONIC := 1
231− EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
232− EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
233− BASIC_CFLAGS += -I.
234−endif
235−endif # MAKECMDGOALS != tags
236−endif # MAKECMDGOALS != clean
108+# sparse is architecture-neutral, which means that we need to tell it
109+# explicitly what architecture to check for. Fix this up for yours..
110+SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
237111
238112 # Guard against environment variables
239113 BUILTIN_OBJS =
@@ -247,20 +121,17 @@ SCRIPT_SH += perf-archive.sh · 7 unmodified lines
247121 grep-libs = $(filter -l%,$(1))
248122 strip-libs = $(filter-out -l%,$(1))
249123
250−LK_DIR = ../lib/lk/
251−TRACE_EVENT_DIR = ../lib/traceevent/
252−
253124 LK_PATH=$(LK_DIR)
254125
255126 ifneq ($(OUTPUT),)
256− TE_PATH=$(OUTPUT)
127+ TE_PATH=$(OUTPUT)
257128 ifneq ($(subdir),)
258− LK_PATH=$(OUTPUT)$(LK_DIR)
129+ LK_PATH=$(OUTPUT)$(LK_DIR)
259130 else
260− LK_PATH=$(OUTPUT)
131+ LK_PATH=$(OUTPUT)
261132 endif
262133 else
263− TE_PATH=$(TRACE_EVENT_DIR)
134+ TE_PATH=$(TRACE_EVENT_DIR)
264135 endif
265136
266137 LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
@@ -278,10 +149,10 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP · 11 unmodified lines
278149 python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
279150
280151 PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
281−PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT)
152+PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
282153
283154 $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
284− $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
155+ $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
285156 --quiet build_ext; \
286157 mkdir -p $(OUTPUT)python && \
287158 cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
@@ -296,8 +167,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) · 8 unmodified lines
296167 #
297168 PROGRAMS += $(OUTPUT)perf
298169
299−LANG_BINDINGS =
300−
301170 # what 'all' will build and 'install' will install, in perfexecdir
302171 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
303172
@@ -306,10 +175,10 @@ OTHER_PROGRAMS = $(OUTPUT)perf · 2 unmodified lines
306175
307176 # Set paths to tools early so that they can be used for version tests.
308177 ifndef SHELL_PATH
309− SHELL_PATH = /bin/sh
178+ SHELL_PATH = /bin/sh
310179 endif
311180 ifndef PERL_PATH
312− PERL_PATH = /usr/bin/perl
181+ PERL_PATH = /usr/bin/perl
313182 endif
314183
315184 export PERL_PATH
@@ -557,79 +426,14 @@ BUILTIN_OBJS += $(OUTPUT)builtin-mem.o · 241 unmodified lines
557426
558427 PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
559428
560−#
561−# Platform specific tweaks
562−#
563−ifneq ($(MAKECMDGOALS),clean)
564−ifneq ($(MAKECMDGOALS),tags)
565−
566429 # We choose to avoid "if .. else if .. else .. endif endif"
567430 # because maintaining the nesting to match is a pain. If
568431 # we had "elif" things would have been much nicer...
569432
570−ifdef NO_LIBELF
571− NO_DWARF := 1
572− NO_DEMANGLE := 1
573− NO_LIBUNWIND := 1
574−else
575−FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
576−ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
577− FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
578− ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
579− LIBC_SUPPORT := 1
580− endif
581− ifeq ($(BIONIC),1)
582− LIBC_SUPPORT := 1
583− endif
584− ifeq ($(LIBC_SUPPORT),1)
585− msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
586−
587− NO_LIBELF := 1
588− NO_DWARF := 1
589− NO_DEMANGLE := 1
590− else
591− msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
592− endif
593−else
594− # for linking with debug library, run like:
595− # make DEBUG=1 LIBDW_DIR=/opt/libdw/
596− ifdef LIBDW_DIR
597− LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
598− LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
599− endif
600−
601− FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
602− ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
603− msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
604− NO_DWARF := 1
605− endif # Dwarf support
606−endif # SOURCE_LIBELF
607−endif # NO_LIBELF
608−
609−# There's only x86 (both 32 and 64) support for CFI unwind so far
610−ifneq ($(ARCH),x86)
611− NO_LIBUNWIND := 1
612−endif
613−
614−ifndef NO_LIBUNWIND
615−# for linking with debug library, run like:
616−# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
617−ifdef LIBUNWIND_DIR
618− LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
619− LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
620−endif
621−
622−FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
623−ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
624− msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
625− NO_LIBUNWIND := 1
626−endif # Libunwind support
627−endif # NO_LIBUNWIND
628−
629433 -include arch/$(ARCH)/Makefile
630434
631435 ifneq ($(OUTPUT),)
632− BASIC_CFLAGS += -I$(OUTPUT)
436+ CFLAGS += -I$(OUTPUT)
633437 endif
634438
635439 ifdef NO_LIBELF
@@ -647,281 +451,74 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS)) · 11 unmodified lines
647451 LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
648452
649453 else # NO_LIBELF
650−BASIC_CFLAGS += -DLIBELF_SUPPORT
651−
652−FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
653−ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
654− BASIC_CFLAGS += -DLIBELF_MMAP
655−endif
656−
657454 ifndef NO_DWARF
658−ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
659− msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
660−else
661− BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
662− BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
663− EXTLIBS += -lelf -ldw
664− LIB_OBJS += $(OUTPUT)util/probe-finder.o
665− LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
666−endif # PERF_HAVE_DWARF_REGS
455+ LIB_OBJS += $(OUTPUT)util/probe-finder.o
456+ LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
667457 endif # NO_DWARF
668458 endif # NO_LIBELF
669459
670460 ifndef NO_LIBUNWIND
671− BASIC_CFLAGS += -DLIBUNWIND_SUPPORT
672− EXTLIBS += $(LIBUNWIND_LIBS)
673− BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
674− BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
675− LIB_OBJS += $(OUTPUT)util/unwind.o
461+ LIB_OBJS += $(OUTPUT)util/unwind.o
676462 endif
677463
678464 ifndef NO_LIBAUDIT
679− FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
680− ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
681− msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
682− else
683− BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
684− BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
685− EXTLIBS += -laudit
686− endif
465+ BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
687466 endif
688467
689468 ifndef NO_SLANG
690− FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
691− ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
692− msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
693− else
694− # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
695− BASIC_CFLAGS += -I/usr/include/slang
696− BASIC_CFLAGS += -DSLANG_SUPPORT
697− EXTLIBS += -lslang
698− LIB_OBJS += $(OUTPUT)ui/browser.o
699− LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
700− LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
701− LIB_OBJS += $(OUTPUT)ui/browsers/map.o
702− LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
703− LIB_OBJS += $(OUTPUT)ui/tui/setup.o
704− LIB_OBJS += $(OUTPUT)ui/tui/util.o
705− LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
706− LIB_OBJS += $(OUTPUT)ui/tui/progress.o
707− LIB_H += ui/browser.h
708− LIB_H += ui/browsers/map.h
709− LIB_H += ui/keysyms.h
710− LIB_H += ui/libslang.h
711− endif
469+ LIB_OBJS += $(OUTPUT)ui/browser.o
470+ LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
471+ LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
472+ LIB_OBJS += $(OUTPUT)ui/browsers/map.o
473+ LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
474+ LIB_OBJS += $(OUTPUT)ui/tui/setup.o
475+ LIB_OBJS += $(OUTPUT)ui/tui/util.o
476+ LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
477+ LIB_OBJS += $(OUTPUT)ui/tui/progress.o
478+ LIB_H += ui/browser.h
479+ LIB_H += ui/browsers/map.h
480+ LIB_H += ui/keysyms.h
481+ LIB_H += ui/libslang.h
712482 endif
713483
714484 ifndef NO_GTK2
715− FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
716− ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
717− msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
718− else
719− ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
720− BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
721− endif
722− BASIC_CFLAGS += -DGTK2_SUPPORT
723− BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
724− EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
725− LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
726− LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
727− LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
728− LIB_OBJS += $(OUTPUT)ui/gtk/util.o
729− LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
730− LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
731− LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
732− endif
485+ LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
486+ LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
487+ LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
488+ LIB_OBJS += $(OUTPUT)ui/gtk/util.o
489+ LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
490+ LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
491+ LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
733492 endif
734493
735−ifdef NO_LIBPERL
736− BASIC_CFLAGS += -DNO_LIBPERL
737−else
738− PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
739− PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
740− PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
741− PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
742− FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
743−
744− ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
745− BASIC_CFLAGS += -DNO_LIBPERL
746− else
747− ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
748− EXTLIBS += $(PERL_EMBED_LIBADD)
749− LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
750− LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
751− endif
494+ifndef NO_LIBPERL
495+ LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
496+ LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
752497 endif
753498
754−disable-python = $(eval $(disable-python_code))
755−define disable-python_code
756− BASIC_CFLAGS += -DNO_LIBPYTHON
757− $(if $(1),$(warning No $(1) was found))
758− $(warning Python support will not be built)
759−endef
760−
761−override PYTHON := \
762− $(call get-executable-or-default,PYTHON,python)
763−
764−ifndef PYTHON
765− $(call disable-python,python interpreter)
766−else
767−
768− PYTHON_WORD := $(call shell-wordify,$(PYTHON))
769−
770− ifdef NO_LIBPYTHON
771− $(call disable-python)
772− else
773−
774− override PYTHON_CONFIG := \
775− $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
776−
777− ifndef PYTHON_CONFIG
778− $(call disable-python,python-config tool)
779− else
780−
781− PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
782−
783− PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
784− PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
785− PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
786− PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
787− FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
788−
789− ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
790− $(call disable-python,Python.h (for Python 2.x))
791− else
792−
793− ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
794− $(warning Python 3 is not yet supported; please set)
795− $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
796− $(warning If you also have Python 2 installed, then)
797− $(warning try something like:)
798− $(warning $(and ,))
799− $(warning $(and ,) make PYTHON=python2)
800− $(warning $(and ,))
801− $(warning Otherwise, disable Python support entirely:)
802− $(warning $(and ,))
803− $(warning $(and ,) make NO_LIBPYTHON=1)
804− $(warning $(and ,))
805− $(error $(and ,))
806− else
807− ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
808− EXTLIBS += $(PYTHON_EMBED_LIBADD)
809− LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
810− LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
811− LANG_BINDINGS += $(OUTPUT)python/perf.so
812− endif
813−
814− endif
815− endif
816− endif
817−endif
818−
819−ifdef NO_DEMANGLE
820− BASIC_CFLAGS += -DNO_DEMANGLE
821−else
822− ifdef HAVE_CPLUS_DEMANGLE
823− EXTLIBS += -liberty
824− BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
825− else
826− FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
827− has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
828− ifeq ($(has_bfd),y)
829− EXTLIBS += -lbfd
830− else
831− FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
832− has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
833− ifeq ($(has_bfd_iberty),y)
834− EXTLIBS += -lbfd -liberty
835− else
836− FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
837− has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
838− ifeq ($(has_bfd_iberty_z),y)
839− EXTLIBS += -lbfd -liberty -lz
840− else
841− FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
842− has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
843− ifeq ($(has_cplus_demangle),y)
844− EXTLIBS += -liberty
845− BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
846− else
847− msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
848− BASIC_CFLAGS += -DNO_DEMANGLE
849− endif
850− endif
851− endif
852− endif
853− endif
499+ifndef NO_LIBPYTHON
500+ LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
501+ LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
854502 endif
855503
856504 ifeq ($(NO_PERF_REGS),0)
857− ifeq ($(ARCH),x86)
858− LIB_H += arch/x86/include/perf_regs.h
859− endif
860− BASIC_CFLAGS += -DHAVE_PERF_REGS
861−endif
862−
863−ifndef NO_STRLCPY
864− ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
865− BASIC_CFLAGS += -DHAVE_STRLCPY
866− endif
867−endif
868−
869−ifndef NO_ON_EXIT
870− ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
871− BASIC_CFLAGS += -DHAVE_ON_EXIT
872− endif
873−endif
874−
875−ifndef NO_BACKTRACE
876− ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
877− BASIC_CFLAGS += -DBACKTRACE_SUPPORT
878− endif
505+ ifeq ($(ARCH),x86)
506+ LIB_H += arch/x86/include/perf_regs.h
507+ endif
879508 endif
880509
881510 ifndef NO_LIBNUMA
882− FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma
883− ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
884− msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
885− else
886− BASIC_CFLAGS += -DLIBNUMA_SUPPORT
887− BUILTIN_OBJS += $(OUTPUT)bench/numa.o
888− EXTLIBS += -lnuma
889− endif
511+ BUILTIN_OBJS += $(OUTPUT)bench/numa.o
890512 endif
891513
892514 ifdef ASCIIDOC8
893− export ASCIIDOC8
515+ export ASCIIDOC8
894516 endif
895517
896−endif # MAKECMDGOALS != tags
897−endif # MAKECMDGOALS != clean
898−
899−# Shell quote (do not use $(call) to accommodate ancient setups);
900−
901−ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
902−
903−DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
904−bindir_SQ = $(subst ','\'',$(bindir))
905−bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
906−mandir_SQ = $(subst ','\'',$(mandir))
907−infodir_SQ = $(subst ','\'',$(infodir))
908−perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
909−template_dir_SQ = $(subst ','\'',$(template_dir))
910−htmldir_SQ = $(subst ','\'',$(htmldir))
911−prefix_SQ = $(subst ','\'',$(prefix))
912−sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
913−
914−SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
915−
916518 LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
917519
918−ALL_CFLAGS += $(BASIC_CFLAGS)
919−ALL_CFLAGS += $(ARCH_CFLAGS)
920−ALL_LDFLAGS += $(BASIC_LDFLAGS)
921−
922520 export INSTALL SHELL_PATH
923521
924−
925522 ### Build rules
926523
927524 SHELL = $(SHELL_PATH)
@@ -939,20 +536,20 @@ strip: $(PROGRAMS) $(OUTPUT)perf · 11 unmodified lines
939536 $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
940537 $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
941538 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
942− $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
539+ $(CFLAGS) -c $(filter %.c,$^) -o $@
943540
944541 $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
945− $(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \
542+ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
946543 $(BUILTIN_OBJS) $(LIBS) -o $@
947544
948545 $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
949− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
546+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
950547 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
951548 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
952549 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
953550
954551 $(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
955− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
552+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
956553 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
957554 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
958555 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
@@ -977,77 +574,77 @@ $(OUTPUT)perf.o perf.spec \ · 18 unmodified lines
977574 # over the general rule for .o
978575
979576 $(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
980− $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -w $<
577+ $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $<
981578
982579 $(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
983− $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
580+ $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
984581
985582 $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
986− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
583+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
987584 $(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
988− $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $<
585+ $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
989586 $(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
990− $(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $<
587+ $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
991588 $(OUTPUT)%.o: %.S
992− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
589+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
993590 $(OUTPUT)%.s: %.S
994− $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $<
591+ $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
995592
996593 $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
997− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
594+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
998595 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
999596 '-DPREFIX="$(prefix_SQ)"' \
1000597 $<
1001598
1002599 $(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
1003− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
600+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
1004601 '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
1005602 $<
1006603
1007604 $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
1008− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
605+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
1009606 -DPYTHONPATH='"$(OUTPUT)python"' \
1010607 -DPYTHON='"$(PYTHON_WORD)"' \
1011608 $<
1012609
1013610 $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
1014− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
611+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
1015612
1016613 $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
1017− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
614+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1018615
1019616 $(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
1020− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
617+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1021618
1022619 $(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
1023− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
620+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1024621
1025622 $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
1026− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
623+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1027624
1028625 $(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
1029− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
626+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1030627
1031628 $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
1032− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
629+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
1033630
1034631 $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
1035− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls $<
632+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
1036633
1037634 $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
1038− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
635+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
1039636
1040637 $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
1041− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
638+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
1042639
1043640 $(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
1044− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
641+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
1045642
1046643 $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
1047− $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
644+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
1048645
1049646 $(OUTPUT)perf-%: %.o $(PERFLIBS)
1050− $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
647+ $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
1051648
1052649 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
1053650 $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
@@ -1134,7 +731,7 @@ cscope: · 80 unmodified lines
1134731 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
1135732
1136733 ### Detect prefix changes
1137−TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
734+TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
1138735 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
1139736
1140737 $(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
@@ -1155,7 +752,7 @@ check: $(OUTPUT)common-cmds.h · 14 unmodified lines
1155752 then \
1156753 for i in *.c */*.c; \
1157754 do \
1158− sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
755+ sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
1159756 done; \
1160757 else \
1161758 exit 1; \
@@ -1163,13 +760,6 @@ check: $(OUTPUT)common-cmds.h · 1 unmodified line
1163760
1164761 ### Installation rules
1165762
1166−ifneq ($(filter /%,$(firstword $(perfexecdir))),)
1167−perfexec_instdir = $(perfexecdir)
1168−else
1169−perfexec_instdir = $(prefix)/$(perfexecdir)
1170−endif
1171−perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
1172−
1173763 install-bin: all
1174764 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
1175765 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
tools/perf/builtin-diff.c+12−7
@@ -323,13 +323,20 @@ static void hists__baseline_only(struct hists *hists) · 322 unmodified lines
323323
324324 static void hists__precompute(struct hists *hists)
325325 {
326− struct rb_node *next = rb_first(&hists->entries);
326+ struct rb_root *root;
327+ struct rb_node *next;
328+
329+ if (sort__need_collapse)
330+ root = &hists->entries_collapsed;
331+ else
332+ root = hists->entries_in;
327333
334+ next = rb_first(root);
328335 while (next != NULL) {
329− struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
336+ struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
330337 struct hist_entry *pair = hist_entry__next_pair(he);
331338
332− next = rb_next(&he->rb_node);
339+ next = rb_next(&he->rb_node_in);
333340 if (!pair)
334341 continue;
335342
@@ -457,7 +464,7 @@ static void hists__process(struct hists *old, struct hists *new) · 121 unmodified lines
457464 hists__output_resort(new);
458465 }
459466
460− hists__fprintf(new, true, 0, 0, stdout);
467+ hists__fprintf(new, true, 0, 0, 0, stdout);
461468 }
462469
463470 static int __cmd_diff(void)
@@ -611,9 +618,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) · 147 unmodified lines
611618
612619 setup_pager();
613620
614− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", NULL);
615− sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", NULL);
616− sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", NULL);
621+ sort__setup_elide(NULL);
617622
618623 return __cmd_diff();
619624 }
tools/perf/builtin-kvm.c+3−0
@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key) · 327 unmodified lines
328328 static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
329329 {
330330 int old_max_vcpu = event->max_vcpu;
331+ void *prev;
331332
332333 if (vcpu_id < event->max_vcpu)
333334 return true;
@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id) · 1 unmodified line
335336 while (event->max_vcpu <= vcpu_id)
336337 event->max_vcpu += DEFAULT_VCPU_NUM;
337338
339+ prev = event->vcpu;
338340 event->vcpu = realloc(event->vcpu,
339341 event->max_vcpu * sizeof(*event->vcpu));
340342 if (!event->vcpu) {
343+ free(prev);
341344 pr_err("Not enough memory\n");
342345 return false;
343346 }
tools/perf/builtin-record.c+1−1
@@ -198,7 +198,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) · 197 unmodified lines
198198 return;
199199
200200 signal(signr, SIG_DFL);
201− kill(getpid(), signr);
202201 }
203202
204203 static bool perf_evlist__equal(struct perf_evlist *evlist,
@@ -404,6 +403,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) · 199 unmodified lines
404403 signal(SIGCHLD, sig_handler);
405404 signal(SIGINT, sig_handler);
406405 signal(SIGUSR1, sig_handler);
406+ signal(SIGTERM, sig_handler);
407407
408408 if (!output_name) {
409409 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
tools/perf/builtin-report.c+54−48
@@ -52,6 +52,7 @@ struct perf_report { · 51 unmodified lines
5252 symbol_filter_t annotate_init;
5353 const char *cpu_list;
5454 const char *symbol_filter_str;
55+ float min_percent;
5556 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
5657 };
5758
@@ -61,6 +62,11 @@ static int perf_report_config(const char *var, const char *value, void *cb) · 3 unmodified lines
6162 symbol_conf.event_group = perf_config_bool(var, value);
6263 return 0;
6364 }
65+ if (!strcmp(var, "report.percent-limit")) {
66+ struct perf_report *rep = cb;
67+ rep->min_percent = strtof(value, NULL);
68+ return 0;
69+ }
6470
6571 return perf_default_config(var, value, cb);
6672 }
@@ -187,6 +193,9 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, · 120 unmodified lines
187193 for (i = 0; i < sample->branch_stack->nr; i++) {
188194 if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
189195 continue;
196+
197+ err = -ENOMEM;
198+
190199 /*
191200 * The report shows the percentage of total branches captured
192201 * and not events sampled. Thus we use a pseudo period of 1.
@@ -195,7 +204,6 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, · 2 unmodified lines
195204 &bi[i], 1, 1);
196205 if (he) {
197206 struct annotation *notes;
198− err = -ENOMEM;
199207 bx = he->branch_info;
200208 if (bx->from.sym && use_browser == 1 && sort__has_sym) {
201209 notes = symbol__annotation(bx->from.sym);
@@ -226,11 +234,12 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, · 24 unmodified lines
226234 }
227235 evsel->hists.stats.total_period += 1;
228236 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
229− err = 0;
230237 } else
231− return -ENOMEM;
238+ goto out;
232239 }
240+ err = 0;
233241 out:
242+ free(bi);
234243 return err;
235244 }
236245
@@ -294,6 +303,7 @@ static int process_sample_event(struct perf_tool *tool, · 57 unmodified lines
294303 {
295304 struct perf_report *rep = container_of(tool, struct perf_report, tool);
296305 struct addr_location al;
306+ int ret;
297307
298308 if (perf_event__preprocess_sample(event, machine, &al, sample,
299309 rep->annotate_init) < 0) {
@@ -308,28 +318,25 @@ static int process_sample_event(struct perf_tool *tool, · 8 unmodified lines
308318 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
309319 return 0;
310320
311− if (sort__branch_mode == 1) {
312− if (perf_report__add_branch_hist_entry(tool, &al, sample,
313− evsel, machine)) {
321+ if (sort__mode == SORT_MODE__BRANCH) {
322+ ret = perf_report__add_branch_hist_entry(tool, &al, sample,
323+ evsel, machine);
324+ if (ret < 0)
314325 pr_debug("problem adding lbr entry, skipping event\n");
315− return -1;
316− }
317326 } else if (rep->mem_mode == 1) {
318− if (perf_report__add_mem_hist_entry(tool, &al, sample,
319− evsel, machine, event)) {
327+ ret = perf_report__add_mem_hist_entry(tool, &al, sample,
328+ evsel, machine, event);
329+ if (ret < 0)
320330 pr_debug("problem adding mem entry, skipping event\n");
321− return -1;
322− }
323331 } else {
324332 if (al.map != NULL)
325333 al.map->dso->hit = 1;
326334
327− if (perf_evsel__add_hist_entry(evsel, &al, sample, machine)) {
335+ ret = perf_evsel__add_hist_entry(evsel, &al, sample, machine);
336+ if (ret < 0)
328337 pr_debug("problem incrementing symbol period, skipping event\n");
329− return -1;
330− }
331338 }
332− return 0;
339+ return ret;
333340 }
334341
335342 static int process_read_event(struct perf_tool *tool,
@@ -384,7 +391,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) · 48 unmodified lines
384391 }
385392 }
386393
387− if (sort__branch_mode == 1) {
394+ if (sort__mode == SORT_MODE__BRANCH) {
388395 if (!self->fd_pipe &&
389396 !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
390397 ui__error("Selected -b but no branch data. "
@@ -455,7 +462,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, · 64 unmodified lines
455462 continue;
456463
457464 hists__fprintf_nr_sample_events(rep, hists, evname, stdout);
458− hists__fprintf(hists, true, 0, 0, stdout);
465+ hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
459466 fprintf(stdout, "\n\n");
460467 }
461468
@@ -574,8 +581,8 @@ static int __cmd_report(struct perf_report *rep) · 112 unmodified lines
574581 if (use_browser > 0) {
575582 if (use_browser == 1) {
576583 ret = perf_evlist__tui_browse_hists(session->evlist,
577− help,
578− NULL,
584+ help, NULL,
585+ rep->min_percent,
579586 &session->header.env);
580587 /*
581588 * Usually "ret" is the last pressed key, and we only
@@ -586,7 +593,7 @@ static int __cmd_report(struct perf_report *rep) · 4 unmodified lines
586593
587594 } else if (use_browser == 2) {
588595 perf_evlist__gtk_browse_hists(session->evlist, help,
589− NULL);
596+ NULL, rep->min_percent);
590597 }
591598 } else
592599 perf_evlist__tty_browse_hists(session->evlist, rep, help);
@@ -691,7 +698,19 @@ static int · 98 unmodified lines
691698 parse_branch_mode(const struct option *opt __maybe_unused,
692699 const char *str __maybe_unused, int unset)
693700 {
694− sort__branch_mode = !unset;
701+ int *branch_mode = opt->value;
702+
703+ *branch_mode = !unset;
704+ return 0;
705+}
706+
707+static int
708+parse_percent_limit(const struct option *opt, const char *str,
709+ int unset __maybe_unused)
710+{
711+ struct perf_report *rep = opt->value;
712+
713+ rep->min_percent = strtof(str, NULL);
695714 return 0;
696715 }
697716
@@ -700,6 +719,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) · 2 unmodified lines
700719 struct perf_session *session;
701720 struct stat st;
702721 bool has_br_stack = false;
722+ int branch_mode = -1;
703723 int ret = -1;
704724 char callchain_default_opt[] = "fractal,0.5,callee";
705725 const char * const report_usage[] = {
@@ -796,17 +816,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) · 90 unmodified lines
796816 "Show a column with the sum of periods"),
797817 OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
798818 "Show event group information together"),
799− OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "",
819+ OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
800820 "use branch records for histogram filling", parse_branch_mode),
801821 OPT_STRING(0, "objdump", &objdump_path, "path",
802822 "objdump binary to use for disassembly and annotations"),
803823 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
804824 "Disable symbol demangling"),
805825 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
826+ OPT_CALLBACK(0, "percent-limit", &report, "percent",
827+ "Don't show entries under that percent", parse_percent_limit),
806828 OPT_END()
807829 };
808830
809− perf_config(perf_report_config, NULL);
831+ perf_config(perf_report_config, &report);
810832
811833 argc = parse_options(argc, argv, options, report_usage, 0);
812834
@@ -846,11 +868,11 @@ repeat: · 33 unmodified lines
846868 has_br_stack = perf_header__has_feat(&session->header,
847869 HEADER_BRANCH_STACK);
848870
849− if (sort__branch_mode == -1 && has_br_stack)
850− sort__branch_mode = 1;
871+ if (branch_mode == -1 && has_br_stack)
872+ sort__mode = SORT_MODE__BRANCH;
851873
852− /* sort__branch_mode could be 0 if --no-branch-stack */
853− if (sort__branch_mode == 1) {
874+ /* sort__mode could be NORMAL if --no-branch-stack */
875+ if (sort__mode == SORT_MODE__BRANCH) {
854876 /*
855877 * if no sort_order is provided, then specify
856878 * branch-mode specific order
@@ -861,10 +883,12 @@ repeat: · 4 unmodified lines
861883
862884 }
863885 if (report.mem_mode) {
864− if (sort__branch_mode == 1) {
886+ if (sort__mode == SORT_MODE__BRANCH) {
865887 fprintf(stderr, "branch and mem mode incompatible\n");
866888 goto error;
867889 }
890+ sort__mode = SORT_MODE__MEMORY;
891+
868892 /*
869893 * if no sort_order is provided, then specify
870894 * branch-mode specific order
@@ -929,25 +953,7 @@ repeat: · 58 unmodified lines
929953 report.symbol_filter_str = argv[0];
930954 }
931955
932− sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
933−
934− if (sort__branch_mode == 1) {
935− sort_entry__setup_elide(&sort_dso_from, symbol_conf.dso_from_list, "dso_from", stdout);
936− sort_entry__setup_elide(&sort_dso_to, symbol_conf.dso_to_list, "dso_to", stdout);
937− sort_entry__setup_elide(&sort_sym_from, symbol_conf.sym_from_list, "sym_from", stdout);
938− sort_entry__setup_elide(&sort_sym_to, symbol_conf.sym_to_list, "sym_to", stdout);
939− } else {
940− if (report.mem_mode) {
941− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "symbol_daddr", stdout);
942− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso_daddr", stdout);
943− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "mem", stdout);
944− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "local_weight", stdout);
945− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "tlb", stdout);
946− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "snoop", stdout);
947− }
948− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
949− sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
950− }
956+ sort__setup_elide(stdout);
951957
952958 ret = __cmd_report(&report);
953959 if (ret == K_SWITCH_INPUT_DATA) {
tools/perf/builtin-top.c+39−35
@@ -70,10 +70,11 @@ · 69 unmodified lines
7070
7171 static volatile int done;
7272
73+#define HEADER_LINE_NR 5
74+
7375 static void perf_top__update_print_entries(struct perf_top *top)
7476 {
75− if (top->print_entries > 9)
76− top->print_entries -= 9;
77+ top->print_entries = top->winsize.ws_row - HEADER_LINE_NR;
7778 }
7879
7980 static void perf_top__sig_winch(int sig __maybe_unused,
@@ -82,13 +83,6 @@ static void perf_top__sig_winch(int sig __maybe_unused, · 2 unmodified lines
8283 struct perf_top *top = arg;
8384
8485 get_term_dimensions(&top->winsize);
85− if (!top->print_entries
86− || (top->print_entries+4) > top->winsize.ws_row) {
87− top->print_entries = top->winsize.ws_row;
88− } else {
89− top->print_entries += 4;
90− top->winsize.ws_row = top->print_entries;
91− }
9286 perf_top__update_print_entries(top);
9387 }
9488
@@ -251,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, · 156 unmodified lines
251245 {
252246 struct hist_entry *he;
253247
248+ pthread_mutex_lock(&evsel->hists.lock);
254249 he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
255250 sample->weight);
251+ pthread_mutex_unlock(&evsel->hists.lock);
252+
256253 if (he == NULL)
257254 return NULL;
258255
@@ -290,16 +287,17 @@ static void perf_top__print_sym_table(struct perf_top *top) · 31 unmodified lines
290287 return;
291288 }
292289
293− hists__collapse_resort_threaded(&top->sym_evsel->hists);
294− hists__output_resort_threaded(&top->sym_evsel->hists);
295− hists__decay_entries_threaded(&top->sym_evsel->hists,
296− top->hide_user_symbols,
297− top->hide_kernel_symbols);
290+ hists__collapse_resort(&top->sym_evsel->hists);
291+ hists__output_resort(&top->sym_evsel->hists);
292+ hists__decay_entries(&top->sym_evsel->hists,
293+ top->hide_user_symbols,
294+ top->hide_kernel_symbols);
298295 hists__output_recalc_col_len(&top->sym_evsel->hists,
299− top->winsize.ws_row - 3);
296+ top->print_entries - printed);
300297 putchar('\n');
301298 hists__fprintf(&top->sym_evsel->hists, false,
302− top->winsize.ws_row - 4 - printed, win_width, stdout);
299+ top->print_entries - printed, win_width,
300+ top->min_percent, stdout);
303301 }
304302
305303 static void prompt_integer(int *target, const char *msg)
@@ -477,7 +475,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) · 171 unmodified lines
477475 perf_top__sig_winch(SIGWINCH, NULL, top);
478476 sigaction(SIGWINCH, &act, NULL);
479477 } else {
480− perf_top__sig_winch(SIGWINCH, NULL, top);
481478 signal(SIGWINCH, SIG_DFL);
482479 }
483480 break;
@@ -556,11 +553,11 @@ static void perf_top__sort_new_samples(void *arg) · 72 unmodified lines
556553 if (t->evlist->selected != NULL)
557554 t->sym_evsel = t->evlist->selected;
558555
559− hists__collapse_resort_threaded(&t->sym_evsel->hists);
560− hists__output_resort_threaded(&t->sym_evsel->hists);
561− hists__decay_entries_threaded(&t->sym_evsel->hists,
562− t->hide_user_symbols,
563− t->hide_kernel_symbols);
556+ hists__collapse_resort(&t->sym_evsel->hists);
557+ hists__output_resort(&t->sym_evsel->hists);
558+ hists__decay_entries(&t->sym_evsel->hists,
559+ t->hide_user_symbols,
560+ t->hide_kernel_symbols);
564561 }
565562
566563 static void *display_thread_tui(void *arg)
@@ -584,7 +581,7 @@ static void *display_thread_tui(void *arg) · 17 unmodified lines
584581 list_for_each_entry(pos, &top->evlist->entries, node)
585582 pos->hists.uid_filter_str = top->record_opts.target.uid_str;
586583
587− perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
584+ perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
588585 &top->session->header.env);
589586
590587 done = 1;
@@ -794,7 +791,7 @@ static void perf_event__process_sample(struct perf_tool *tool, · 203 unmodified lines
794791 return;
795792 }
796793
797− if (top->sort_has_symbols)
794+ if (sort__has_sym)
798795 perf_top__record_precise_ip(top, he, evsel->idx, ip);
799796 }
800797
@@ -912,9 +909,9 @@ out_err: · 111 unmodified lines
912909 return -1;
913910 }
914911
915−static int perf_top__setup_sample_type(struct perf_top *top)
912+static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
916913 {
917− if (!top->sort_has_symbols) {
914+ if (!sort__has_sym) {
918915 if (symbol_conf.use_callchain) {
919916 ui__error("Selected -g but \"sym\" not present in --sort/-s.");
920917 return -EINVAL;
@@ -1025,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) · 104 unmodified lines
10251022 return record_parse_callchain_opt(opt, arg, unset);
10261023 }
10271024
1025+static int
1026+parse_percent_limit(const struct option *opt, const char *arg,
1027+ int unset __maybe_unused)
1028+{
1029+ struct perf_top *top = opt->value;
1030+
1031+ top->min_percent = strtof(arg, NULL);
1032+ return 0;
1033+}
1034+
10281035 int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
10291036 {
10301037 int status;
@@ -1110,6 +1117,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 79 unmodified lines
11101117 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
11111118 "Specify disassembler style (e.g. -M intel for intel syntax)"),
11121119 OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"),
1120+ OPT_CALLBACK(0, "percent-limit", &top, "percent",
1121+ "Don't show entries under that percent", parse_percent_limit),
11131122 OPT_END()
11141123 };
11151124 const char * const top_usage[] = {
@@ -1133,6 +1142,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 17 unmodified lines
11331142 if (setup_sorting() < 0)
11341143 usage_with_options(top_usage, options);
11351144
1145+ /* display thread wants entries to be collapsed in a different tree */
1146+ sort__need_collapse = 1;
1147+
11361148 if (top.use_stdio)
11371149 use_browser = 0;
11381150 else if (top.use_tui)
@@ -1200,15 +1212,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) · 61 unmodified lines
12001212 if (symbol__init() < 0)
12011213 return -1;
12021214
1203− sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
1204− sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
1205− sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
1206−
1207− /*
1208− * Avoid annotation data structures overhead when symbols aren't on the
1209− * sort list.
1210− */
1211− top.sort_has_symbols = sort_sym.list.next != NULL;
1215+ sort__setup_elide(stdout);
12121216
12131217 get_term_dimensions(&top.winsize);
12141218 if (top.print_entries == 0) {
tools/perf/config/Makefile+477−0
@@ -0,0 +1,477 @@
1+uname_M := $(shell uname -m 2>/dev/null || echo not)
2+
3+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
4+ -e s/arm.*/arm/ -e s/sa110/arm/ \
5+ -e s/s390x/s390/ -e s/parisc64/parisc/ \
6+ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
7+ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
8+NO_PERF_REGS := 1
9+CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
10+
11+# Additional ARCH settings for x86
12+ifeq ($(ARCH),i386)
13+ override ARCH := x86
14+ NO_PERF_REGS := 0
15+ LIBUNWIND_LIBS = -lunwind -lunwind-x86
16+endif
17+
18+ifeq ($(ARCH),x86_64)
19+ override ARCH := x86
20+ IS_X86_64 := 0
21+ ifeq (, $(findstring m32,$(CFLAGS)))
22+ IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
23+ endif
24+ ifeq (${IS_X86_64}, 1)
25+ RAW_ARCH := x86_64
26+ CFLAGS += -DARCH_X86_64
27+ ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
28+ endif
29+ NO_PERF_REGS := 0
30+ LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
31+endif
32+
33+ifeq ($(NO_PERF_REGS),0)
34+ CFLAGS += -DHAVE_PERF_REGS
35+endif
36+
37+ifeq ($(src-perf),)
38+src-perf := $(srctree)/tools/perf
39+endif
40+
41+ifeq ($(obj-perf),)
42+obj-perf := $(objtree)
43+endif
44+
45+ifneq ($(obj-perf),)
46+obj-perf := $(abspath $(obj-perf))/
47+endif
48+
49+# include ARCH specific config
50+-include $(src-perf)/arch/$(ARCH)/Makefile
51+
52+include $(src-perf)/config/feature-tests.mak
53+include $(src-perf)/config/utilities.mak
54+
55+ifeq ($(call get-executable,$(FLEX)),)
56+ dummy := $(error Error: $(FLEX) is missing on this system, please install it)
57+endif
58+
59+ifeq ($(call get-executable,$(BISON)),)
60+ dummy := $(error Error: $(BISON) is missing on this system, please install it)
61+endif
62+
63+# Treat warnings as errors unless directed not to
64+ifneq ($(WERROR),0)
65+ CFLAGS += -Werror
66+endif
67+
68+ifeq ("$(origin DEBUG)", "command line")
69+ PERF_DEBUG = $(DEBUG)
70+endif
71+ifndef PERF_DEBUG
72+ CFLAGS += -O6
73+endif
74+
75+ifdef PARSER_DEBUG
76+ PARSER_DEBUG_BISON := -t
77+ PARSER_DEBUG_FLEX := -d
78+ CFLAGS += -DPARSER_DEBUG
79+endif
80+
81+CFLAGS += -fno-omit-frame-pointer
82+CFLAGS += -ggdb3
83+CFLAGS += -funwind-tables
84+CFLAGS += -Wall
85+CFLAGS += -Wextra
86+CFLAGS += -std=gnu99
87+
88+EXTLIBS = -lpthread -lrt -lelf -lm
89+
90+ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
91+ CFLAGS += -fstack-protector-all
92+endif
93+
94+ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
95+ CFLAGS += -Wstack-protector
96+endif
97+
98+ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
99+ CFLAGS += -Wvolatile-register-var
100+endif
101+
102+ifndef PERF_DEBUG
103+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
104+ CFLAGS += -D_FORTIFY_SOURCE=2
105+ endif
106+endif
107+
108+CFLAGS += -I$(src-perf)/util/include
109+CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
110+CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi
111+CFLAGS += -I$(srctree)/arch/$(ARCH)/include
112+CFLAGS += -I$(srctree)/include/uapi
113+CFLAGS += -I$(srctree)/include
114+
115+# $(obj-perf) for generated common-cmds.h
116+# $(obj-perf)/util for generated bison/flex headers
117+ifneq ($(OUTPUT),)
118+CFLAGS += -I$(obj-perf)/util
119+CFLAGS += -I$(obj-perf)
120+endif
121+
122+CFLAGS += -I$(src-perf)/util
123+CFLAGS += -I$(src-perf)
124+CFLAGS += -I$(TRACE_EVENT_DIR)
125+CFLAGS += -I$(srctree)/tools/lib/
126+
127+CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
128+
129+ifndef NO_BIONIC
130+ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
131+ BIONIC := 1
132+ EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
133+ EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
134+endif
135+endif # NO_BIONIC
136+
137+ifdef NO_LIBELF
138+ NO_DWARF := 1
139+ NO_DEMANGLE := 1
140+ NO_LIBUNWIND := 1
141+else
142+FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
143+ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
144+ FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
145+ ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
146+ LIBC_SUPPORT := 1
147+ endif
148+ ifeq ($(BIONIC),1)
149+ LIBC_SUPPORT := 1
150+ endif
151+ ifeq ($(LIBC_SUPPORT),1)
152+ msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
153+
154+ NO_LIBELF := 1
155+ NO_DWARF := 1
156+ NO_DEMANGLE := 1
157+ else
158+ msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
159+ endif
160+else
161+ # for linking with debug library, run like:
162+ # make DEBUG=1 LIBDW_DIR=/opt/libdw/
163+ ifdef LIBDW_DIR
164+ LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
165+ LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
166+ endif
167+
168+ FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
169+ ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
170+ msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
171+ NO_DWARF := 1
172+ endif # Dwarf support
173+endif # SOURCE_LIBELF
174+endif # NO_LIBELF
175+
176+ifndef NO_LIBELF
177+CFLAGS += -DLIBELF_SUPPORT
178+FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
179+ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
180+ CFLAGS += -DLIBELF_MMAP
181+endif
182+
183+# include ARCH specific config
184+-include $(src-perf)/arch/$(ARCH)/Makefile
185+
186+ifndef NO_DWARF
187+ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
188+ msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
189+ NO_DWARF := 1
190+else
191+ CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
192+ LDFLAGS += $(LIBDW_LDFLAGS)
193+ EXTLIBS += -lelf -ldw
194+endif # PERF_HAVE_DWARF_REGS
195+endif # NO_DWARF
196+
197+endif # NO_LIBELF
198+
199+ifndef NO_LIBELF
200+CFLAGS += -DLIBELF_SUPPORT
201+FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
202+ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
203+ CFLAGS += -DLIBELF_MMAP
204+endif # try-cc
205+endif # NO_LIBELF
206+
207+# There's only x86 (both 32 and 64) support for CFI unwind so far
208+ifneq ($(ARCH),x86)
209+ NO_LIBUNWIND := 1
210+endif
211+
212+ifndef NO_LIBUNWIND
213+# for linking with debug library, run like:
214+# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
215+ifdef LIBUNWIND_DIR
216+ LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
217+ LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
218+endif
219+
220+FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
221+ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
222+ msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
223+ NO_LIBUNWIND := 1
224+endif # Libunwind support
225+endif # NO_LIBUNWIND
226+
227+ifndef NO_LIBUNWIND
228+ CFLAGS += -DLIBUNWIND_SUPPORT
229+ EXTLIBS += $(LIBUNWIND_LIBS)
230+ CFLAGS += $(LIBUNWIND_CFLAGS)
231+ LDFLAGS += $(LIBUNWIND_LDFLAGS)
232+endif # NO_LIBUNWIND
233+
234+ifndef NO_LIBAUDIT
235+ FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
236+ ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
237+ msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
238+ NO_LIBAUDIT := 1
239+ else
240+ CFLAGS += -DLIBAUDIT_SUPPORT
241+ EXTLIBS += -laudit
242+ endif
243+endif
244+
245+ifdef NO_NEWT
246+ NO_SLANG=1
247+endif
248+
249+ifndef NO_SLANG
250+ FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
251+ ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
252+ msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
253+ NO_SLANG := 1
254+ else
255+ # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
256+ CFLAGS += -I/usr/include/slang
257+ CFLAGS += -DSLANG_SUPPORT
258+ EXTLIBS += -lslang
259+ endif
260+endif
261+
262+ifndef NO_GTK2
263+ FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
264+ ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
265+ msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
266+ NO_GTK2 := 1
267+ else
268+ ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
269+ CFLAGS += -DHAVE_GTK_INFO_BAR
270+ endif
271+ CFLAGS += -DGTK2_SUPPORT
272+ CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
273+ EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
274+ endif
275+endif
276+
277+grep-libs = $(filter -l%,$(1))
278+strip-libs = $(filter-out -l%,$(1))
279+
280+ifdef NO_LIBPERL
281+ CFLAGS += -DNO_LIBPERL
282+else
283+ PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
284+ PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
285+ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
286+ PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
287+ FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
288+
289+ ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
290+ CFLAGS += -DNO_LIBPERL
291+ NO_LIBPERL := 1
292+ else
293+ LDFLAGS += $(PERL_EMBED_LDFLAGS)
294+ EXTLIBS += $(PERL_EMBED_LIBADD)
295+ endif
296+endif
297+
298+disable-python = $(eval $(disable-python_code))
299+define disable-python_code
300+ CFLAGS += -DNO_LIBPYTHON
301+ $(if $(1),$(warning No $(1) was found))
302+ $(warning Python support will not be built)
303+ NO_LIBPYTHON := 1
304+endef
305+
306+override PYTHON := \
307+ $(call get-executable-or-default,PYTHON,python)
308+
309+ifndef PYTHON
310+ $(call disable-python,python interpreter)
311+else
312+
313+ PYTHON_WORD := $(call shell-wordify,$(PYTHON))
314+
315+ ifdef NO_LIBPYTHON
316+ $(call disable-python)
317+ else
318+
319+ override PYTHON_CONFIG := \
320+ $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
321+
322+ ifndef PYTHON_CONFIG
323+ $(call disable-python,python-config tool)
324+ else
325+
326+ PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
327+
328+ PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
329+ PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
330+ PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
331+ PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
332+ FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
333+
334+ ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
335+ $(call disable-python,Python.h (for Python 2.x))
336+ else
337+
338+ ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
339+ $(warning Python 3 is not yet supported; please set)
340+ $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
341+ $(warning If you also have Python 2 installed, then)
342+ $(warning try something like:)
343+ $(warning $(and ,))
344+ $(warning $(and ,) make PYTHON=python2)
345+ $(warning $(and ,))
346+ $(warning Otherwise, disable Python support entirely:)
347+ $(warning $(and ,))
348+ $(warning $(and ,) make NO_LIBPYTHON=1)
349+ $(warning $(and ,))
350+ $(error $(and ,))
351+ else
352+ LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
353+ EXTLIBS += $(PYTHON_EMBED_LIBADD)
354+ LANG_BINDINGS += $(obj-perf)python/perf.so
355+ endif
356+ endif
357+ endif
358+ endif
359+endif
360+
361+ifdef NO_DEMANGLE
362+ CFLAGS += -DNO_DEMANGLE
363+else
364+ ifdef HAVE_CPLUS_DEMANGLE
365+ EXTLIBS += -liberty
366+ CFLAGS += -DHAVE_CPLUS_DEMANGLE
367+ else
368+ FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
369+ has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
370+ ifeq ($(has_bfd),y)
371+ EXTLIBS += -lbfd
372+ else
373+ FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
374+ has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
375+ ifeq ($(has_bfd_iberty),y)
376+ EXTLIBS += -lbfd -liberty
377+ else
378+ FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
379+ has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
380+ ifeq ($(has_bfd_iberty_z),y)
381+ EXTLIBS += -lbfd -liberty -lz
382+ else
383+ FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
384+ has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
385+ ifeq ($(has_cplus_demangle),y)
386+ EXTLIBS += -liberty
387+ CFLAGS += -DHAVE_CPLUS_DEMANGLE
388+ else
389+ msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
390+ CFLAGS += -DNO_DEMANGLE
391+ endif
392+ endif
393+ endif
394+ endif
395+ endif
396+endif
397+
398+ifndef NO_STRLCPY
399+ ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
400+ CFLAGS += -DHAVE_STRLCPY
401+ endif
402+endif
403+
404+ifndef NO_ON_EXIT
405+ ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
406+ CFLAGS += -DHAVE_ON_EXIT
407+ endif
408+endif
409+
410+ifndef NO_BACKTRACE
411+ ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
412+ CFLAGS += -DBACKTRACE_SUPPORT
413+ endif
414+endif
415+
416+ifndef NO_LIBNUMA
417+ FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
418+ ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
419+ msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
420+ NO_LIBNUMA := 1
421+ else
422+ CFLAGS += -DLIBNUMA_SUPPORT
423+ EXTLIBS += -lnuma
424+ endif
425+endif
426+
427+# Among the variables below, these:
428+# perfexecdir
429+# template_dir
430+# mandir
431+# infodir
432+# htmldir
433+# ETC_PERFCONFIG (but not sysconfdir)
434+# can be specified as a relative path some/where/else;
435+# this is interpreted as relative to $(prefix) and "perf" at
436+# runtime figures out where they are based on the path to the executable.
437+# This can help installing the suite in a relocatable way.
438+
439+# Make the path relative to DESTDIR, not to prefix
440+ifndef DESTDIR
441+prefix = $(HOME)
442+endif
443+bindir_relative = bin
444+bindir = $(prefix)/$(bindir_relative)
445+mandir = share/man
446+infodir = share/info
447+perfexecdir = libexec/perf-core
448+sharedir = $(prefix)/share
449+template_dir = share/perf-core/templates
450+htmldir = share/doc/perf-doc
451+ifeq ($(prefix),/usr)
452+sysconfdir = /etc
453+ETC_PERFCONFIG = $(sysconfdir)/perfconfig
454+else
455+sysconfdir = $(prefix)/etc
456+ETC_PERFCONFIG = etc/perfconfig
457+endif
458+lib = lib
459+
460+# Shell quote (do not use $(call) to accommodate ancient setups);
461+ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
462+DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
463+bindir_SQ = $(subst ','\'',$(bindir))
464+mandir_SQ = $(subst ','\'',$(mandir))
465+infodir_SQ = $(subst ','\'',$(infodir))
466+perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
467+template_dir_SQ = $(subst ','\'',$(template_dir))
468+htmldir_SQ = $(subst ','\'',$(htmldir))
469+prefix_SQ = $(subst ','\'',$(prefix))
470+sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
471+
472+ifneq ($(filter /%,$(firstword $(perfexecdir))),)
473+perfexec_instdir = $(perfexecdir)
474+else
475+perfexec_instdir = $(prefix)/$(perfexecdir)
476+endif
477+perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
tools/perf/tests/attr/base-record+2−2
@@ -27,8 +27,8 @@ watermark=0 · 26 unmodified lines
2727 precise_ip=0
2828 mmap_data=0
2929 sample_id_all=1
30−exclude_host=0
31−exclude_guest=1
30+exclude_host=0|1
31+exclude_guest=0|1
3232 exclude_callchain_kernel=0
3333 exclude_callchain_user=0
3434 wakeup_events=0
tools/perf/tests/attr/base-stat+2−2
@@ -27,8 +27,8 @@ watermark=0 · 26 unmodified lines
2727 precise_ip=0
2828 mmap_data=0
2929 sample_id_all=0
30−exclude_host=0
31−exclude_guest=1
30+exclude_host=0|1
31+exclude_guest=0|1
3232 exclude_callchain_kernel=0
3333 exclude_callchain_user=0
3434 wakeup_events=0
tools/perf/tests/attr/test-record-data+4−1
@@ -4,5 +4,8 @@ args = -d kill >/dev/null 2>&1 · 3 unmodified lines
44
55 [event:base-record]
66 sample_period=4000
7−sample_type=271
7+
8+# sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
9+# PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC
10+sample_type=33039
811 mmap_data=1
tools/perf/tests/bp_signal.c+6−0
@@ -4,6 +4,12 @@ · 3 unmodified lines
44 * (git://github.com/deater/perf_event_tests)
55 */
66
7+/*
8+ * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
9+ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
10+ */
11+#define __SANE_USERSPACE_TYPES__
12+
713 #include <stdlib.h>
814 #include <stdio.h>
915 #include <unistd.h>
tools/perf/tests/bp_signal_overflow.c+6−0
@@ -3,6 +3,12 @@ · 2 unmodified lines
33 * perf_event_tests (git://github.com/deater/perf_event_tests)
44 */
55
6+/*
7+ * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
8+ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
9+ */
10+#define __SANE_USERSPACE_TYPES__
11+
612 #include <stdlib.h>
713 #include <stdio.h>
814 #include <unistd.h>
tools/perf/tests/builtin-test.c+1−1
@@ -70,7 +70,7 @@ static struct test { · 69 unmodified lines
7070 .func = test__attr,
7171 },
7272 {
73− .desc = "Test matching and linking mutliple hists",
73+ .desc = "Test matching and linking multiple hists",
7474 .func = test__hists_link,
7575 },
7676 {
tools/perf/tests/make+138−0
@@ -0,0 +1,138 @@
1+PERF := .
2+MK := Makefile
3+
4+# standard single make variable specified
5+make_clean_all := clean all
6+make_python_perf_so := python/perf.so
7+make_debug := DEBUG=1
8+make_no_libperl := NO_LIBPERL=1
9+make_no_libpython := NO_LIBPYTHON=1
10+make_no_scripts := NO_LIBPYTHON=1 NO_LIBPERL=1
11+make_no_newt := NO_NEWT=1
12+make_no_slang := NO_SLANG=1
13+make_no_gtk2 := NO_GTK2=1
14+make_no_ui := NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
15+make_no_demangle := NO_DEMANGLE=1
16+make_no_libelf := NO_LIBELF=1
17+make_no_libunwind := NO_LIBUNWIND=1
18+make_no_backtrace := NO_BACKTRACE=1
19+make_no_libnuma := NO_LIBNUMA=1
20+make_no_libaudit := NO_LIBAUDIT=1
21+make_no_libbionic := NO_LIBBIONIC=1
22+make_tags := tags
23+make_cscope := cscope
24+make_help := help
25+make_doc := doc
26+make_perf_o := perf.o
27+make_util_map_o := util/map.o
28+
29+# all the NO_* variable combined
30+make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
31+make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
32+make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
33+
34+# $(run) contains all available tests
35+run := make_pure
36+run += make_clean_all
37+run += make_python_perf_so
38+run += make_debug
39+run += make_no_libperl
40+run += make_no_libpython
41+run += make_no_scripts
42+run += make_no_newt
43+run += make_no_slang
44+run += make_no_gtk2
45+run += make_no_ui
46+run += make_no_demangle
47+run += make_no_libelf
48+run += make_no_libunwind
49+run += make_no_backtrace
50+run += make_no_libnuma
51+run += make_no_libaudit
52+run += make_no_libbionic
53+run += make_tags
54+run += make_cscope
55+run += make_help
56+run += make_doc
57+run += make_perf_o
58+run += make_util_map_o
59+run += make_minimal
60+
61+# $(run_O) contains same portion of $(run) tests with '_O' attached
62+# to distinguish O=... tests
63+run_O := $(addsuffix _O,$(run))
64+
65+# disable some tests for O=...
66+run_O := $(filter-out make_python_perf_so_O,$(run_O))
67+
68+# define test for each compile as 'test_NAME' variable
69+# with the test itself as a value
70+test_make_tags = test -f tags
71+test_make_cscope = test -f cscope.out
72+
73+test_make_tags_O := $(test_make_tags)
74+test_make_cscope_O := $(test_make_cscope)
75+
76+test_ok := true
77+test_make_help := $(test_ok)
78+test_make_doc := $(test_ok)
79+test_make_help_O := $(test_ok)
80+test_make_doc_O := $(test_ok)
81+
82+test_make_python_perf_so := test -f $(PERF)/python/perf.so
83+
84+test_make_perf_o := test -f $(PERF)/perf.o
85+test_make_util_map_o := test -f $(PERF)/util/map.o
86+
87+# Kbuild tests only
88+#test_make_python_perf_so_O := test -f $$TMP/tools/perf/python/perf.so
89+#test_make_perf_o_O := test -f $$TMP/tools/perf/perf.o
90+#test_make_util_map_o_O := test -f $$TMP/tools/perf/util/map.o
91+
92+test_make_perf_o_O := true
93+test_make_util_map_o_O := true
94+
95+test_default = test -x $(PERF)/perf
96+test = $(if $(test_$1),$(test_$1),$(test_default))
97+
98+test_default_O = test -x $$TMP/perf
99+test_O = $(if $(test_$1),$(test_$1),$(test_default_O))
100+
101+all:
102+
103+ifdef DEBUG
104+d := $(info run $(run))
105+d := $(info run_O $(run_O))
106+endif
107+
108+MAKEFLAGS := --no-print-directory
109+
110+clean := @(cd $(PERF); make -s -f $(MK) clean >/dev/null)
111+
112+$(run):
113+ $(call clean)
114+ @cmd="cd $(PERF) && make -f $(MK) $($@)"; \
115+ echo "- $@: $$cmd" && echo $$cmd > $@ && \
116+ ( eval $$cmd ) >> $@ 2>&1; \
117+ echo " test: $(call test,$@)"; \
118+ $(call test,$@) && \
119+ rm -f $@
120+
121+$(run_O):
122+ $(call clean)
123+ @TMP=$$(mktemp -d); \
124+ cmd="cd $(PERF) && make -f $(MK) $($(patsubst %_O,%,$@)) O=$$TMP"; \
125+ echo "- $@: $$cmd" && echo $$cmd > $@ && \
126+ ( eval $$cmd ) >> $@ 2>&1 && \
127+ echo " test: $(call test_O,$@)"; \
128+ $(call test_O,$@) && \
129+ rm -f $@ && \
130+ rm -rf $$TMP
131+
132+all: $(run) $(run_O)
133+ @echo OK
134+
135+out: $(run_O)
136+ @echo OK
137+
138+.PHONY: all $(run) $(run_O) clean
tools/perf/ui/browsers/hists.c+85−21
@@ -25,7 +25,8 @@ struct hist_browser { · 24 unmodified lines
2525 struct map_symbol *selection;
2626 int print_seq;
2727 bool show_dso;
28− bool has_symbols;
28+ float min_pcnt;
29+ u64 nr_pcnt_entries;
2930 };
3031
3132 extern void hist_browser__init_hpp(void);
@@ -309,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser) · 277 unmodified lines
309310 "Or reduce the sampling frequency.");
310311 }
311312
313+static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
314+
312315 static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
313316 struct hist_browser_timer *hbt)
314317 {
@@ -318,6 +321,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, · 3 unmodified lines
318321
319322 browser->b.entries = &browser->hists->entries;
320323 browser->b.nr_entries = browser->hists->nr_entries;
324+ if (browser->min_pcnt)
325+ browser->b.nr_entries = browser->nr_pcnt_entries;
321326
322327 hist_browser__refresh_dimensions(browser);
323328 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
@@ -330,9 +335,18 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, · 6 unmodified lines
330335 key = ui_browser__run(&browser->b, delay_secs);
331336
332337 switch (key) {
333− case K_TIMER:
338+ case K_TIMER: {
339+ u64 nr_entries;
334340 hbt->timer(hbt->arg);
335− ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
341+
342+ if (browser->min_pcnt) {
343+ hist_browser__update_pcnt_entries(browser);
344+ nr_entries = browser->nr_pcnt_entries;
345+ } else {
346+ nr_entries = browser->hists->nr_entries;
347+ }
348+
349+ ui_browser__update_nr_entries(&browser->b, nr_entries);
336350
337351 if (browser->hists->stats.nr_lost_warned !=
338352 browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
@@ -344,6 +358,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, · 5 unmodified lines
344358 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
345359 ui_browser__show_title(&browser->b, title);
346360 continue;
361+ }
347362 case 'D': { /* Debug */
348363 static int seq;
349364 struct hist_entry *h = rb_entry(browser->b.top,
@@ -796,10 +811,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) · 446 unmodified lines
796811
797812 for (nd = browser->top; nd; nd = rb_next(nd)) {
798813 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
814+ float percent = h->stat.period * 100.0 /
815+ hb->hists->stats.total_period;
799816
800817 if (h->filtered)
801818 continue;
802819
820+ if (percent < hb->min_pcnt)
821+ continue;
822+
803823 row += hist_browser__show_entry(hb, h, row);
804824 if (row == browser->height)
805825 break;
@@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) · 2 unmodified lines
808828 return row;
809829 }
810830
811−static struct rb_node *hists__filter_entries(struct rb_node *nd)
831+static struct rb_node *hists__filter_entries(struct rb_node *nd,
832+ struct hists *hists,
833+ float min_pcnt)
812834 {
813835 while (nd != NULL) {
814836 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
837+ float percent = h->stat.period * 100.0 /
838+ hists->stats.total_period;
839+
840+ if (percent < min_pcnt)
841+ return NULL;
842+
815843 if (!h->filtered)
816844 return nd;
817845
@@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd) · 3 unmodified lines
821849 return NULL;
822850 }
823851
824−static struct rb_node *hists__filter_prev_entries(struct rb_node *nd)
852+static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
853+ struct hists *hists,
854+ float min_pcnt)
825855 {
826856 while (nd != NULL) {
827857 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
828− if (!h->filtered)
858+ float percent = h->stat.period * 100.0 /
859+ hists->stats.total_period;
860+
861+ if (!h->filtered && percent >= min_pcnt)
829862 return nd;
830863
831864 nd = rb_prev(nd);
@@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser, · 8 unmodified lines
840873 struct hist_entry *h;
841874 struct rb_node *nd;
842875 bool first = true;
876+ struct hist_browser *hb;
877+
878+ hb = container_of(browser, struct hist_browser, b);
843879
844880 if (browser->nr_entries == 0)
845881 return;
@@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser, · 2 unmodified lines
848884
849885 switch (whence) {
850886 case SEEK_SET:
851− nd = hists__filter_entries(rb_first(browser->entries));
887+ nd = hists__filter_entries(rb_first(browser->entries),
888+ hb->hists, hb->min_pcnt);
852889 break;
853890 case SEEK_CUR:
854891 nd = browser->top;
855892 goto do_offset;
856893 case SEEK_END:
857− nd = hists__filter_prev_entries(rb_last(browser->entries));
894+ nd = hists__filter_prev_entries(rb_last(browser->entries),
895+ hb->hists, hb->min_pcnt);
858896 first = false;
859897 break;
860898 default:
@@ -897,7 +935,8 @@ do_offset: · 36 unmodified lines
897935 break;
898936 }
899937 }
900− nd = hists__filter_entries(rb_next(nd));
938+ nd = hists__filter_entries(rb_next(nd), hb->hists,
939+ hb->min_pcnt);
901940 if (nd == NULL)
902941 break;
903942 --offset;
@@ -930,7 +969,8 @@ do_offset: · 26 unmodified lines
930969 }
931970 }
932971
933− nd = hists__filter_prev_entries(rb_prev(nd));
972+ nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
973+ hb->min_pcnt);
934974 if (nd == NULL)
935975 break;
936976 ++offset;
@@ -1099,14 +1139,17 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, · 162 unmodified lines
10991139
11001140 static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
11011141 {
1102− struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries));
1142+ struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
1143+ browser->hists,
1144+ browser->min_pcnt);
11031145 int printed = 0;
11041146
11051147 while (nd) {
11061148 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
11071149
11081150 printed += hist_browser__fprintf_entry(browser, h, fp);
1109− nd = hists__filter_entries(rb_next(nd));
1151+ nd = hists__filter_entries(rb_next(nd), browser->hists,
1152+ browser->min_pcnt);
11101153 }
11111154
11121155 return printed;
@@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists) · 42 unmodified lines
11551198 browser->b.refresh = hist_browser__refresh;
11561199 browser->b.seek = ui_browser__hists_seek;
11571200 browser->b.use_navkeypressed = true;
1158− if (sort__branch_mode == 1)
1159− browser->has_symbols = sort_sym_from.list.next != NULL;
1160− else
1161− browser->has_symbols = sort_sym.list.next != NULL;
11621201 }
11631202
11641203 return browser;
@@ -1329,11 +1368,25 @@ close_file_and_continue: · 164 unmodified lines
13291368 return ret;
13301369 }
13311370
1371+static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
1372+{
1373+ u64 nr_entries = 0;
1374+ struct rb_node *nd = rb_first(&hb->hists->entries);
1375+
1376+ while (nd) {
1377+ nr_entries++;
1378+ nd = hists__filter_entries(rb_next(nd), hb->hists,
1379+ hb->min_pcnt);
1380+ }
1381+
1382+ hb->nr_pcnt_entries = nr_entries;
1383+}
13321384
13331385 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
13341386 const char *helpline, const char *ev_name,
13351387 bool left_exits,
13361388 struct hist_browser_timer *hbt,
1389+ float min_pcnt,
13371390 struct perf_session_env *env)
13381391 {
13391392 struct hists *hists = &evsel->hists;
@@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, · 10 unmodified lines
13501403 if (browser == NULL)
13511404 return -1;
13521405
1406+ if (min_pcnt) {
1407+ browser->min_pcnt = min_pcnt;
1408+ hist_browser__update_pcnt_entries(browser);
1409+ }
1410+
13531411 fstack = pstack__new(2);
13541412 if (fstack == NULL)
13551413 goto out;
@@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, · 30 unmodified lines
13861444 */
13871445 goto out_free_stack;
13881446 case 'a':
1389− if (!browser->has_symbols) {
1447+ if (!sort__has_sym) {
13901448 ui_browser__warning(&browser->b, delay_secs * 2,
13911449 "Annotation is only available for symbolic views, "
13921450 "include \"sym*\" in --sort to use it.");
@@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, · 92 unmodified lines
14851543 continue;
14861544 }
14871545
1488− if (!browser->has_symbols)
1546+ if (!sort__has_sym)
14891547 goto add_exit_option;
14901548
1491− if (sort__branch_mode == 1) {
1549+ if (sort__mode == SORT_MODE__BRANCH) {
14921550 bi = browser->he_selection->branch_info;
14931551 if (browser->selection != NULL &&
14941552 bi &&
@@ -1689,6 +1747,7 @@ struct perf_evsel_menu { · 194 unmodified lines
16891747 struct ui_browser b;
16901748 struct perf_evsel *selection;
16911749 bool lost_events, lost_events_warned;
1750+ float min_pcnt;
16921751 struct perf_session_env *env;
16931752 };
16941753
@@ -1782,6 +1841,7 @@ browse_hists: · 87 unmodified lines
17821841 ev_name = perf_evsel__name(pos);
17831842 key = perf_evsel__hists_browse(pos, nr_events, help,
17841843 ev_name, true, hbt,
1844+ menu->min_pcnt,
17851845 menu->env);
17861846 ui_browser__show_title(&menu->b, title);
17871847 switch (key) {
@@ -1843,6 +1903,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused, · 55 unmodified lines
18431903 static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
18441904 int nr_entries, const char *help,
18451905 struct hist_browser_timer *hbt,
1906+ float min_pcnt,
18461907 struct perf_session_env *env)
18471908 {
18481909 struct perf_evsel *pos;
@@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, · 7 unmodified lines
18561917 .nr_entries = nr_entries,
18571918 .priv = evlist,
18581919 },
1920+ .min_pcnt = min_pcnt,
18591921 .env = env,
18601922 };
18611923
@@ -1874,6 +1936,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, · 12 unmodified lines
18741936
18751937 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
18761938 struct hist_browser_timer *hbt,
1939+ float min_pcnt,
18771940 struct perf_session_env *env)
18781941 {
18791942 int nr_entries = evlist->nr_entries;
@@ -1885,7 +1948,8 @@ single_entry: · 5 unmodified lines
18851948 const char *ev_name = perf_evsel__name(first);
18861949
18871950 return perf_evsel__hists_browse(first, nr_entries, help,
1888− ev_name, false, hbt, env);
1951+ ev_name, false, hbt, min_pcnt,
1952+ env);
18891953 }
18901954
18911955 if (symbol_conf.event_group) {
@@ -1901,5 +1965,5 @@ single_entry: · 9 unmodified lines
19011965 }
19021966
19031967 return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
1904− hbt, env);
1968+ hbt, min_pcnt, env);
19051969 }
tools/perf/ui/gtk/hists.c+10−3
@@ -124,7 +124,8 @@ void perf_gtk__init_hpp(void) · 123 unmodified lines
124124 perf_gtk__hpp_color_overhead_guest_us;
125125 }
126126
127−static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
127+static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
128+ float min_pcnt)
128129 {
129130 struct perf_hpp_fmt *fmt;
130131 GType col_types[MAX_COLUMNS];
@@ -189,10 +190,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) · 58 unmodified lines
189190 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
190191 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
191192 GtkTreeIter iter;
193+ float percent = h->stat.period * 100.0 /
194+ hists->stats.total_period;
192195
193196 if (h->filtered)
194197 continue;
195198
199+ if (percent < min_pcnt)
200+ continue;
201+
196202 gtk_list_store_append(store, &iter);
197203
198204 col_idx = 0;
@@ -222,7 +228,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) · 23 unmodified lines
222228
223229 int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
224230 const char *help,
225− struct hist_browser_timer *hbt __maybe_unused)
231+ struct hist_browser_timer *hbt __maybe_unused,
232+ float min_pcnt)
226233 {
227234 struct perf_evsel *pos;
228235 GtkWidget *vbox;
@@ -286,7 +293,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, · 57 unmodified lines
286293 GTK_POLICY_AUTOMATIC,
287294 GTK_POLICY_AUTOMATIC);
288295
289− perf_gtk__show_hists(scrolled_window, hists);
296+ perf_gtk__show_hists(scrolled_window, hists, min_pcnt);
290297
291298 tab_label = gtk_label_new(evname);
292299
tools/perf/ui/stdio/hist.c+6−1
@@ -334,7 +334,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, · 333 unmodified lines
334334 }
335335
336336 size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
337− int max_cols, FILE *fp)
337+ int max_cols, float min_pcnt, FILE *fp)
338338 {
339339 struct perf_hpp_fmt *fmt;
340340 struct sort_entry *se;
@@ -440,10 +440,15 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, · 99 unmodified lines
440440 print_entries:
441441 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
442442 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
443+ float percent = h->stat.period * 100.0 /
444+ hists->stats.total_period;
443445
444446 if (h->filtered)
445447 continue;
446448
449+ if (percent < min_pcnt)
450+ continue;
451+
447452 ret += hist_entry__fprintf(h, max_cols, hists, fp);
448453
449454 if (max_rows && ++nr_rows >= max_rows)
tools/perf/util/evlist.c+2−0
@@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, · 775 unmodified lines
776776 if (pipe_output)
777777 dup2(2, 1);
778778
779+ signal(SIGTERM, SIG_DFL);
780+
779781 close(child_ready_pipe[0]);
780782 close(go_pipe[1]);
781783 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
tools/perf/util/evsel.c+1−1
@@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, · 1513 unmodified lines
15141514 switch (err) {
15151515 case EPERM:
15161516 case EACCES:
1517− return scnprintf(msg, size, "%s",
1517+ return scnprintf(msg, size,
15181518 "You may not have permission to collect %sstats.\n"
15191519 "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
15201520 " -1 - Not paranoid at all\n"
tools/perf/util/header.c+0−2
@@ -2391,7 +2391,6 @@ out_err_write: · 2390 unmodified lines
23912391 }
23922392 lseek(fd, header->data_offset + header->data_size, SEEK_SET);
23932393
2394− header->frozen = 1;
23952394 return 0;
23962395 }
23972396
@@ -2871,7 +2870,6 @@ int perf_session__read_header(struct perf_session *session, int fd) · 473 unmodified lines
28712870 session->pevent))
28722871 goto out_delete_evlist;
28732872
2874− header->frozen = 1;
28752873 return 0;
28762874 out_errno:
28772875 return -errno;
tools/perf/util/header.h+0−1
@@ -84,7 +84,6 @@ struct perf_session_env { · 83 unmodified lines
8484 };
8585
8686 struct perf_header {
87− int frozen;
8887 bool needs_swap;
8988 s64 attr_offset;
9089 u64 data_offset;
tools/perf/util/hist.c+42−54
@@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) · 69 unmodified lines
7070 int symlen;
7171 u16 len;
7272
73− if (h->ms.sym)
74− hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4);
75− else {
73+ /*
74+ * +4 accounts for '[x] ' priv level info
75+ * +2 accounts for 0x prefix on raw addresses
76+ * +3 accounts for ' y ' symtab origin info
77+ */
78+ if (h->ms.sym) {
79+ symlen = h->ms.sym->namelen + 4;
80+ if (verbose)
81+ symlen += BITS_PER_LONG / 4 + 2 + 3;
82+ hists__new_col_len(hists, HISTC_SYMBOL, symlen);
83+ } else {
7684 symlen = unresolved_col_width + 4 + 2;
7785 hists__new_col_len(hists, HISTC_SYMBOL, symlen);
7886 hists__set_unres_dso_col_len(hists, HISTC_DSO);
@@ -91,12 +99,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) · 12 unmodified lines
9199 hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
92100
93101 if (h->branch_info) {
94− /*
95− * +4 accounts for '[x] ' priv level info
96− * +2 account of 0x prefix on raw addresses
97− */
98102 if (h->branch_info->from.sym) {
99103 symlen = (int)h->branch_info->from.sym->namelen + 4;
104+ if (verbose)
105+ symlen += BITS_PER_LONG / 4 + 2 + 3;
100106 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
101107
102108 symlen = dso__name_len(h->branch_info->from.map->dso);
@@ -109,6 +115,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) · 6 unmodified lines
109115
110116 if (h->branch_info->to.sym) {
111117 symlen = (int)h->branch_info->to.sym->namelen + 4;
118+ if (verbose)
119+ symlen += BITS_PER_LONG / 4 + 2 + 3;
112120 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
113121
114122 symlen = dso__name_len(h->branch_info->to.map->dso);
@@ -121,10 +129,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) · 6 unmodified lines
121129 }
122130
123131 if (h->mem_info) {
124− /*
125− * +4 accounts for '[x] ' priv level info
126− * +2 account of 0x prefix on raw addresses
127− */
128132 if (h->mem_info->daddr.sym) {
129133 symlen = (int)h->mem_info->daddr.sym->namelen + 4
130134 + unresolved_col_width + 2;
@@ -236,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) · 105 unmodified lines
236240 return he->stat.period == 0;
237241 }
238242
239−static void __hists__decay_entries(struct hists *hists, bool zap_user,
240− bool zap_kernel, bool threaded)
243+void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
241244 {
242245 struct rb_node *next = rb_first(&hists->entries);
243246 struct hist_entry *n;
@@ -256,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user, · 12 unmodified lines
256259 !n->used) {
257260 rb_erase(&n->rb_node, &hists->entries);
258261
259− if (sort__need_collapse || threaded)
262+ if (sort__need_collapse)
260263 rb_erase(&n->rb_node_in, &hists->entries_collapsed);
261264
262265 hist_entry__free(n);
@@ -265,17 +268,6 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user, · 2 unmodified lines
265268 }
266269 }
267270
268−void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
269−{
270− return __hists__decay_entries(hists, zap_user, zap_kernel, false);
271−}
272−
273−void hists__decay_entries_threaded(struct hists *hists,
274− bool zap_user, bool zap_kernel)
275−{
276− return __hists__decay_entries(hists, zap_user, zap_kernel, true);
277−}
278−
279271 /*
280272 * histogram, sorted on item, collects periods
281273 */
@@ -292,6 +284,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) · 10 unmodified lines
292284 he->ms.map->referenced = true;
293285
294286 if (he->branch_info) {
287+ /*
288+ * This branch info is (a part of) allocated from
289+ * machine__resolve_bstack() and will be freed after
290+ * adding new entries. So we need to save a copy.
291+ */
292+ he->branch_info = malloc(sizeof(*he->branch_info));
293+ if (he->branch_info == NULL) {
294+ free(he);
295+ return NULL;
296+ }
297+
298+ memcpy(he->branch_info, template->branch_info,
299+ sizeof(*he->branch_info));
300+
295301 if (he->branch_info->from.map)
296302 he->branch_info->from.map->referenced = true;
297303 if (he->branch_info->to.map)
@@ -341,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists, · 43 unmodified lines
341347 struct hist_entry *he;
342348 int cmp;
343349
344− pthread_mutex_lock(&hists->lock);
345−
346350 p = &hists->entries_in->rb_node;
347351
348352 while (*p != NULL) {
@@ -360,6 +364,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists, · 11 unmodified lines
360364 if (!cmp) {
361365 he_stat__add_period(&he->stat, period, weight);
362366
367+ /*
368+ * This mem info was allocated from machine__resolve_mem
369+ * and will not be used anymore.
370+ */
371+ free(entry->mem_info);
372+
363373 /* If the map of an existing hist_entry has
364374 * become out-of-date due to an exec() or
365375 * similar, update it. Otherwise we will
@@ -382,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists, · 16 unmodified lines
382392
383393 he = hist_entry__new(entry);
384394 if (!he)
385− goto out_unlock;
395+ return NULL;
386396
387397 rb_link_node(&he->rb_node_in, parent, p);
388398 rb_insert_color(&he->rb_node_in, hists->entries_in);
389399 out:
390400 hist_entry__add_cpumode_period(he, al->cpumode, period);
391−out_unlock:
392− pthread_mutex_unlock(&hists->lock);
393401 return he;
394402 }
395403
@@ -589,13 +597,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he) · 193 unmodified lines
589597 hists__filter_entry_by_symbol(hists, he);
590598 }
591599
592−static void __hists__collapse_resort(struct hists *hists, bool threaded)
600+void hists__collapse_resort(struct hists *hists)
593601 {
594602 struct rb_root *root;
595603 struct rb_node *next;
596604 struct hist_entry *n;
597605
598− if (!sort__need_collapse && !threaded)
606+ if (!sort__need_collapse)
599607 return;
600608
601609 root = hists__get_rotate_entries_in(hists);
@@ -617,16 +625,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded) · 15 unmodified lines
617625 }
618626 }
619627
620−void hists__collapse_resort(struct hists *hists)
621−{
622− return __hists__collapse_resort(hists, false);
623−}
624−
625−void hists__collapse_resort_threaded(struct hists *hists)
626−{
627− return __hists__collapse_resort(hists, true);
628−}
629−
630628 /*
631629 * reverse the map, sort on period.
632630 */
@@ -713,7 +711,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, · 80 unmodified lines
713711 rb_insert_color(&he->rb_node, entries);
714712 }
715713
716−static void __hists__output_resort(struct hists *hists, bool threaded)
714+void hists__output_resort(struct hists *hists)
717715 {
718716 struct rb_root *root;
719717 struct rb_node *next;
@@ -722,7 +720,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded) · 2 unmodified lines
722720
723721 min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
724722
725− if (sort__need_collapse || threaded)
723+ if (sort__need_collapse)
726724 root = &hists->entries_collapsed;
727725 else
728726 root = hists->entries_in;
@@ -743,16 +741,6 @@ static void __hists__output_resort(struct hists *hists, bool threaded) · 14 unmodified lines
743741 }
744742 }
745743
746−void hists__output_resort(struct hists *hists)
747−{
748− return __hists__output_resort(hists, false);
749−}
750−
751−void hists__output_resort_threaded(struct hists *hists)
752−{
753− return __hists__output_resort(hists, true);
754−}
755−
756744 static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
757745 enum hist_filter filter)
758746 {
tools/perf/util/hist.h+8−8
@@ -43,12 +43,12 @@ enum hist_column { · 42 unmodified lines
4343 HISTC_COMM,
4444 HISTC_PARENT,
4545 HISTC_CPU,
46+ HISTC_SRCLINE,
4647 HISTC_MISPREDICT,
4748 HISTC_SYMBOL_FROM,
4849 HISTC_SYMBOL_TO,
4950 HISTC_DSO_FROM,
5051 HISTC_DSO_TO,
51− HISTC_SRCLINE,
5252 HISTC_LOCAL_WEIGHT,
5353 HISTC_GLOBAL_WEIGHT,
5454 HISTC_MEM_DADDR_SYMBOL,
@@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self, · 49 unmodified lines
104104 u64 weight);
105105
106106 void hists__output_resort(struct hists *self);
107−void hists__output_resort_threaded(struct hists *hists);
108107 void hists__collapse_resort(struct hists *self);
109−void hists__collapse_resort_threaded(struct hists *hists);
110108
111109 void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
112−void hists__decay_entries_threaded(struct hists *hists, bool zap_user,
113− bool zap_kernel);
114110 void hists__output_recalc_col_len(struct hists *hists, int max_rows);
115111
116112 void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h);
@@ -119,7 +115,7 @@ void events_stats__inc(struct events_stats *stats, u32 type); · 2 unmodified lines
119115 size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
120116
121117 size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
122− int max_cols, FILE *fp);
118+ int max_cols, float min_pcnt, FILE *fp);
123119
124120 int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
125121 int hist_entry__annotate(struct hist_entry *self, size_t privsize);
@@ -199,6 +195,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, · 73 unmodified lines
199195
200196 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
201197 struct hist_browser_timer *hbt,
198+ float min_pcnt,
202199 struct perf_session_env *env);
203200 int script_browse(const char *script_opt);
204201 #else
@@ -206,6 +203,7 @@ static inline · 1 unmodified line
206203 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
207204 const char *help __maybe_unused,
208205 struct hist_browser_timer *hbt __maybe_unused,
206+ float min_pcnt __maybe_unused,
209207 struct perf_session_env *env __maybe_unused)
210208 {
211209 return 0;
@@ -233,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused) · 21 unmodified lines
233231
234232 #ifdef GTK2_SUPPORT
235233 int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
236− struct hist_browser_timer *hbt __maybe_unused);
234+ struct hist_browser_timer *hbt __maybe_unused,
235+ float min_pcnt);
237236 #else
238237 static inline
239238 int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
240239 const char *help __maybe_unused,
241− struct hist_browser_timer *hbt __maybe_unused)
240+ struct hist_browser_timer *hbt __maybe_unused,
241+ float min_pcnt __maybe_unused)
242242 {
243243 return 0;
244244 }
tools/perf/util/map.c+1−0
@@ -21,6 +21,7 @@ const char *map_type__name[MAP__NR_TYPES] = { · 20 unmodified lines
2121 static inline int is_anon_memory(const char *filename)
2222 {
2323 return !strcmp(filename, "//anon") ||
24+ !strcmp(filename, "/dev/zero (deleted)") ||
2425 !strcmp(filename, "/anon_hugepage (deleted)");
2526 }
2627
tools/perf/util/session.h+0−1
@@ -37,7 +37,6 @@ struct perf_session { · 36 unmodified lines
3737 int fd;
3838 bool fd_pipe;
3939 bool repipe;
40− int cwdlen;
4140 char *cwd;
4241 struct ordered_samples ordered_samples;
4342 char filename[1];
tools/perf/util/setup.py+3−2
@@ -18,8 +18,9 @@ class install_lib(_install_lib): · 17 unmodified lines
1818 self.build_dir = build_lib
1919
2020
21−cflags = ['-fno-strict-aliasing', '-Wno-write-strings']
22−cflags += getenv('CFLAGS', '').split()
21+cflags = getenv('CFLAGS', '').split()
22+# switch off several checks (need to be at the end of cflags list)
23+cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ]
2324
2425 build_lib = getenv('PYTHON_EXTBUILD_LIB')
2526 build_tmp = getenv('PYTHON_EXTBUILD_TMP')
tools/perf/util/sort.c+91−37
@@ -1,5 +1,6 @@
11 #include "sort.h"
22 #include "hist.h"
3+#include "symbol.h"
34
45 regex_t parent_regex;
56 const char default_parent_pattern[] = "^sys_|^do_page_fault";
@@ -9,7 +10,7 @@ const char *sort_order = default_sort_order; · 3 unmodified lines
910 int sort__need_collapse = 0;
1011 int sort__has_parent = 0;
1112 int sort__has_sym = 0;
12−int sort__branch_mode = -1; /* -1 = means not set */
13+enum sort_mode sort__mode = SORT_MODE__NORMAL;
1314
1415 enum sort_type sort__first_dimension;
1516
@@ -194,7 +195,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, · 178 unmodified lines
194195 if (verbose) {
195196 char o = map ? dso__symtab_origin(map->dso) : '!';
196197 ret += repsep_snprintf(bf, size, "%-#*llx %c ",
197− BITS_PER_LONG / 4, ip, o);
198+ BITS_PER_LONG / 4 + 2, ip, o);
198199 }
199200
200201 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
@@ -871,14 +872,6 @@ static struct sort_dimension common_sort_dimensions[] = { · 670 unmodified lines
871872 DIM(SORT_PARENT, "parent", sort_parent),
872873 DIM(SORT_CPU, "cpu", sort_cpu),
873874 DIM(SORT_SRCLINE, "srcline", sort_srcline),
874− DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
875− DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
876− DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
877− DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
878− DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
879− DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
880− DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
881− DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
882875 };
883876
884877 #undef DIM
@@ -895,6 +888,36 @@ static struct sort_dimension bstack_sort_dimensions[] = { · 10 unmodified lines
895888
896889 #undef DIM
897890
891+#define DIM(d, n, func) [d - __SORT_MEMORY_MODE] = { .name = n, .entry = &(func) }
892+
893+static struct sort_dimension memory_sort_dimensions[] = {
894+ DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
895+ DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
896+ DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
897+ DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
898+ DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
899+ DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
900+ DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
901+ DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
902+};
903+
904+#undef DIM
905+
906+static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
907+{
908+ if (sd->taken)
909+ return;
910+
911+ if (sd->entry->se_collapse)
912+ sort__need_collapse = 1;
913+
914+ if (list_empty(&hist_entry__sort_list))
915+ sort__first_dimension = idx;
916+
917+ list_add_tail(&sd->entry->list, &hist_entry__sort_list);
918+ sd->taken = 1;
919+}
920+
898921 int sort_dimension__add(const char *tok)
899922 {
900923 unsigned int i;
@@ -915,25 +938,11 @@ int sort_dimension__add(const char *tok) · 14 unmodified lines
915938 return -EINVAL;
916939 }
917940 sort__has_parent = 1;
918− } else if (sd->entry == &sort_sym ||
919− sd->entry == &sort_sym_from ||
920− sd->entry == &sort_sym_to ||
921− sd->entry == &sort_mem_daddr_sym) {
941+ } else if (sd->entry == &sort_sym) {
922942 sort__has_sym = 1;
923943 }
924944
925− if (sd->taken)
926− return 0;
927−
928− if (sd->entry->se_collapse)
929− sort__need_collapse = 1;
930−
931− if (list_empty(&hist_entry__sort_list))
932− sort__first_dimension = i;
933−
934− list_add_tail(&sd->entry->list, &hist_entry__sort_list);
935− sd->taken = 1;
936−
945+ __sort_dimension__add(sd, i);
937946 return 0;
938947 }
939948
@@ -943,24 +952,29 @@ int sort_dimension__add(const char *tok) · 3 unmodified lines
943952 if (strncasecmp(tok, sd->name, strlen(tok)))
944953 continue;
945954
946− if (sort__branch_mode != 1)
955+ if (sort__mode != SORT_MODE__BRANCH)
947956 return -EINVAL;
948957
949958 if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
950959 sort__has_sym = 1;
951960
952− if (sd->taken)
953− return 0;
961+ __sort_dimension__add(sd, i + __SORT_BRANCH_STACK);
962+ return 0;
963+ }
954964
955− if (sd->entry->se_collapse)
956− sort__need_collapse = 1;
965+ for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
966+ struct sort_dimension *sd = &memory_sort_dimensions[i];
957967
958− if (list_empty(&hist_entry__sort_list))
959− sort__first_dimension = i + __SORT_BRANCH_STACK;
968+ if (strncasecmp(tok, sd->name, strlen(tok)))
969+ continue;
960970
961− list_add_tail(&sd->entry->list, &hist_entry__sort_list);
962− sd->taken = 1;
971+ if (sort__mode != SORT_MODE__MEMORY)
972+ return -EINVAL;
973+
974+ if (sd->entry == &sort_mem_daddr_sym)
975+ sort__has_sym = 1;
963976
977+ __sort_dimension__add(sd, i + __SORT_MEMORY_MODE);
964978 return 0;
965979 }
966980
@@ -993,8 +1007,9 @@ int setup_sorting(void) · 26 unmodified lines
9931007 return ret;
9941008 }
9951009
996−void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
997− const char *list_name, FILE *fp)
1010+static void sort_entry__setup_elide(struct sort_entry *self,
1011+ struct strlist *list,
1012+ const char *list_name, FILE *fp)
9981013 {
9991014 if (list && strlist__nr_entries(list) == 1) {
10001015 if (fp != NULL)
@@ -1003,3 +1018,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, · 2 unmodified lines
10031018 self->elide = true;
10041019 }
10051020 }
1021+
1022+void sort__setup_elide(FILE *output)
1023+{
1024+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1025+ "dso", output);
1026+ sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list,
1027+ "comm", output);
1028+ sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list,
1029+ "symbol", output);
1030+
1031+ if (sort__mode == SORT_MODE__BRANCH) {
1032+ sort_entry__setup_elide(&sort_dso_from,
1033+ symbol_conf.dso_from_list,
1034+ "dso_from", output);
1035+ sort_entry__setup_elide(&sort_dso_to,
1036+ symbol_conf.dso_to_list,
1037+ "dso_to", output);
1038+ sort_entry__setup_elide(&sort_sym_from,
1039+ symbol_conf.sym_from_list,
1040+ "sym_from", output);
1041+ sort_entry__setup_elide(&sort_sym_to,
1042+ symbol_conf.sym_to_list,
1043+ "sym_to", output);
1044+ } else if (sort__mode == SORT_MODE__MEMORY) {
1045+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1046+ "symbol_daddr", output);
1047+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1048+ "dso_daddr", output);
1049+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1050+ "mem", output);
1051+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1052+ "local_weight", output);
1053+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1054+ "tlb", output);
1055+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1056+ "snoop", output);
1057+ }
1058+
1059+}
tools/perf/util/sort.h+22−14
@@ -32,7 +32,7 @@ extern const char default_sort_order[]; · 31 unmodified lines
3232 extern int sort__need_collapse;
3333 extern int sort__has_parent;
3434 extern int sort__has_sym;
35−extern int sort__branch_mode;
35+extern enum sort_mode sort__mode;
3636 extern struct sort_entry sort_comm;
3737 extern struct sort_entry sort_dso;
3838 extern struct sort_entry sort_sym;
@@ -117,12 +117,18 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he) · 78 unmodified lines
117117 return NULL;
118118 }
119119
120−static inline void hist_entry__add_pair(struct hist_entry *he,
121− struct hist_entry *pair)
120+static inline void hist_entry__add_pair(struct hist_entry *pair,
121+ struct hist_entry *he)
122122 {
123− list_add_tail(&he->pairs.head, &pair->pairs.node);
123+ list_add_tail(&pair->pairs.node, &he->pairs.head);
124124 }
125125
126+enum sort_mode {
127+ SORT_MODE__NORMAL,
128+ SORT_MODE__BRANCH,
129+ SORT_MODE__MEMORY,
130+};
131+
126132 enum sort_type {
127133 /* common sort keys */
128134 SORT_PID,
@@ -132,14 +138,6 @@ enum sort_type { · 3 unmodified lines
132138 SORT_PARENT,
133139 SORT_CPU,
134140 SORT_SRCLINE,
135− SORT_LOCAL_WEIGHT,
136− SORT_GLOBAL_WEIGHT,
137− SORT_MEM_DADDR_SYMBOL,
138− SORT_MEM_DADDR_DSO,
139− SORT_MEM_LOCKED,
140− SORT_MEM_TLB,
141− SORT_MEM_LVL,
142− SORT_MEM_SNOOP,
143141
144142 /* branch stack specific sort keys */
145143 __SORT_BRANCH_STACK,
@@ -148,6 +146,17 @@ enum sort_type { · 2 unmodified lines
148146 SORT_SYM_FROM,
149147 SORT_SYM_TO,
150148 SORT_MISPREDICT,
149+
150+ /* memory mode specific sort keys */
151+ __SORT_MEMORY_MODE,
152+ SORT_LOCAL_WEIGHT = __SORT_MEMORY_MODE,
153+ SORT_GLOBAL_WEIGHT,
154+ SORT_MEM_DADDR_SYMBOL,
155+ SORT_MEM_DADDR_DSO,
156+ SORT_MEM_LOCKED,
157+ SORT_MEM_TLB,
158+ SORT_MEM_LVL,
159+ SORT_MEM_SNOOP,
151160 };
152161
153162 /*
@@ -172,7 +181,6 @@ extern struct list_head hist_entry__sort_list; · 18 unmodified lines
172181
173182 int setup_sorting(void);
174183 extern int sort_dimension__add(const char *);
175−void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
176− const char *list_name, FILE *fp);
184+void sort__setup_elide(FILE *fp);
177185
178186 #endif /* __PERF_SORT_H */
tools/perf/util/stat.c+1−1
@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats) · 36 unmodified lines
3737 {
3838 double variance, variance_mean;
3939
40− if (!stats->n)
40+ if (stats->n < 2)
4141 return 0.0;
4242
4343 variance = stats->M2 / (stats->n - 1);
tools/perf/util/thread.c+4−0
@@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid) · 13 unmodified lines
1414 if (self != NULL) {
1515 map_groups__init(&self->mg);
1616 self->pid = pid;
17+ self->ppid = -1;
1718 self->comm = malloc(32);
1819 if (self->comm)
1920 snprintf(self->comm, 32, ":%d", self->pid);
@@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent) · 62 unmodified lines
8283 for (i = 0; i < MAP__NR_TYPES; ++i)
8384 if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
8485 return -ENOMEM;
86+
87+ self->ppid = parent->pid;
88+
8589 return 0;
8690 }
tools/perf/util/thread.h+1−0
@@ -13,6 +13,7 @@ struct thread { · 12 unmodified lines
1313 };
1414 struct map_groups mg;
1515 pid_t pid;
16+ pid_t ppid;
1617 char shortname[3];
1718 bool comm_set;
1819 char *comm;
tools/perf/util/top.c+17−6
@@ -23,20 +23,31 @@ · 22 unmodified lines
2323
2424 size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
2525 {
26− float samples_per_sec = top->samples / top->delay_secs;
27− float ksamples_per_sec = top->kernel_samples / top->delay_secs;
28− float esamples_percent = (100.0 * top->exact_samples) / top->samples;
26+ float samples_per_sec;
27+ float ksamples_per_sec;
28+ float esamples_percent;
2929 struct perf_record_opts *opts = &top->record_opts;
3030 struct perf_target *target = &opts->target;
3131 size_t ret = 0;
3232
33+ if (top->samples) {
34+ samples_per_sec = top->samples / top->delay_secs;
35+ ksamples_per_sec = top->kernel_samples / top->delay_secs;
36+ esamples_percent = (100.0 * top->exact_samples) / top->samples;
37+ } else {
38+ samples_per_sec = ksamples_per_sec = esamples_percent = 0.0;
39+ }
40+
3341 if (!perf_guest) {
42+ float ksamples_percent = 0.0;
43+
44+ if (samples_per_sec)
45+ ksamples_percent = (100.0 * ksamples_per_sec) /
46+ samples_per_sec;
3447 ret = SNPRINTF(bf, size,
3548 " PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
3649 " exact: %4.1f%% [", samples_per_sec,
37− 100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
38− samples_per_sec)),
39− esamples_percent);
50+ ksamples_percent, esamples_percent);
4051 } else {
4152 float us_samples_per_sec = top->us_samples / top->delay_secs;
4253 float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
tools/perf/util/top.h+1−1
@@ -26,7 +26,6 @@ struct perf_top { · 25 unmodified lines
2626 int print_entries, count_filter, delay_secs;
2727 bool hide_kernel_symbols, hide_user_symbols, zero;
2828 bool use_tui, use_stdio;
29− bool sort_has_symbols;
3029 bool kptr_restrict_warned;
3130 bool vmlinux_warned;
3231 bool dump_symtab;
@@ -37,6 +36,7 @@ struct perf_top { · 4 unmodified lines
3736 int realtime_prio;
3837 int sym_pcnt_filter;
3938 const char *sym_filter;
39+ float min_percent;
4040 };
4141
4242 size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
tools/perf/util/util.h+2−2
@@ -221,8 +221,8 @@ extern unsigned char sane_ctype[256]; · 220 unmodified lines
221221 #define isalpha(x) sane_istest(x,GIT_ALPHA)
222222 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
223223 #define isprint(x) sane_istest(x,GIT_PRINT)
224−#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20))
225−#define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20))
224+#define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20))
225+#define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20))
226226 #define tolower(x) sane_case((unsigned char)(x), 0x20)
227227 #define toupper(x) sane_case((unsigned char)(x), 0)
228228