diff options
author | Peter Zijlstra <peterz@infradead.org> | 2013-09-12 07:00:47 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-09-12 13:13:37 -0400 |
commit | d2beea4a3419e63804094e9ac4b6d1518bc17a9b (patch) | |
tree | cbc99e503af4301424957ed7b4e3846c283483f4 | |
parent | 2b9e344df384e595db24ac61ae5f780e9b024878 (diff) |
perf/x86/intel: Clean-up/reduce PEBS code
Get rid of some pointless duplication introduced by the Haswell code.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-8q6y4davda9aawwv5yxe7klp@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_ds.c | 94 |
1 files changed, 26 insertions, 68 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 104cbba3b595..f364c13ddaa6 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -188,8 +188,7 @@ struct pebs_record_hsw { | |||
188 | u64 r8, r9, r10, r11; | 188 | u64 r8, r9, r10, r11; |
189 | u64 r12, r13, r14, r15; | 189 | u64 r12, r13, r14, r15; |
190 | u64 status, dla, dse, lat; | 190 | u64 status, dla, dse, lat; |
191 | u64 real_ip; /* the actual eventing ip */ | 191 | u64 real_ip, tsx_tuning; |
192 | u64 tsx_tuning; /* TSX abort cycles and flags */ | ||
193 | }; | 192 | }; |
194 | 193 | ||
195 | union hsw_tsx_tuning { | 194 | union hsw_tsx_tuning { |
@@ -811,10 +810,8 @@ static void __intel_pmu_pebs_event(struct perf_event *event, | |||
811 | struct pt_regs *iregs, void *__pebs) | 810 | struct pt_regs *iregs, void *__pebs) |
812 | { | 811 | { |
813 | /* | 812 | /* |
814 | * We cast to pebs_record_nhm to get the load latency data | 813 | * We cast to the biggest pebs_record but are careful not to |
815 | * if extra_reg MSR_PEBS_LD_LAT_THRESHOLD used | 814 | * unconditionally access the 'extra' entries. |
816 | * We cast to the biggest PEBS record are careful not | ||
817 | * to access out-of-bounds members. | ||
818 | */ | 815 | */ |
819 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 816 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
820 | struct pebs_record_hsw *pebs = __pebs; | 817 | struct pebs_record_hsw *pebs = __pebs; |
@@ -884,12 +881,11 @@ static void __intel_pmu_pebs_event(struct perf_event *event, | |||
884 | regs.flags &= ~PERF_EFLAGS_EXACT; | 881 | regs.flags &= ~PERF_EFLAGS_EXACT; |
885 | 882 | ||
886 | if ((event->attr.sample_type & PERF_SAMPLE_ADDR) && | 883 | if ((event->attr.sample_type & PERF_SAMPLE_ADDR) && |
887 | x86_pmu.intel_cap.pebs_format >= 1) | 884 | x86_pmu.intel_cap.pebs_format >= 1) |
888 | data.addr = pebs->dla; | 885 | data.addr = pebs->dla; |
889 | 886 | ||
890 | /* Only set the TSX weight when no memory weight was requested. */ | 887 | /* Only set the TSX weight when no memory weight was requested. */ |
891 | if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) && | 888 | if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) && !fll && |
892 | !fll && | ||
893 | (x86_pmu.intel_cap.pebs_format >= 2)) | 889 | (x86_pmu.intel_cap.pebs_format >= 2)) |
894 | data.weight = intel_hsw_weight(pebs); | 890 | data.weight = intel_hsw_weight(pebs); |
895 | 891 | ||
@@ -941,17 +937,34 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) | |||
941 | __intel_pmu_pebs_event(event, iregs, at); | 937 | __intel_pmu_pebs_event(event, iregs, at); |
942 | } | 938 | } |
943 | 939 | ||
944 | static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at, | 940 | static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) |
945 | void *top) | ||
946 | { | 941 | { |
947 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 942 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
948 | struct debug_store *ds = cpuc->ds; | 943 | struct debug_store *ds = cpuc->ds; |
949 | struct perf_event *event = NULL; | 944 | struct perf_event *event = NULL; |
945 | void *at, *top; | ||
950 | u64 status = 0; | 946 | u64 status = 0; |
951 | int bit; | 947 | int bit, n; |
948 | |||
949 | if (!x86_pmu.pebs_active) | ||
950 | return; | ||
951 | |||
952 | at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; | ||
953 | top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; | ||
952 | 954 | ||
953 | ds->pebs_index = ds->pebs_buffer_base; | 955 | ds->pebs_index = ds->pebs_buffer_base; |
954 | 956 | ||
957 | n = (top - at) / x86_pmu.pebs_record_size; | ||
958 | if (n <= 0) | ||
959 | return; | ||
960 | |||
961 | /* | ||
962 | * Should not happen, we program the threshold at 1 and do not | ||
963 | * set a reset value. | ||
964 | */ | ||
965 | WARN_ONCE(n > x86_pmu.max_pebs_events, | ||
966 | "Unexpected number of pebs records %d\n", n); | ||
967 | |||
955 | for (; at < top; at += x86_pmu.pebs_record_size) { | 968 | for (; at < top; at += x86_pmu.pebs_record_size) { |
956 | struct pebs_record_nhm *p = at; | 969 | struct pebs_record_nhm *p = at; |
957 | 970 | ||
@@ -979,61 +992,6 @@ static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at, | |||
979 | } | 992 | } |
980 | } | 993 | } |
981 | 994 | ||
982 | static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) | ||
983 | { | ||
984 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
985 | struct debug_store *ds = cpuc->ds; | ||
986 | struct pebs_record_nhm *at, *top; | ||
987 | int n; | ||
988 | |||
989 | if (!x86_pmu.pebs_active) | ||
990 | return; | ||
991 | |||
992 | at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; | ||
993 | top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; | ||
994 | |||
995 | ds->pebs_index = ds->pebs_buffer_base; | ||
996 | |||
997 | n = top - at; | ||
998 | if (n <= 0) | ||
999 | return; | ||
1000 | |||
1001 | /* | ||
1002 | * Should not happen, we program the threshold at 1 and do not | ||
1003 | * set a reset value. | ||
1004 | */ | ||
1005 | WARN_ONCE(n > x86_pmu.max_pebs_events, | ||
1006 | "Unexpected number of pebs records %d\n", n); | ||
1007 | |||
1008 | return __intel_pmu_drain_pebs_nhm(iregs, at, top); | ||
1009 | } | ||
1010 | |||
1011 | static void intel_pmu_drain_pebs_hsw(struct pt_regs *iregs) | ||
1012 | { | ||
1013 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
1014 | struct debug_store *ds = cpuc->ds; | ||
1015 | struct pebs_record_hsw *at, *top; | ||
1016 | int n; | ||
1017 | |||
1018 | if (!x86_pmu.pebs_active) | ||
1019 | return; | ||
1020 | |||
1021 | at = (struct pebs_record_hsw *)(unsigned long)ds->pebs_buffer_base; | ||
1022 | top = (struct pebs_record_hsw *)(unsigned long)ds->pebs_index; | ||
1023 | |||
1024 | n = top - at; | ||
1025 | if (n <= 0) | ||
1026 | return; | ||
1027 | /* | ||
1028 | * Should not happen, we program the threshold at 1 and do not | ||
1029 | * set a reset value. | ||
1030 | */ | ||
1031 | WARN_ONCE(n > x86_pmu.max_pebs_events, | ||
1032 | "Unexpected number of pebs records %d\n", n); | ||
1033 | |||
1034 | return __intel_pmu_drain_pebs_nhm(iregs, at, top); | ||
1035 | } | ||
1036 | |||
1037 | /* | 995 | /* |
1038 | * BTS, PEBS probe and setup | 996 | * BTS, PEBS probe and setup |
1039 | */ | 997 | */ |
@@ -1068,7 +1026,7 @@ void intel_ds_init(void) | |||
1068 | case 2: | 1026 | case 2: |
1069 | pr_cont("PEBS fmt2%c, ", pebs_type); | 1027 | pr_cont("PEBS fmt2%c, ", pebs_type); |
1070 | x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw); | 1028 | x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw); |
1071 | x86_pmu.drain_pebs = intel_pmu_drain_pebs_hsw; | 1029 | x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; |
1072 | break; | 1030 | break; |
1073 | 1031 | ||
1074 | default: | 1032 | default: |