diff options
author | Anton Blanchard <anton@samba.org> | 2012-06-25 21:01:36 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-07-10 05:18:41 -0400 |
commit | 75382aa72f06823db7312ad069c3bae2eb3f8548 (patch) | |
tree | d345dbb162b14375d20a622a0801fd9a93cf1c1c | |
parent | 68b30bb9f0fed8281fe8a1ac818d6d07c803fa7b (diff) |
powerpc/perf: Move code to select SIAR or pt_regs into perf_read_regs
The logic to choose whether to use the SIAR or get the information
out of pt_regs is going to get more complicated, so do it once in
perf_read_regs.
We overload regs->result which is gross but we are already doing it
with regs->dsisr.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/include/asm/perf_event.h | 5 | ||||
-rw-r--r-- | arch/powerpc/perf/core-book3s.c | 47 |
2 files changed, 30 insertions, 22 deletions
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h index 5c16b891d501..0bb23725b1e7 100644 --- a/arch/powerpc/include/asm/perf_event.h +++ b/arch/powerpc/include/asm/perf_event.h | |||
@@ -26,8 +26,13 @@ | |||
26 | #include <asm/ptrace.h> | 26 | #include <asm/ptrace.h> |
27 | #include <asm/reg.h> | 27 | #include <asm/reg.h> |
28 | 28 | ||
29 | /* | ||
30 | * Overload regs->result to specify whether we should use the MSR (result | ||
31 | * is zero) or the SIAR (result is non zero). | ||
32 | */ | ||
29 | #define perf_arch_fetch_caller_regs(regs, __ip) \ | 33 | #define perf_arch_fetch_caller_regs(regs, __ip) \ |
30 | do { \ | 34 | do { \ |
35 | (regs)->result = 0; \ | ||
31 | (regs)->nip = __ip; \ | 36 | (regs)->nip = __ip; \ |
32 | (regs)->gpr[1] = *(unsigned long *)__get_SP(); \ | 37 | (regs)->gpr[1] = *(unsigned long *)__get_SP(); \ |
33 | asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \ | 38 | asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \ |
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 1818f636b9ae..dcb6a798f111 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -73,7 +73,10 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) | |||
73 | { | 73 | { |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | static inline void perf_read_regs(struct pt_regs *regs) { } | 76 | static inline void perf_read_regs(struct pt_regs *regs) |
77 | { | ||
78 | regs->result = 0; | ||
79 | } | ||
77 | static inline int perf_intr_is_nmi(struct pt_regs *regs) | 80 | static inline int perf_intr_is_nmi(struct pt_regs *regs) |
78 | { | 81 | { |
79 | return 0; | 82 | return 0; |
@@ -148,17 +151,9 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs) | |||
148 | static inline u32 perf_get_misc_flags(struct pt_regs *regs) | 151 | static inline u32 perf_get_misc_flags(struct pt_regs *regs) |
149 | { | 152 | { |
150 | unsigned long mmcra = regs->dsisr; | 153 | unsigned long mmcra = regs->dsisr; |
154 | unsigned long use_siar = regs->result; | ||
151 | 155 | ||
152 | /* Not a PMU interrupt: Make up flags from regs->msr */ | 156 | if (!use_siar) |
153 | if (TRAP(regs) != 0xf00) | ||
154 | return perf_flags_from_msr(regs); | ||
155 | |||
156 | /* | ||
157 | * If we don't support continuous sampling and this | ||
158 | * is not a marked event, same deal | ||
159 | */ | ||
160 | if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && | ||
161 | !(mmcra & MMCRA_SAMPLE_ENABLE)) | ||
162 | return perf_flags_from_msr(regs); | 157 | return perf_flags_from_msr(regs); |
163 | 158 | ||
164 | /* | 159 | /* |
@@ -185,10 +180,24 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) | |||
185 | /* | 180 | /* |
186 | * Overload regs->dsisr to store MMCRA so we only need to read it once | 181 | * Overload regs->dsisr to store MMCRA so we only need to read it once |
187 | * on each interrupt. | 182 | * on each interrupt. |
183 | * Overload regs->result to specify whether we should use the MSR (result | ||
184 | * is zero) or the SIAR (result is non zero). | ||
188 | */ | 185 | */ |
189 | static inline void perf_read_regs(struct pt_regs *regs) | 186 | static inline void perf_read_regs(struct pt_regs *regs) |
190 | { | 187 | { |
191 | regs->dsisr = mfspr(SPRN_MMCRA); | 188 | unsigned long mmcra = mfspr(SPRN_MMCRA); |
189 | int marked = mmcra & MMCRA_SAMPLE_ENABLE; | ||
190 | int use_siar; | ||
191 | |||
192 | if (TRAP(regs) != 0xf00) | ||
193 | use_siar = 0; | ||
194 | else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && !marked) | ||
195 | use_siar = 0; | ||
196 | else | ||
197 | use_siar = 1; | ||
198 | |||
199 | regs->dsisr = mmcra; | ||
200 | regs->result = use_siar; | ||
192 | } | 201 | } |
193 | 202 | ||
194 | /* | 203 | /* |
@@ -1342,18 +1351,12 @@ unsigned long perf_misc_flags(struct pt_regs *regs) | |||
1342 | */ | 1351 | */ |
1343 | unsigned long perf_instruction_pointer(struct pt_regs *regs) | 1352 | unsigned long perf_instruction_pointer(struct pt_regs *regs) |
1344 | { | 1353 | { |
1345 | unsigned long mmcra = regs->dsisr; | 1354 | unsigned long use_siar = regs->result; |
1346 | 1355 | ||
1347 | /* Not a PMU interrupt */ | 1356 | if (use_siar) |
1348 | if (TRAP(regs) != 0xf00) | 1357 | return mfspr(SPRN_SIAR) + perf_ip_adjust(regs); |
1349 | return regs->nip; | 1358 | else |
1350 | |||
1351 | /* Processor doesn't support sampling non marked events */ | ||
1352 | if ((ppmu->flags & PPMU_NO_CONT_SAMPLING) && | ||
1353 | !(mmcra & MMCRA_SAMPLE_ENABLE)) | ||
1354 | return regs->nip; | 1359 | return regs->nip; |
1355 | |||
1356 | return mfspr(SPRN_SIAR) + perf_ip_adjust(regs); | ||
1357 | } | 1360 | } |
1358 | 1361 | ||
1359 | static bool pmc_overflow(unsigned long val) | 1362 | static bool pmc_overflow(unsigned long val) |