aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/oprofile
diff options
context:
space:
mode:
authorCarl E. Love <cel@linux.vnet.ibm.com>2012-08-02 23:02:17 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-06 21:10:54 -0400
commitadbf115d66649b3a52e6875f93c9f131ba690cce (patch)
tree710646c039a4449858f8c3e853bac22b04390647 /arch/powerpc/oprofile
parent22d8ce887991f8f70a68fb68972f187ec79d44b7 (diff)
powerpc/oprofile: Fix marked events support on Power7+ not set.
Starting with Power 7+ we need to check for marked events if the SIAR register is valid, i.e. it contains the correct address of the instruction at the time the performance counter overflowed. The mmcra register on Power 7+, contains a new bit to indicate that the contents of the SIAR is valid. If the event is not marked, then the sample is recorded independently of the SIAR valid bit setting. For older processors, there is no SIAR valid bit to check so the samples are always recorded. This is done by forcing the cntr_marked_events bit mask to zero. The code will always record the sample in this case since the bit mask says the event is not a marked event even if it really is a marked event. Signed-off-by: Carl Love <cel@us.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/oprofile')
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c100
1 files changed, 99 insertions, 1 deletions
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index caffffa5b8f2..315f9495e9b2 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -21,6 +21,13 @@
21#include <asm/reg.h> 21#include <asm/reg.h>
22 22
23#define dbg(args...) 23#define dbg(args...)
24#define OPROFILE_PM_PMCSEL_MSK 0xffULL
25#define OPROFILE_PM_UNIT_SHIFT 60
26#define OPROFILE_PM_UNIT_MSK 0xfULL
27#define OPROFILE_MAX_PMC_NUM 3
28#define OPROFILE_PMSEL_FIELD_WIDTH 8
29#define OPROFILE_UNIT_FIELD_WIDTH 4
30#define MMCRA_SIAR_VALID_MASK 0x10000000ULL
24 31
25static unsigned long reset_value[OP_MAX_COUNTER]; 32static unsigned long reset_value[OP_MAX_COUNTER];
26 33
@@ -31,6 +38,61 @@ static int use_slot_nums;
31static u32 mmcr0_val; 38static u32 mmcr0_val;
32static u64 mmcr1_val; 39static u64 mmcr1_val;
33static u64 mmcra_val; 40static u64 mmcra_val;
41static u32 cntr_marked_events;
42
43static int power7_marked_instr_event(u64 mmcr1)
44{
45 u64 psel, unit;
46 int pmc, cntr_marked_events = 0;
47
48 /* Given the MMCR1 value, look at the field for each counter to
49 * determine if it is a marked event. Code based on the function
50 * power7_marked_instr_event() in file arch/powerpc/perf/power7-pmu.c.
51 */
52 for (pmc = 0; pmc < 4; pmc++) {
53 psel = mmcr1 & (OPROFILE_PM_PMCSEL_MSK
54 << (OPROFILE_MAX_PMC_NUM - pmc)
55 * OPROFILE_MAX_PMC_NUM);
56 psel = (psel >> ((OPROFILE_MAX_PMC_NUM - pmc)
57 * OPROFILE_PMSEL_FIELD_WIDTH)) & ~1ULL;
58 unit = mmcr1 & (OPROFILE_PM_UNIT_MSK
59 << (OPROFILE_PM_UNIT_SHIFT
60 - (pmc * OPROFILE_PMSEL_FIELD_WIDTH )));
61 unit = unit >> (OPROFILE_PM_UNIT_SHIFT
62 - (pmc * OPROFILE_PMSEL_FIELD_WIDTH));
63
64 switch (psel >> 4) {
65 case 2:
66 cntr_marked_events |= (pmc == 1 || pmc == 3) << pmc;
67 break;
68 case 3:
69 if (psel == 0x3c) {
70 cntr_marked_events |= (pmc == 0) << pmc;
71 break;
72 }
73
74 if (psel == 0x3e) {
75 cntr_marked_events |= (pmc != 1) << pmc;
76 break;
77 }
78
79 cntr_marked_events |= 1 << pmc;
80 break;
81 case 4:
82 case 5:
83 cntr_marked_events |= (unit == 0xd) << pmc;
84 break;
85 case 6:
86 if (psel == 0x64)
87 cntr_marked_events |= (pmc >= 2) << pmc;
88 break;
89 case 8:
90 cntr_marked_events |= (unit == 0xd) << pmc;
91 break;
92 }
93 }
94 return cntr_marked_events;
95}
34 96
35static int power4_reg_setup(struct op_counter_config *ctr, 97static int power4_reg_setup(struct op_counter_config *ctr,
36 struct op_system_config *sys, 98 struct op_system_config *sys,
@@ -47,6 +109,23 @@ static int power4_reg_setup(struct op_counter_config *ctr,
47 mmcr1_val = sys->mmcr1; 109 mmcr1_val = sys->mmcr1;
48 mmcra_val = sys->mmcra; 110 mmcra_val = sys->mmcra;
49 111
112 /* Power 7+ and newer architectures:
113 * Determine which counter events in the group (the group of events is
114 * specified by the bit settings in the MMCR1 register) are marked
115 * events for use in the interrupt handler. Do the calculation once
116 * before OProfile starts. Information is used in the interrupt
117 * handler. Starting with Power 7+ we only record the sample for
118 * marked events if the SIAR valid bit is set. For non marked events
119 * the sample is always recorded.
120 */
121 if (pvr_version_is(PVR_POWER7p))
122 cntr_marked_events = power7_marked_instr_event(mmcr1_val);
123 else
124 cntr_marked_events = 0; /* For older processors, set the bit map
125 * to zero so the sample will always be
126 * be recorded.
127 */
128
50 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) 129 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
51 reset_value[i] = 0x80000000UL - ctr[i].count; 130 reset_value[i] = 0x80000000UL - ctr[i].count;
52 131
@@ -291,6 +370,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
291 int i; 370 int i;
292 unsigned int mmcr0; 371 unsigned int mmcr0;
293 unsigned long mmcra; 372 unsigned long mmcra;
373 bool siar_valid = false;
294 374
295 mmcra = mfspr(SPRN_MMCRA); 375 mmcra = mfspr(SPRN_MMCRA);
296 376
@@ -300,11 +380,29 @@ static void power4_handle_interrupt(struct pt_regs *regs,
300 /* set the PMM bit (see comment below) */ 380 /* set the PMM bit (see comment below) */
301 mtmsrd(mfmsr() | MSR_PMM); 381 mtmsrd(mfmsr() | MSR_PMM);
302 382
383 /* Check that the SIAR valid bit in MMCRA is set to 1. */
384 if ((mmcra & MMCRA_SIAR_VALID_MASK) == MMCRA_SIAR_VALID_MASK)
385 siar_valid = true;
386
303 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { 387 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
304 val = classic_ctr_read(i); 388 val = classic_ctr_read(i);
305 if (pmc_overflow(val)) { 389 if (pmc_overflow(val)) {
306 if (oprofile_running && ctr[i].enabled) { 390 if (oprofile_running && ctr[i].enabled) {
307 oprofile_add_ext_sample(pc, regs, i, is_kernel); 391 /* Power 7+ and newer architectures:
392 * If the event is a marked event, then only
393 * save the sample if the SIAR valid bit is
394 * set. If the event is not marked, then
395 * always save the sample.
396 * Note, the Sample enable bit in the MMCRA
397 * register must be set to 1 if the group
398 * contains a marked event.
399 */
400 if ((siar_valid &&
401 (cntr_marked_events & (1 << i)))
402 || !(cntr_marked_events & (1 << i)))
403 oprofile_add_ext_sample(pc, regs, i,
404 is_kernel);
405
308 classic_ctr_write(i, reset_value[i]); 406 classic_ctr_write(i, reset_value[i]);
309 } else { 407 } else {
310 classic_ctr_write(i, 0); 408 classic_ctr_write(i, 0);