* [PATCH 2/5] powerpc/perf: Clean up the EBB hash defines a little
2014-03-06 6:59 [PATCH 1/5] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
@ 2014-03-06 6:59 ` Michael Ellerman
2014-03-06 6:59 ` [PATCH 3/5] powerpc/perf: Avoid mutating event in power8_get_constraint() Michael Ellerman
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Michael Ellerman @ 2014-03-06 6:59 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ymanton, Paul Mackerras, khandual
Rather than using PERF_EVENT_CONFIG_EBB_SHIFT everywhere, add an
EVENT_EBB_SHIFT like every other event and use that.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/perf/power8-pmu.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 96cee20..26905ce 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -117,6 +117,7 @@
*/
#define EVENT_EBB_MASK 1ull
+#define EVENT_EBB_SHIFT PERF_EVENT_CONFIG_EBB_SHIFT
#define EVENT_THR_CMP_SHIFT 40 /* Threshold CMP value */
#define EVENT_THR_CMP_MASK 0x3ff
#define EVENT_THR_CTL_SHIFT 32 /* Threshold control value (start/stop) */
@@ -149,7 +150,7 @@
(EVENT_UNIT_MASK << EVENT_UNIT_SHIFT) | \
(EVENT_COMBINE_MASK << EVENT_COMBINE_SHIFT) | \
(EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \
- (EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT) | \
+ (EVENT_EBB_MASK << EVENT_EBB_SHIFT) | \
EVENT_PSEL_MASK)
/* MMCRA IFM bits - POWER8 */
@@ -265,10 +266,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK;
- ebb = (event >> PERF_EVENT_CONFIG_EBB_SHIFT) & EVENT_EBB_MASK;
+ ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK;
/* Clear the EBB bit in the event, so event checks work below */
- event &= ~(EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT);
+ event &= ~(EVENT_EBB_MASK << EVENT_EBB_SHIFT);
if (pmc) {
if (pmc > 6)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/5] powerpc/perf: Avoid mutating event in power8_get_constraint()
2014-03-06 6:59 [PATCH 1/5] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
2014-03-06 6:59 ` [PATCH 2/5] powerpc/perf: Clean up the EBB hash defines a little Michael Ellerman
@ 2014-03-06 6:59 ` Michael Ellerman
2014-03-06 6:59 ` [PATCH 4/5] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB Michael Ellerman
2014-03-06 6:59 ` [PATCH 5/5] powerpc/perf: Enable BHRB access for EBB events Michael Ellerman
3 siblings, 0 replies; 5+ messages in thread
From: Michael Ellerman @ 2014-03-06 6:59 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ymanton, Paul Mackerras, khandual
We only need to mask the EBB bit out of the event for the check of the
special PMC 5 & 6 events. So use a local to do it just for that code,
rather than changing the event value for the life of the function.
While we're there move the set of mask and value after all the checks.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/perf/power8-pmu.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 26905ce..04c1c77 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -268,18 +268,20 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK;
ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK;
- /* Clear the EBB bit in the event, so event checks work below */
- event &= ~(EVENT_EBB_MASK << EVENT_EBB_SHIFT);
-
if (pmc) {
+ u64 base_event;
+
if (pmc > 6)
return -1;
- mask |= CNST_PMC_MASK(pmc);
- value |= CNST_PMC_VAL(pmc);
+ /* Ignore Linux defined bits when checking event below */
+ base_event = event & ~(EVENT_EBB_MASK << EVENT_EBB_SHIFT);
- if (pmc >= 5 && event != 0x500fa && event != 0x600f4)
+ if (pmc >= 5 && base_event != 0x500fa && base_event != 0x600f4)
return -1;
+
+ mask |= CNST_PMC_MASK(pmc);
+ value |= CNST_PMC_VAL(pmc);
}
if (pmc <= 4) {
--
1.8.3.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/5] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB
2014-03-06 6:59 [PATCH 1/5] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
2014-03-06 6:59 ` [PATCH 2/5] powerpc/perf: Clean up the EBB hash defines a little Michael Ellerman
2014-03-06 6:59 ` [PATCH 3/5] powerpc/perf: Avoid mutating event in power8_get_constraint() Michael Ellerman
@ 2014-03-06 6:59 ` Michael Ellerman
2014-03-06 6:59 ` [PATCH 5/5] powerpc/perf: Enable BHRB access for EBB events Michael Ellerman
3 siblings, 0 replies; 5+ messages in thread
From: Michael Ellerman @ 2014-03-06 6:59 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ymanton, Paul Mackerras, khandual
We want a way for users of EBB (Event Based Branches) to also access the
BHRB (Branch History Rolling Buffer). EBB does not interoperate with our
existing BHRB support, which is wired into the generic Linux branch
stack sampling support.
To support EBB & BHRB we add three new bits to the event code. The first
bit indicates that the event wants access to the BHRB, and the other two
bits indicate the desired IFM (Instruction Filtering Mode).
We allow multiple events to request access to the BHRB, but they must
agree on the IFM value. Events which are not interested in the BHRB can
also interoperate with events which do.
Finally we program the desired IFM value into MMCRA. Although we do this
for every event, we know that the value will be identical for all events
that request BHRB access.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/perf/power8-pmu.c | 53 +++++++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 04c1c77..babc3c0 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -62,9 +62,11 @@
*
* 60 56 52 48 44 40 36 32
* | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
- * | [ thresh_cmp ] [ thresh_ctl ]
- * | |
- * *- EBB (Linux) thresh start/stop OR FAB match -*
+ * | | [ ] [ thresh_cmp ] [ thresh_ctl ]
+ * | | | |
+ * | | *- IFM (Linux) thresh start/stop OR FAB match -*
+ * | *- BHRB (Linux)
+ * *- EBB (Linux)
*
* 28 24 20 16 12 8 4 0
* | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
@@ -114,10 +116,18 @@
* MMCRA[57:59] = sample[0:2] (RAND_SAMP_ELIG)
* MMCRA[61:62] = sample[3:4] (RAND_SAMP_MODE)
*
+ * if EBB and BHRB:
+ * MMCRA[32:33] = IFM
+ *
*/
#define EVENT_EBB_MASK 1ull
#define EVENT_EBB_SHIFT PERF_EVENT_CONFIG_EBB_SHIFT
+#define EVENT_BHRB_MASK 1ull
+#define EVENT_BHRB_SHIFT 62
+#define EVENT_WANTS_BHRB (EVENT_BHRB_MASK << EVENT_BHRB_SHIFT)
+#define EVENT_IFM_MASK 3ull
+#define EVENT_IFM_SHIFT 60
#define EVENT_THR_CMP_SHIFT 40 /* Threshold CMP value */
#define EVENT_THR_CMP_MASK 0x3ff
#define EVENT_THR_CTL_SHIFT 32 /* Threshold control value (start/stop) */
@@ -142,6 +152,12 @@
#define EVENT_IS_MARKED (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT)
#define EVENT_PSEL_MASK 0xff /* PMCxSEL value */
+/* Bits defined by Linux */
+#define EVENT_LINUX_MASK \
+ ((EVENT_EBB_MASK << EVENT_EBB_SHIFT) | \
+ (EVENT_BHRB_MASK << EVENT_BHRB_SHIFT) | \
+ (EVENT_IFM_MASK << EVENT_IFM_SHIFT))
+
#define EVENT_VALID_MASK \
((EVENT_THRESH_MASK << EVENT_THRESH_SHIFT) | \
(EVENT_SAMPLE_MASK << EVENT_SAMPLE_SHIFT) | \
@@ -150,7 +166,7 @@
(EVENT_UNIT_MASK << EVENT_UNIT_SHIFT) | \
(EVENT_COMBINE_MASK << EVENT_COMBINE_SHIFT) | \
(EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \
- (EVENT_EBB_MASK << EVENT_EBB_SHIFT) | \
+ EVENT_LINUX_MASK | \
EVENT_PSEL_MASK)
/* MMCRA IFM bits - POWER8 */
@@ -174,10 +190,11 @@
*
* 28 24 20 16 12 8 4 0
* | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
- * | [ ] [ sample ] [ ] [6] [5] [4] [3] [2] [1]
- * EBB -* | |
- * | | Count of events for each PMC.
- * L1 I/D qualifier -* | p1, p2, p3, p4, p5, p6.
+ * [ ] | [ ] [ sample ] [ ] [6] [5] [4] [3] [2] [1]
+ * | | | |
+ * BHRB IFM -* | | | Count of events for each PMC.
+ * EBB -* | | p1, p2, p3, p4, p5, p6.
+ * L1 I/D qualifier -* |
* nc - number of counters -*
*
* The PMC fields P1..P6, and NC, are adder fields. As we accumulate constraints
@@ -196,6 +213,9 @@
#define CNST_EBB_VAL(v) (((v) & EVENT_EBB_MASK) << 24)
#define CNST_EBB_MASK CNST_EBB_VAL(EVENT_EBB_MASK)
+#define CNST_IFM_VAL(v) (((v) & EVENT_IFM_MASK) << 25)
+#define CNST_IFM_MASK CNST_IFM_VAL(EVENT_IFM_MASK)
+
#define CNST_L1_QUAL_VAL(v) (((v) & 3) << 22)
#define CNST_L1_QUAL_MASK CNST_L1_QUAL_VAL(3)
@@ -242,6 +262,7 @@
#define MMCRA_THR_SEL_SHIFT 16
#define MMCRA_THR_CMP_SHIFT 32
#define MMCRA_SDAR_MODE_TLB (1ull << 42)
+#define MMCRA_IFM_SHIFT 30
static inline bool event_is_fab_match(u64 event)
@@ -275,7 +296,7 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
return -1;
/* Ignore Linux defined bits when checking event below */
- base_event = event & ~(EVENT_EBB_MASK << EVENT_EBB_SHIFT);
+ base_event = event & ~EVENT_LINUX_MASK;
if (pmc >= 5 && base_event != 0x500fa && base_event != 0x600f4)
return -1;
@@ -345,6 +366,15 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
/* EBB events must specify the PMC */
return -1;
+ if (event & EVENT_WANTS_BHRB) {
+ if (!ebb)
+ /* Only EBB events can request BHRB */
+ return -1;
+
+ mask |= CNST_IFM_MASK;
+ value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT);
+ }
+
/*
* All events must agree on EBB, either all request it or none.
* EBB events are pinned & exclusive, so this should never actually
@@ -434,6 +464,11 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
mmcra |= val << MMCRA_THR_CMP_SHIFT;
}
+ if (event[i] & EVENT_WANTS_BHRB) {
+ val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK;
+ mmcra |= val << MMCRA_IFM_SHIFT;
+ }
+
hwc[i] = pmc - 1;
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5] powerpc/perf: Enable BHRB access for EBB events
2014-03-06 6:59 [PATCH 1/5] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
` (2 preceding siblings ...)
2014-03-06 6:59 ` [PATCH 4/5] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB Michael Ellerman
@ 2014-03-06 6:59 ` Michael Ellerman
3 siblings, 0 replies; 5+ messages in thread
From: Michael Ellerman @ 2014-03-06 6:59 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ymanton, Paul Mackerras, khandual
The previous commit added constraint and register handling to allow
processes using EBB (Event Based Branches) to request access to the BHRB
(Branch History Rolling Buffer).
With that in place we can allow processes using EBB to access the BHRB.
This is achieved by setting BHRBA in MMCR0 when we enable EBB access. We
must also clear BHRBA when we are disabling.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/perf/core-book3s.c | 10 ++++++----
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 90c06ec..d48ce94 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -664,6 +664,7 @@
#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */
#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
+#define MMCR0_BHRBA 0x00200000UL /* BHRB Access allowed in userspace */
#define MMCR0_EBE 0x00100000UL /* Event based branch enable */
#define MMCR0_PMCC 0x000c0000UL /* PMC control */
#define MMCR0_PMCC_U6 0x00080000UL /* PMC1-6 are R/W by user (PR) */
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 4b2ba0c..a75bb69 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -78,6 +78,7 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;
#define MMCR0_FC56 0
#define MMCR0_PMAO 0
#define MMCR0_EBE 0
+#define MMCR0_BHRBA 0
#define MMCR0_PMCC 0
#define MMCR0_PMCC_U6 0
@@ -545,8 +546,8 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
if (!ebb)
goto out;
- /* Enable EBB and read/write to all 6 PMCs for userspace */
- mmcr0 |= MMCR0_EBE | MMCR0_PMCC_U6;
+ /* Enable EBB and read/write to all 6 PMCs and BHRB for userspace */
+ mmcr0 |= MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC_U6;
/* Add any bits from the user reg, FC or PMAO */
mmcr0 |= current->thread.mmcr0;
@@ -976,11 +977,12 @@ static void power_pmu_disable(struct pmu *pmu)
}
/*
- * Set the 'freeze counters' bit, clear EBE/PMCC/PMAO/FC56.
+ * Set the 'freeze counters' bit, clear EBE/BHRBA/PMCC/PMAO/FC56
*/
val = mmcr0 = mfspr(SPRN_MMCR0);
val |= MMCR0_FC;
- val &= ~(MMCR0_EBE | MMCR0_PMCC | MMCR0_PMAO | MMCR0_FC56);
+ val &= ~(MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC | MMCR0_PMAO |
+ MMCR0_FC56);
/*
* The barrier is to make sure the mtspr has been
--
1.8.3.2
^ permalink raw reply related [flat|nested] 5+ messages in thread