powerpc/perf: Add missing L2 constraint handling in Power7 PMU
authorMichael Ellerman <michael@ellerman.id.au>
Tue, 30 Oct 2012 16:09:56 +0000 (16:09 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 15 Nov 2012 02:00:36 +0000 (13:00 +1100)
If we have two cache events that require different settings of the L2SEL
bits in MMCR1 then we can not schedule those events simultaneously. Add
logic to the constraint handling to express that.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/perf/power7-pmu.c

index 441af08edf434cc9729d0df344e422f32f487962..2ee01e38d5e256b9a92f0ee678e08a19e768f572 100644 (file)
  * Layout of constraint bits:
  * 6666555555555544444444443333333333222222222211111111110000000000
  * 3210987654321098765432109876543210987654321098765432109876543210
- *                                                 [  ><><><><><><>
- *                                                  NC P6P5P4P3P2P1
+ *                                              < ><  ><><><><><><>
+ *                                              L2  NC P6P5P4P3P2P1
+ *
+ * L2 - 16-18 - Required L2SEL value (select field)
  *
  * NC - number of counters
  *     15: NC error 0x8000
@@ -72,7 +74,7 @@
 static int power7_get_constraint(u64 event, unsigned long *maskp,
                                 unsigned long *valp)
 {
-       int pmc, sh;
+       int pmc, sh, unit;
        unsigned long mask = 0, value = 0;
 
        pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
@@ -90,6 +92,15 @@ static int power7_get_constraint(u64 event, unsigned long *maskp,
                mask  |= 0x8000;
                value |= 0x1000;
        }
+
+       unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
+       if (unit == 6) {
+               /* L2SEL must be identical across events */
+               int l2sel = (event >> PM_L2SEL_SH) & PM_L2SEL_MSK;
+               mask  |= 0x7 << 16;
+               value |= l2sel << 16;
+       }
+
        *maskp = mask;
        *valp = value;
        return 0;