linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* powerpc/perf: patches for 3.15
@ 2014-03-14  5:00 Michael Ellerman
  2014-03-14  5:00 ` [PATCH 01/20] powerpc/perf: Make some new raw event codes available in sysfs Michael Ellerman
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

Hi folks,

This is the series of patches I have in my git tree to send to Ben.

https://github.com/mpe/powerpc-merge

These have all been to the list previously as-is, except for some of Cody's
which I've modified slightly to avoid depending on other peoples' trees.

The patch to fs/sysfs/group.c has already been merged by Greg, but we want to
carry it too so the code works prior to merging with his tree.

cheers

 Documentation/ABI/testing/sysfs-bus-event_source-devices-events  | 517 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 |  23 ++++
 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci |  43 +++++++
 arch/powerpc/include/asm/cputable.h                              |   6 +-
 arch/powerpc/include/asm/hvcall.h                                |   5 +
 arch/powerpc/include/asm/perf_event_server.h                     |   1 +
 arch/powerpc/include/asm/reg.h                                   |   3 +
 arch/powerpc/kernel/cputable.c                                   |   2 +-
 arch/powerpc/perf/Makefile                                       |   2 +
 arch/powerpc/perf/core-book3s.c                                  | 172 ++++++++++++++++++++++++--
 arch/powerpc/perf/hv-24x7-catalog.h                              |  33 +++++
 arch/powerpc/perf/hv-24x7.c                                      | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/powerpc/perf/hv-24x7.h                                      | 109 +++++++++++++++++
 arch/powerpc/perf/hv-common.c                                    |  39 ++++++
 arch/powerpc/perf/hv-common.h                                    |  36 ++++++
 arch/powerpc/perf/hv-gpci.c                                      | 294 ++++++++++++++++++++++++++++++++++++++++++++
 arch/powerpc/perf/hv-gpci.h                                      |  73 +++++++++++
 arch/powerpc/perf/power7-events-list.h                           |  10 ++
 arch/powerpc/perf/power8-pmu.c                                   |  78 +++++++++---
 arch/powerpc/platforms/pseries/Kconfig                           |  12 ++
 fs/sysfs/group.c                                                 |   7 +-
 21 files changed, 1941 insertions(+), 34 deletions(-)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/20] powerpc/perf: Make some new raw event codes available in sysfs
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 02/20] powerpc/perf: Define perf_event_print_debug() to print PMU register values Michael Ellerman
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Anshuman Khandual <khandual@linux.vnet.ibm.com>

This patchset adds some missing event list for POWER7 PMU raw
events which are exported through sysfs interface. Also updates
the ABI documentation to add all the sysfs exported raw events.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 .../testing/sysfs-bus-event_source-devices-events  | 517 +++++++++++++++++++++
 arch/powerpc/perf/power7-events-list.h             |  10 +
 2 files changed, 527 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
index 3c1cc24..7b40a3c 100644
--- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
@@ -57,6 +57,523 @@ What: 		/sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
 		/sys/devices/cpu/events/PM_LD_REF_L1
 		/sys/devices/cpu/events/PM_RUN_CYC
 		/sys/devices/cpu/events/PM_RUN_INST_CMPL
+		/sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_ALL
+		/sys/devices/cpu/events/PM_GCT_UTIL_7_TO_10_SLOTS
+		/sys/devices/cpu/events/PM_PMC2_SAVED
+		/sys/devices/cpu/events/PM_VSU0_16FLOP
+		/sys/devices/cpu/events/PM_MRK_LSU_DERAT_MISS
+		/sys/devices/cpu/events/PM_MRK_ST_CMPL
+		/sys/devices/cpu/events/PM_NEST_PAIR3_ADD
+		/sys/devices/cpu/events/PM_L2_ST_DISP
+		/sys/devices/cpu/events/PM_L2_CASTOUT_MOD
+		/sys/devices/cpu/events/PM_ISEG
+		/sys/devices/cpu/events/PM_MRK_INST_TIMEO
+		/sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_ADDR
+		/sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM
+		/sys/devices/cpu/events/PM_IERAT_WR_64K
+		/sys/devices/cpu/events/PM_MRK_DTLB_MISS_16M
+		/sys/devices/cpu/events/PM_IERAT_MISS
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_LMEM
+		/sys/devices/cpu/events/PM_FLOP
+		/sys/devices/cpu/events/PM_THRD_PRIO_4_5_CYC
+		/sys/devices/cpu/events/PM_BR_PRED_TA
+		/sys/devices/cpu/events/PM_EXT_INT
+		/sys/devices/cpu/events/PM_VSU_FSQRT_FDIV
+		/sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC
+		/sys/devices/cpu/events/PM_LSU1_LDF
+		/sys/devices/cpu/events/PM_IC_WRITE_ALL
+		/sys/devices/cpu/events/PM_LSU0_SRQ_STFWD
+		/sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_MOD
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_DATA_FROM_L21_MOD
+		/sys/devices/cpu/events/PM_VSU1_SCAL_DOUBLE_ISSUED
+		/sys/devices/cpu/events/PM_VSU0_8FLOP
+		/sys/devices/cpu/events/PM_POWER_EVENT1
+		/sys/devices/cpu/events/PM_DISP_CLB_HELD_BAL
+		/sys/devices/cpu/events/PM_VSU1_2FLOP
+		/sys/devices/cpu/events/PM_LWSYNC_HELD
+		/sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_SHR
+		/sys/devices/cpu/events/PM_INST_FROM_L21_MOD
+		/sys/devices/cpu/events/PM_IERAT_XLATE_WR_16MPLUS
+		/sys/devices/cpu/events/PM_IC_REQ_ALL
+		/sys/devices/cpu/events/PM_DSLB_MISS
+		/sys/devices/cpu/events/PM_L3_MISS
+		/sys/devices/cpu/events/PM_LSU0_L1_PREF
+		/sys/devices/cpu/events/PM_VSU_SCALAR_SINGLE_ISSUED
+		/sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM_STRIDE
+		/sys/devices/cpu/events/PM_L2_INST
+		/sys/devices/cpu/events/PM_VSU0_FRSP
+		/sys/devices/cpu/events/PM_FLUSH_DISP
+		/sys/devices/cpu/events/PM_PTEG_FROM_L2MISS
+		/sys/devices/cpu/events/PM_VSU1_DQ_ISSUED
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM
+		/sys/devices/cpu/events/PM_LSU_FLUSH_ULD
+		/sys/devices/cpu/events/PM_PTEG_FROM_LMEM
+		/sys/devices/cpu/events/PM_MRK_DERAT_MISS_16M
+		/sys/devices/cpu/events/PM_THRD_ALL_RUN_CYC
+		/sys/devices/cpu/events/PM_MEM0_PREFETCH_DISP
+		/sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC_COUNT
+		/sys/devices/cpu/events/PM_DATA_FROM_DL2L3_MOD
+		/sys/devices/cpu/events/PM_VSU_FRSP
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD
+		/sys/devices/cpu/events/PM_PMC1_OVERFLOW
+		/sys/devices/cpu/events/PM_VSU0_SINGLE
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3MISS
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_VSU0_VECTOR_SP_ISSUED
+		/sys/devices/cpu/events/PM_VSU1_FEST
+		/sys/devices/cpu/events/PM_MRK_INST_DISP
+		/sys/devices/cpu/events/PM_VSU0_COMPLEX_ISSUED
+		/sys/devices/cpu/events/PM_LSU1_FLUSH_UST
+		/sys/devices/cpu/events/PM_FXU_IDLE
+		/sys/devices/cpu/events/PM_LSU0_FLUSH_ULD
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD
+		/sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_ALL_CYC
+		/sys/devices/cpu/events/PM_LSU1_REJECT_LMQ_FULL
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_MOD
+		/sys/devices/cpu/events/PM_INST_FROM_RL2L3_MOD
+		/sys/devices/cpu/events/PM_SHL_CREATED
+		/sys/devices/cpu/events/PM_L2_ST_HIT
+		/sys/devices/cpu/events/PM_DATA_FROM_DMEM
+		/sys/devices/cpu/events/PM_L3_LD_MISS
+		/sys/devices/cpu/events/PM_FXU1_BUSY_FXU0_IDLE
+		/sys/devices/cpu/events/PM_DISP_CLB_HELD_RES
+		/sys/devices/cpu/events/PM_L2_SN_SX_I_DONE
+		/sys/devices/cpu/events/PM_STCX_CMPL
+		/sys/devices/cpu/events/PM_VSU0_2FLOP
+		/sys/devices/cpu/events/PM_L3_PREF_MISS
+		/sys/devices/cpu/events/PM_LSU_SRQ_SYNC_CYC
+		/sys/devices/cpu/events/PM_LSU_REJECT_ERAT_MISS
+		/sys/devices/cpu/events/PM_L1_ICACHE_MISS
+		/sys/devices/cpu/events/PM_LSU1_FLUSH_SRQ
+		/sys/devices/cpu/events/PM_LD_REF_L1_LSU0
+		/sys/devices/cpu/events/PM_VSU0_FEST
+		/sys/devices/cpu/events/PM_VSU_VECTOR_SINGLE_ISSUED
+		/sys/devices/cpu/events/PM_FREQ_UP
+		/sys/devices/cpu/events/PM_DATA_FROM_LMEM
+		/sys/devices/cpu/events/PM_LSU1_LDX
+		/sys/devices/cpu/events/PM_PMC3_OVERFLOW
+		/sys/devices/cpu/events/PM_MRK_BR_MPRED
+		/sys/devices/cpu/events/PM_SHL_MATCH
+		/sys/devices/cpu/events/PM_MRK_BR_TAKEN
+		/sys/devices/cpu/events/PM_ISLB_MISS
+		/sys/devices/cpu/events/PM_DISP_HELD_THERMAL
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_SHR
+		/sys/devices/cpu/events/PM_LSU1_SRQ_STFWD
+		/sys/devices/cpu/events/PM_PTEG_FROM_DMEM
+		/sys/devices/cpu/events/PM_VSU_2FLOP
+		/sys/devices/cpu/events/PM_GCT_FULL_CYC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L3_CYC
+		/sys/devices/cpu/events/PM_LSU_SRQ_S0_ALLOC
+		/sys/devices/cpu/events/PM_MRK_DERAT_MISS_4K
+		/sys/devices/cpu/events/PM_BR_MPRED_TA
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L2MISS
+		/sys/devices/cpu/events/PM_DPU_HELD_POWER
+		/sys/devices/cpu/events/PM_MRK_VSU_FIN
+		/sys/devices/cpu/events/PM_LSU_SRQ_S0_VALID
+		/sys/devices/cpu/events/PM_GCT_EMPTY_CYC
+		/sys/devices/cpu/events/PM_IOPS_DISP
+		/sys/devices/cpu/events/PM_RUN_SPURR
+		/sys/devices/cpu/events/PM_PTEG_FROM_L21_MOD
+		/sys/devices/cpu/events/PM_VSU0_1FLOP
+		/sys/devices/cpu/events/PM_SNOOP_TLBIE
+		/sys/devices/cpu/events/PM_DATA_FROM_L3MISS
+		/sys/devices/cpu/events/PM_VSU_SINGLE
+		/sys/devices/cpu/events/PM_DTLB_MISS_16G
+		/sys/devices/cpu/events/PM_FLUSH
+		/sys/devices/cpu/events/PM_L2_LD_HIT
+		/sys/devices/cpu/events/PM_NEST_PAIR2_AND
+		/sys/devices/cpu/events/PM_VSU1_1FLOP
+		/sys/devices/cpu/events/PM_IC_PREF_REQ
+		/sys/devices/cpu/events/PM_L3_LD_HIT
+		/sys/devices/cpu/events/PM_DISP_HELD
+		/sys/devices/cpu/events/PM_L2_LD
+		/sys/devices/cpu/events/PM_LSU_FLUSH_SRQ
+		/sys/devices/cpu/events/PM_BC_PLUS_8_CONV
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD_CYC
+		/sys/devices/cpu/events/PM_L2_RCST_BUSY_RC_FULL
+		/sys/devices/cpu/events/PM_TB_BIT_TRANS
+		/sys/devices/cpu/events/PM_THERMAL_MAX
+		/sys/devices/cpu/events/PM_LSU1_FLUSH_ULD
+		/sys/devices/cpu/events/PM_LSU1_REJECT_LHS
+		/sys/devices/cpu/events/PM_LSU_LRQ_S0_ALLOC
+		/sys/devices/cpu/events/PM_L3_CO_L31
+		/sys/devices/cpu/events/PM_POWER_EVENT4
+		/sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_BR_UNCOND
+		/sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_ALLOC
+		/sys/devices/cpu/events/PM_PMC4_REWIND
+		/sys/devices/cpu/events/PM_L2_RCLD_DISP
+		/sys/devices/cpu/events/PM_THRD_PRIO_2_3_CYC
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2MISS
+		/sys/devices/cpu/events/PM_IC_DEMAND_L2_BHT_REDIRECT
+		/sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_IC_PREF_CANCEL_L2
+		/sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC_COUNT
+		/sys/devices/cpu/events/PM_BR_PRED_CCACHE
+		/sys/devices/cpu/events/PM_GCT_UTIL_1_TO_2_SLOTS
+		/sys/devices/cpu/events/PM_MRK_ST_CMPL_INT
+		/sys/devices/cpu/events/PM_LSU_TWO_TABLEWALK_CYC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L3MISS
+		/sys/devices/cpu/events/PM_LSU_SET_MPRED
+		/sys/devices/cpu/events/PM_FLUSH_DISP_TLBIE
+		/sys/devices/cpu/events/PM_VSU1_FCONV
+		/sys/devices/cpu/events/PM_DERAT_MISS_16G
+		/sys/devices/cpu/events/PM_INST_FROM_LMEM
+		/sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_REDIRECT
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L2
+		/sys/devices/cpu/events/PM_PTEG_FROM_L2
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR_CYC
+		/sys/devices/cpu/events/PM_MRK_DTLB_MISS_4K
+		/sys/devices/cpu/events/PM_VSU0_FPSCR
+		/sys/devices/cpu/events/PM_VSU1_VECT_DOUBLE_ISSUED
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_MOD
+		/sys/devices/cpu/events/PM_MEM0_RQ_DISP
+		/sys/devices/cpu/events/PM_L2_LD_MISS
+		/sys/devices/cpu/events/PM_VMX_RESULT_SAT_1
+		/sys/devices/cpu/events/PM_L1_PREF
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM_CYC
+		/sys/devices/cpu/events/PM_GRP_IC_MISS_NONSPEC
+		/sys/devices/cpu/events/PM_PB_NODE_PUMP
+		/sys/devices/cpu/events/PM_SHL_MERGED
+		/sys/devices/cpu/events/PM_NEST_PAIR1_ADD
+		/sys/devices/cpu/events/PM_DATA_FROM_L3
+		/sys/devices/cpu/events/PM_LSU_FLUSH
+		/sys/devices/cpu/events/PM_LSU_SRQ_SYNC_COUNT
+		/sys/devices/cpu/events/PM_PMC2_OVERFLOW
+		/sys/devices/cpu/events/PM_LSU_LDF
+		/sys/devices/cpu/events/PM_POWER_EVENT3
+		/sys/devices/cpu/events/PM_DISP_WT
+		/sys/devices/cpu/events/PM_IC_BANK_CONFLICT
+		/sys/devices/cpu/events/PM_BR_MPRED_CR_TA
+		/sys/devices/cpu/events/PM_L2_INST_MISS
+		/sys/devices/cpu/events/PM_NEST_PAIR2_ADD
+		/sys/devices/cpu/events/PM_MRK_LSU_FLUSH
+		/sys/devices/cpu/events/PM_L2_LDST
+		/sys/devices/cpu/events/PM_INST_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_VSU0_FIN
+		/sys/devices/cpu/events/PM_VSU1_FCONV
+		/sys/devices/cpu/events/PM_INST_FROM_RMEM
+		/sys/devices/cpu/events/PM_DISP_CLB_HELD_TLBIE
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM_CYC
+		/sys/devices/cpu/events/PM_BR_PRED_CR
+		/sys/devices/cpu/events/PM_LSU_REJECT
+		/sys/devices/cpu/events/PM_GCT_UTIL_3_TO_6_SLOTS
+		/sys/devices/cpu/events/PM_CMPLU_STALL_END_GCT_NOSLOT
+		/sys/devices/cpu/events/PM_LSU0_REJECT_LMQ_FULL
+		/sys/devices/cpu/events/PM_VSU_FEST
+		/sys/devices/cpu/events/PM_NEST_PAIR0_AND
+		/sys/devices/cpu/events/PM_PTEG_FROM_L3
+		/sys/devices/cpu/events/PM_POWER_EVENT2
+		/sys/devices/cpu/events/PM_IC_PREF_CANCEL_PAGE
+		/sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV
+		/sys/devices/cpu/events/PM_MRK_GRP_CMPL
+		/sys/devices/cpu/events/PM_VSU0_SCAL_DOUBLE_ISSUED
+		/sys/devices/cpu/events/PM_GRP_DISP
+		/sys/devices/cpu/events/PM_LSU0_LDX
+		/sys/devices/cpu/events/PM_DATA_FROM_L2
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD
+		/sys/devices/cpu/events/PM_VSU0_VECT_DOUBLE_ISSUED
+		/sys/devices/cpu/events/PM_VSU1_2FLOP_DOUBLE
+		/sys/devices/cpu/events/PM_THRD_PRIO_6_7_CYC
+		/sys/devices/cpu/events/PM_BC_PLUS_8_RSLV_TAKEN
+		/sys/devices/cpu/events/PM_BR_MPRED_CR
+		/sys/devices/cpu/events/PM_L3_CO_MEM
+		/sys/devices/cpu/events/PM_DATA_FROM_RL2L3_MOD
+		/sys/devices/cpu/events/PM_LSU_SRQ_FULL_CYC
+		/sys/devices/cpu/events/PM_TABLEWALK_CYC
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_RMEM
+		/sys/devices/cpu/events/PM_LSU_SRQ_STFWD
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_RMEM
+		/sys/devices/cpu/events/PM_FXU0_FIN
+		/sys/devices/cpu/events/PM_LSU1_L1_SW_PREF
+		/sys/devices/cpu/events/PM_PTEG_FROM_L31_MOD
+		/sys/devices/cpu/events/PM_PMC5_OVERFLOW
+		/sys/devices/cpu/events/PM_LD_REF_L1_LSU1
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_SHR
+		/sys/devices/cpu/events/PM_DATA_FROM_RMEM
+		/sys/devices/cpu/events/PM_VSU0_SCAL_SINGLE_ISSUED
+		/sys/devices/cpu/events/PM_BR_MPRED_LSTACK
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD_CYC
+		/sys/devices/cpu/events/PM_LSU0_FLUSH_UST
+		/sys/devices/cpu/events/PM_LSU_NCST
+		/sys/devices/cpu/events/PM_BR_TAKEN
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_LMEM
+		/sys/devices/cpu/events/PM_DTLB_MISS_4K
+		/sys/devices/cpu/events/PM_PMC4_SAVED
+		/sys/devices/cpu/events/PM_VSU1_PERMUTE_ISSUED
+		/sys/devices/cpu/events/PM_SLB_MISS
+		/sys/devices/cpu/events/PM_LSU1_FLUSH_LRQ
+		/sys/devices/cpu/events/PM_DTLB_MISS
+		/sys/devices/cpu/events/PM_VSU1_FRSP
+		/sys/devices/cpu/events/PM_VSU_VECTOR_DOUBLE_ISSUED
+		/sys/devices/cpu/events/PM_L2_CASTOUT_SHR
+		/sys/devices/cpu/events/PM_DATA_FROM_DL2L3_SHR
+		/sys/devices/cpu/events/PM_VSU1_STF
+		/sys/devices/cpu/events/PM_ST_FIN
+		/sys/devices/cpu/events/PM_PTEG_FROM_L21_SHR
+		/sys/devices/cpu/events/PM_L2_LOC_GUESS_WRONG
+		/sys/devices/cpu/events/PM_MRK_STCX_FAIL
+		/sys/devices/cpu/events/PM_LSU0_REJECT_LHS
+		/sys/devices/cpu/events/PM_IC_PREF_CANCEL_HIT
+		/sys/devices/cpu/events/PM_L3_PREF_BUSY
+		/sys/devices/cpu/events/PM_MRK_BRU_FIN
+		/sys/devices/cpu/events/PM_LSU1_NCLD
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_MOD
+		/sys/devices/cpu/events/PM_LSU_NCLD
+		/sys/devices/cpu/events/PM_LSU_LDX
+		/sys/devices/cpu/events/PM_L2_LOC_GUESS_CORRECT
+		/sys/devices/cpu/events/PM_THRESH_TIMEO
+		/sys/devices/cpu/events/PM_L3_PREF_ST
+		/sys/devices/cpu/events/PM_DISP_CLB_HELD_SYNC
+		/sys/devices/cpu/events/PM_VSU_SIMPLE_ISSUED
+		/sys/devices/cpu/events/PM_VSU1_SINGLE
+		/sys/devices/cpu/events/PM_DATA_TABLEWALK_CYC
+		/sys/devices/cpu/events/PM_L2_RC_ST_DONE
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_MOD
+		/sys/devices/cpu/events/PM_LARX_LSU1
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM
+		/sys/devices/cpu/events/PM_DISP_CLB_HELD
+		/sys/devices/cpu/events/PM_DERAT_MISS_4K
+		/sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_ADDR
+		/sys/devices/cpu/events/PM_SEG_EXCEPTION
+		/sys/devices/cpu/events/PM_FLUSH_DISP_SB
+		/sys/devices/cpu/events/PM_L2_DC_INV
+		/sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_MOD
+		/sys/devices/cpu/events/PM_DSEG
+		/sys/devices/cpu/events/PM_BR_PRED_LSTACK
+		/sys/devices/cpu/events/PM_VSU0_STF
+		/sys/devices/cpu/events/PM_LSU_FX_FIN
+		/sys/devices/cpu/events/PM_DERAT_MISS_16M
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_MOD
+		/sys/devices/cpu/events/PM_GCT_UTIL_11_PLUS_SLOTS
+		/sys/devices/cpu/events/PM_INST_FROM_L3
+		/sys/devices/cpu/events/PM_MRK_IFU_FIN
+		/sys/devices/cpu/events/PM_ITLB_MISS
+		/sys/devices/cpu/events/PM_VSU_STF
+		/sys/devices/cpu/events/PM_LSU_FLUSH_UST
+		/sys/devices/cpu/events/PM_L2_LDST_MISS
+		/sys/devices/cpu/events/PM_FXU1_FIN
+		/sys/devices/cpu/events/PM_SHL_DEALLOCATED
+		/sys/devices/cpu/events/PM_L2_SN_M_WR_DONE
+		/sys/devices/cpu/events/PM_LSU_REJECT_SET_MPRED
+		/sys/devices/cpu/events/PM_L3_PREF_LD
+		/sys/devices/cpu/events/PM_L2_SN_M_RD_DONE
+		/sys/devices/cpu/events/PM_MRK_DERAT_MISS_16G
+		/sys/devices/cpu/events/PM_VSU_FCONV
+		/sys/devices/cpu/events/PM_ANY_THRD_RUN_CYC
+		/sys/devices/cpu/events/PM_LSU_LMQ_FULL_CYC
+		/sys/devices/cpu/events/PM_MRK_LSU_REJECT_LHS
+		/sys/devices/cpu/events/PM_MRK_LD_MISS_L1_CYC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L2_CYC
+		/sys/devices/cpu/events/PM_INST_IMC_MATCH_DISP
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM_CYC
+		/sys/devices/cpu/events/PM_VSU0_SIMPLE_ISSUED
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_SHR
+		/sys/devices/cpu/events/PM_VSU_FMA_DOUBLE
+		/sys/devices/cpu/events/PM_VSU_4FLOP
+		/sys/devices/cpu/events/PM_VSU1_FIN
+		/sys/devices/cpu/events/PM_NEST_PAIR1_AND
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_MOD
+		/sys/devices/cpu/events/PM_PTEG_FROM_RMEM
+		/sys/devices/cpu/events/PM_LSU_LRQ_S0_VALID
+		/sys/devices/cpu/events/PM_LSU0_LDF
+		/sys/devices/cpu/events/PM_FLUSH_COMPLETION
+		/sys/devices/cpu/events/PM_ST_MISS_L1
+		/sys/devices/cpu/events/PM_L2_NODE_PUMP
+		/sys/devices/cpu/events/PM_INST_FROM_DL2L3_SHR
+		/sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC
+		/sys/devices/cpu/events/PM_VSU1_DENORM
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR_CYC
+		/sys/devices/cpu/events/PM_NEST_PAIR0_ADD
+		/sys/devices/cpu/events/PM_INST_FROM_L3MISS
+		/sys/devices/cpu/events/PM_EE_OFF_EXT_INT
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_DMEM
+		/sys/devices/cpu/events/PM_INST_FROM_DL2L3_MOD
+		/sys/devices/cpu/events/PM_PMC6_OVERFLOW
+		/sys/devices/cpu/events/PM_VSU_2FLOP_DOUBLE
+		/sys/devices/cpu/events/PM_TLB_MISS
+		/sys/devices/cpu/events/PM_FXU_BUSY
+		/sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_OTHER
+		/sys/devices/cpu/events/PM_LSU_REJECT_LMQ_FULL
+		/sys/devices/cpu/events/PM_IC_RELOAD_SHR
+		/sys/devices/cpu/events/PM_GRP_MRK
+		/sys/devices/cpu/events/PM_MRK_ST_NEST
+		/sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV
+		/sys/devices/cpu/events/PM_LSU0_FLUSH_LRQ
+		/sys/devices/cpu/events/PM_LARX_LSU0
+		/sys/devices/cpu/events/PM_IBUF_FULL_CYC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR_CYC
+		/sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_ALLOC
+		/sys/devices/cpu/events/PM_GRP_MRK_CYC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR_CYC
+		/sys/devices/cpu/events/PM_L2_GLOB_GUESS_CORRECT
+		/sys/devices/cpu/events/PM_LSU_REJECT_LHS
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L3
+		/sys/devices/cpu/events/PM_FREQ_DOWN
+		/sys/devices/cpu/events/PM_PB_RETRY_NODE_PUMP
+		/sys/devices/cpu/events/PM_INST_FROM_RL2L3_SHR
+		/sys/devices/cpu/events/PM_MRK_INST_ISSUED
+		/sys/devices/cpu/events/PM_PTEG_FROM_L3MISS
+		/sys/devices/cpu/events/PM_RUN_PURR
+		/sys/devices/cpu/events/PM_MRK_GRP_IC_MISS
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L3
+		/sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_SHR
+		/sys/devices/cpu/events/PM_LSU_FLUSH_LRQ
+		/sys/devices/cpu/events/PM_MRK_DERAT_MISS_64K
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_MOD
+		/sys/devices/cpu/events/PM_L2_ST_MISS
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_SHR
+		/sys/devices/cpu/events/PM_LWSYNC
+		/sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM_STRIDE
+		/sys/devices/cpu/events/PM_MRK_LSU_FLUSH_LRQ
+		/sys/devices/cpu/events/PM_INST_IMC_MATCH_CMPL
+		/sys/devices/cpu/events/PM_NEST_PAIR3_AND
+		/sys/devices/cpu/events/PM_PB_RETRY_SYS_PUMP
+		/sys/devices/cpu/events/PM_MRK_INST_FIN
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_SHR
+		/sys/devices/cpu/events/PM_INST_FROM_L31_MOD
+		/sys/devices/cpu/events/PM_MRK_DTLB_MISS_64K
+		/sys/devices/cpu/events/PM_LSU_FIN
+		/sys/devices/cpu/events/PM_MRK_LSU_REJECT
+		/sys/devices/cpu/events/PM_L2_CO_FAIL_BUSY
+		/sys/devices/cpu/events/PM_MEM0_WQ_DISP
+		/sys/devices/cpu/events/PM_DATA_FROM_L31_MOD
+		/sys/devices/cpu/events/PM_THERMAL_WARN
+		/sys/devices/cpu/events/PM_VSU0_4FLOP
+		/sys/devices/cpu/events/PM_BR_MPRED_CCACHE
+		/sys/devices/cpu/events/PM_L1_DEMAND_WRITE
+		/sys/devices/cpu/events/PM_FLUSH_BR_MPRED
+		/sys/devices/cpu/events/PM_MRK_DTLB_MISS_16G
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_DMEM
+		/sys/devices/cpu/events/PM_L2_RCST_DISP
+		/sys/devices/cpu/events/PM_LSU_PARTIAL_CDF
+		/sys/devices/cpu/events/PM_DISP_CLB_HELD_SB
+		/sys/devices/cpu/events/PM_VSU0_FMA_DOUBLE
+		/sys/devices/cpu/events/PM_FXU0_BUSY_FXU1_IDLE
+		/sys/devices/cpu/events/PM_IC_DEMAND_CYC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR
+		/sys/devices/cpu/events/PM_MRK_LSU_FLUSH_UST
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L3MISS
+		/sys/devices/cpu/events/PM_VSU_DENORM
+		/sys/devices/cpu/events/PM_MRK_LSU_PARTIAL_CDF
+		/sys/devices/cpu/events/PM_INST_FROM_L21_SHR
+		/sys/devices/cpu/events/PM_IC_PREF_WRITE
+		/sys/devices/cpu/events/PM_BR_PRED
+		/sys/devices/cpu/events/PM_INST_FROM_DMEM
+		/sys/devices/cpu/events/PM_IC_PREF_CANCEL_ALL
+		/sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_CONFIRM
+		/sys/devices/cpu/events/PM_MRK_LSU_FLUSH_SRQ
+		/sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC
+		/sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_OTHER
+		/sys/devices/cpu/events/PM_VSU1_DD_ISSUED
+		/sys/devices/cpu/events/PM_PTEG_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_DATA_FROM_L21_SHR
+		/sys/devices/cpu/events/PM_LSU0_NCLD
+		/sys/devices/cpu/events/PM_VSU1_4FLOP
+		/sys/devices/cpu/events/PM_VSU1_8FLOP
+		/sys/devices/cpu/events/PM_VSU_8FLOP
+		/sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_CYC
+		/sys/devices/cpu/events/PM_DTLB_MISS_64K
+		/sys/devices/cpu/events/PM_THRD_CONC_RUN_INST
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2
+		/sys/devices/cpu/events/PM_PB_SYS_PUMP
+		/sys/devices/cpu/events/PM_VSU_FIN
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD
+		/sys/devices/cpu/events/PM_THRD_PRIO_0_1_CYC
+		/sys/devices/cpu/events/PM_DERAT_MISS_64K
+		/sys/devices/cpu/events/PM_PMC2_REWIND
+		/sys/devices/cpu/events/PM_INST_FROM_L2
+		/sys/devices/cpu/events/PM_GRP_BR_MPRED_NONSPEC
+		/sys/devices/cpu/events/PM_INST_DISP
+		/sys/devices/cpu/events/PM_MEM0_RD_CANCEL_TOTAL
+		/sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM
+		/sys/devices/cpu/events/PM_L1_DCACHE_RELOAD_VALID
+		/sys/devices/cpu/events/PM_VSU_SCALAR_DOUBLE_ISSUED
+		/sys/devices/cpu/events/PM_L3_PREF_HIT
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_MOD
+		/sys/devices/cpu/events/PM_MRK_FXU_FIN
+		/sys/devices/cpu/events/PM_PMC4_OVERFLOW
+		/sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3
+		/sys/devices/cpu/events/PM_LSU0_LMQ_LHR_MERGE
+		/sys/devices/cpu/events/PM_BTAC_HIT
+		/sys/devices/cpu/events/PM_L3_RD_BUSY
+		/sys/devices/cpu/events/PM_LSU0_L1_SW_PREF
+		/sys/devices/cpu/events/PM_INST_FROM_L2MISS
+		/sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_ALLOC
+		/sys/devices/cpu/events/PM_L2_ST
+		/sys/devices/cpu/events/PM_VSU0_DENORM
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR
+		/sys/devices/cpu/events/PM_BR_PRED_CR_TA
+		/sys/devices/cpu/events/PM_VSU0_FCONV
+		/sys/devices/cpu/events/PM_MRK_LSU_FLUSH_ULD
+		/sys/devices/cpu/events/PM_BTAC_MISS
+		/sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC_COUNT
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L2
+		/sys/devices/cpu/events/PM_LSU_DCACHE_RELOAD_VALID
+		/sys/devices/cpu/events/PM_VSU_FMA
+		/sys/devices/cpu/events/PM_LSU0_FLUSH_SRQ
+		/sys/devices/cpu/events/PM_LSU1_L1_PREF
+		/sys/devices/cpu/events/PM_IOPS_CMPL
+		/sys/devices/cpu/events/PM_L2_SYS_PUMP
+		/sys/devices/cpu/events/PM_L2_RCLD_BUSY_RC_FULL
+		/sys/devices/cpu/events/PM_LSU_LMQ_S0_ALLOC
+		/sys/devices/cpu/events/PM_FLUSH_DISP_SYNC
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD_CYC
+		/sys/devices/cpu/events/PM_L2_IC_INV
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD_CYC
+		/sys/devices/cpu/events/PM_L3_PREF_LDST
+		/sys/devices/cpu/events/PM_LSU_SRQ_EMPTY_CYC
+		/sys/devices/cpu/events/PM_LSU_LMQ_S0_VALID
+		/sys/devices/cpu/events/PM_FLUSH_PARTIAL
+		/sys/devices/cpu/events/PM_VSU1_FMA_DOUBLE
+		/sys/devices/cpu/events/PM_1PLUS_PPC_DISP
+		/sys/devices/cpu/events/PM_DATA_FROM_L2MISS
+		/sys/devices/cpu/events/PM_SUSPENDED
+		/sys/devices/cpu/events/PM_VSU0_FMA
+		/sys/devices/cpu/events/PM_STCX_FAIL
+		/sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV_DOUBLE
+		/sys/devices/cpu/events/PM_DC_PREF_DST
+		/sys/devices/cpu/events/PM_VSU1_SCAL_SINGLE_ISSUED
+		/sys/devices/cpu/events/PM_L3_HIT
+		/sys/devices/cpu/events/PM_L2_GLOB_GUESS_WRONG
+		/sys/devices/cpu/events/PM_MRK_DFU_FIN
+		/sys/devices/cpu/events/PM_INST_FROM_L1
+		/sys/devices/cpu/events/PM_IC_DEMAND_REQ
+		/sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV_DOUBLE
+		/sys/devices/cpu/events/PM_VSU1_FMA
+		/sys/devices/cpu/events/PM_MRK_LD_MISS_L1
+		/sys/devices/cpu/events/PM_VSU0_2FLOP_DOUBLE
+		/sys/devices/cpu/events/PM_LSU_DC_PREF_STRIDED_STREAM_CONFIRM
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_SHR
+		/sys/devices/cpu/events/PM_MRK_LSU_REJECT_ERAT_MISS
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_L2MISS
+		/sys/devices/cpu/events/PM_DATA_FROM_RL2L3_SHR
+		/sys/devices/cpu/events/PM_INST_FROM_PREF
+		/sys/devices/cpu/events/PM_VSU1_SQ
+		/sys/devices/cpu/events/PM_L2_LD_DISP
+		/sys/devices/cpu/events/PM_L2_DISP_ALL
+		/sys/devices/cpu/events/PM_THRD_GRP_CMPL_BOTH_CYC
+		/sys/devices/cpu/events/PM_VSU_FSQRT_FDIV_DOUBLE
+		/sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_SHR
+		/sys/devices/cpu/events/PM_VSU_1FLOP
+		/sys/devices/cpu/events/PM_HV_CYC
+		/sys/devices/cpu/events/PM_MRK_LSU_FIN
+		/sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR
+		/sys/devices/cpu/events/PM_DTLB_MISS_16M
+		/sys/devices/cpu/events/PM_LSU1_LMQ_LHR_MERGE
+		/sys/devices/cpu/events/PM_IFU_FIN
+		/sys/devices/cpu/events/PM_1THRD_CON_RUN_INSTR
+		/sys/devices/cpu/events/PM_CMPLU_STALL_COUNT
+		/sys/devices/cpu/events/PM_MEM0_PB_RD_CL
+		/sys/devices/cpu/events/PM_THRD_1_RUN_CYC
+		/sys/devices/cpu/events/PM_THRD_2_CONC_RUN_INSTR
+		/sys/devices/cpu/events/PM_THRD_2_RUN_CYC
+		/sys/devices/cpu/events/PM_THRD_3_CONC_RUN_INST
+		/sys/devices/cpu/events/PM_THRD_3_RUN_CYC
+		/sys/devices/cpu/events/PM_THRD_4_CONC_RUN_INST
+		/sys/devices/cpu/events/PM_THRD_4_RUN_CYC
 
 Date:		2013/01/08
 
diff --git a/arch/powerpc/perf/power7-events-list.h b/arch/powerpc/perf/power7-events-list.h
index 687790a..64f13d9 100644
--- a/arch/powerpc/perf/power7-events-list.h
+++ b/arch/powerpc/perf/power7-events-list.h
@@ -546,3 +546,13 @@ EVENT(PM_MRK_DATA_FROM_RL2L3_SHR,             0x1d04c)
 EVENT(PM_DTLB_MISS_16M,                       0x4c05e)
 EVENT(PM_LSU1_LMQ_LHR_MERGE,                  0x0d09a)
 EVENT(PM_IFU_FIN,                             0x40066)
+EVENT(PM_1THRD_CON_RUN_INSTR,                 0x30062)
+EVENT(PM_CMPLU_STALL_COUNT,                   0x4000B)
+EVENT(PM_MEM0_PB_RD_CL,                       0x30083)
+EVENT(PM_THRD_1_RUN_CYC,                      0x10060)
+EVENT(PM_THRD_2_CONC_RUN_INSTR,               0x40062)
+EVENT(PM_THRD_2_RUN_CYC,                      0x20060)
+EVENT(PM_THRD_3_CONC_RUN_INST,                0x10062)
+EVENT(PM_THRD_3_RUN_CYC,                      0x30060)
+EVENT(PM_THRD_4_CONC_RUN_INST,                0x20062)
+EVENT(PM_THRD_4_RUN_CYC,                      0x40060)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 02/20] powerpc/perf: Define perf_event_print_debug() to print PMU register values
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
  2014-03-14  5:00 ` [PATCH 01/20] powerpc/perf: Make some new raw event codes available in sysfs Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 03/20] powerpc: Add a cpu feature CPU_FTR_PMAO_BUG Michael Ellerman
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Anshuman Khandual <khandual@linux.vnet.ibm.com>

Currently the sysrq ShowRegs command does not print any PMU registers as
we have an empty definition for perf_event_print_debug(). This patch
defines perf_event_print_debug() to print various PMU registers.

Example output:

CPU: 0 PMU registers, ppmu = POWER7 n_counters = 6
PMC1:  00000000 PMC2: 00000000 PMC3: 00000000 PMC4: 00000000
PMC5:  00000000 PMC6: 00000000 PMC7: deadbeef PMC8: deadbeef
MMCR0: 0000000080000000 MMCR1: 0000000000000000 MMCRA: 0f00000001000000
SIAR:  0000000000000000 SDAR:  0000000000000000 SIER:  0000000000000000

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
[mpe: Fix 32 bit build and rework formatting for compactness]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/perf_event_server.h |  1 +
 arch/powerpc/perf/core-book3s.c              | 55 ++++++++++++++++++++++++++--
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 3fd2f1b..9ed73714 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <uapi/asm/perf_event.h>
 
+/* Update perf_event_print_debug() if this changes */
 #define MAX_HWEVENTS		8
 #define MAX_EVENT_ALTERNATIVES	8
 #define MAX_LIMITED_HWCOUNTERS	2
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 67cf220..704d1c5 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -563,10 +563,6 @@ out:
 
 static void perf_event_interrupt(struct pt_regs *regs);
 
-void perf_event_print_debug(void)
-{
-}
-
 /*
  * Read one performance monitor counter (PMC).
  */
@@ -645,6 +641,57 @@ static void write_pmc(int idx, unsigned long val)
 	}
 }
 
+/* Called from sysrq_handle_showregs() */
+void perf_event_print_debug(void)
+{
+	unsigned long sdar, sier, flags;
+	u32 pmcs[MAX_HWEVENTS];
+	int i;
+
+	if (!ppmu->n_counter)
+		return;
+
+	local_irq_save(flags);
+
+	pr_info("CPU: %d PMU registers, ppmu = %s n_counters = %d",
+		 smp_processor_id(), ppmu->name, ppmu->n_counter);
+
+	for (i = 0; i < ppmu->n_counter; i++)
+		pmcs[i] = read_pmc(i + 1);
+
+	for (; i < MAX_HWEVENTS; i++)
+		pmcs[i] = 0xdeadbeef;
+
+	pr_info("PMC1:  %08x PMC2: %08x PMC3: %08x PMC4: %08x\n",
+		 pmcs[0], pmcs[1], pmcs[2], pmcs[3]);
+
+	if (ppmu->n_counter > 4)
+		pr_info("PMC5:  %08x PMC6: %08x PMC7: %08x PMC8: %08x\n",
+			 pmcs[4], pmcs[5], pmcs[6], pmcs[7]);
+
+	pr_info("MMCR0: %016lx MMCR1: %016lx MMCRA: %016lx\n",
+		mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCRA));
+
+	sdar = sier = 0;
+#ifdef CONFIG_PPC64
+	sdar = mfspr(SPRN_SDAR);
+
+	if (ppmu->flags & PPMU_HAS_SIER)
+		sier = mfspr(SPRN_SIER);
+
+	if (ppmu->flags & PPMU_EBB) {
+		pr_info("MMCR2: %016lx EBBHR: %016lx\n",
+			mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
+		pr_info("EBBRR: %016lx BESCR: %016lx\n",
+			mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
+	}
+#endif
+	pr_info("SIAR:  %016lx SDAR:  %016lx SIER:  %016lx\n",
+		mfspr(SPRN_SIAR), sdar, sier);
+
+	local_irq_restore(flags);
+}
+
 /*
  * Check if a set of events can all go on the PMU at once.
  * If they can't, this will look at alternative codes for the events
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 03/20] powerpc: Add a cpu feature CPU_FTR_PMAO_BUG
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
  2014-03-14  5:00 ` [PATCH 01/20] powerpc/perf: Make some new raw event codes available in sysfs Michael Ellerman
  2014-03-14  5:00 ` [PATCH 02/20] powerpc/perf: Define perf_event_print_debug() to print PMU register values Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 04/20] powerpc/perf: Add lost exception workaround Michael Ellerman
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

Some power8 revisions have a hardware bug where we can lose a
Performance Monitor (PMU) exception under certain circumstances.

We will be adding a workaround for this case, see the next commit for
details. The observed behaviour is that writing PMAO doesn't cause an
exception as we would expect, hence the name of the feature.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/cputable.h | 6 ++++--
 arch/powerpc/kernel/cputable.c      | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 617cc76..bc23477 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -189,6 +189,7 @@ extern const char *powerpc_base_platform;
 #define	CPU_FTR_HAS_PPR			LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_DAWR			LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_DABRX			LONG_ASM_CONST(0x0800000000000000)
+#define CPU_FTR_PMAO_BUG		LONG_ASM_CONST(0x1000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -445,6 +446,7 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
 	    CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
+#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -466,8 +468,8 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_POSSIBLE	\
 	    (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |	\
 	    CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 |	\
-	    CPU_FTRS_POWER7 | CPU_FTRS_POWER8 | CPU_FTRS_CELL |		\
-	    CPU_FTRS_PA6T | CPU_FTR_VSX)
+	    CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 |	\
+	    CPU_FTRS_CELL | CPU_FTRS_PA6T | CPU_FTR_VSX)
 #endif
 #else
 enum {
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6c8dd5d..c1faade 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -510,7 +510,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x004b0000,
 		.cpu_name		= "POWER8E (raw)",
-		.cpu_features		= CPU_FTRS_POWER8,
+		.cpu_features		= CPU_FTRS_POWER8E,
 		.cpu_user_features	= COMMON_USER_POWER8,
 		.cpu_user_features2	= COMMON_USER2_POWER8,
 		.mmu_features		= MMU_FTRS_POWER8,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 04/20] powerpc/perf: Add lost exception workaround
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (2 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 03/20] powerpc: Add a cpu feature CPU_FTR_PMAO_BUG Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 05/20] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

Some power8 revisions have a hardware bug where we can lose a PMU
exception, this commit adds a workaround to detect the bad condition and
rectify the situation.

See the comment in the commit for a full description.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/reg.h  |   2 +
 arch/powerpc/perf/core-book3s.c | 100 +++++++++++++++++++++++++++++++++++++++-
 arch/powerpc/perf/power8-pmu.c  |   5 ++
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 90c06ec..3003472 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -670,6 +670,7 @@
 #define   MMCR0_PMC1CE	0x00008000UL /* PMC1 count enable*/
 #define   MMCR0_PMCjCE	0x00004000UL /* PMCj count enable*/
 #define   MMCR0_TRIGGER	0x00002000UL /* TRIGGER enable */
+#define   MMCR0_PMAO_SYNC 0x00000800UL /* PMU interrupt is synchronous */
 #define   MMCR0_PMAO	0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
 #define   MMCR0_SHRFC	0x00000040UL /* SHRre freeze conditions between threads */
 #define   MMCR0_FC56	0x00000010UL /* freeze counters 5 and 6 */
@@ -703,6 +704,7 @@
 #define SPRN_EBBHR	804	/* Event based branch handler register */
 #define SPRN_EBBRR	805	/* Event based branch return register */
 #define SPRN_BESCR	806	/* Branch event status and control register */
+#define   BESCR_GE	0x8000000000000000ULL /* Global Enable */
 #define SPRN_WORT	895	/* Workload optimization register - thread */
 
 #define SPRN_PMC1	787
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 704d1c5..53ac1b2 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -120,6 +120,7 @@ static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
 static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
 void power_pmu_flush_branch_stack(void) {}
 static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
+static void pmao_restore_workaround(bool ebb) { }
 #endif /* CONFIG_PPC32 */
 
 static bool regs_use_siar(struct pt_regs *regs)
@@ -545,10 +546,18 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
 	/* Enable EBB and read/write to all 6 PMCs for userspace */
 	mmcr0 |= MMCR0_EBE | MMCR0_PMCC_U6;
 
-	/* Add any bits from the user reg, FC or PMAO */
+	/*
+	 * Add any bits from the user MMCR0, FC or PMAO. This is compatible
+	 * with pmao_restore_workaround() because we may add PMAO but we never
+	 * clear it here.
+	 */
 	mmcr0 |= current->thread.mmcr0;
 
-	/* Be careful not to set PMXE if userspace had it cleared */
+	/*
+	 * Be careful not to set PMXE if userspace had it cleared. This is also
+	 * compatible with pmao_restore_workaround() because it has already
+	 * cleared PMXE and we leave PMAO alone.
+	 */
 	if (!(current->thread.mmcr0 & MMCR0_PMXE))
 		mmcr0 &= ~MMCR0_PMXE;
 
@@ -559,6 +568,91 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
 out:
 	return mmcr0;
 }
+
+static void pmao_restore_workaround(bool ebb)
+{
+	unsigned pmcs[6];
+
+	if (!cpu_has_feature(CPU_FTR_PMAO_BUG))
+		return;
+
+	/*
+	 * On POWER8E there is a hardware defect which affects the PMU context
+	 * switch logic, ie. power_pmu_disable/enable().
+	 *
+	 * When a counter overflows PMXE is cleared and FC/PMAO is set in MMCR0
+	 * by the hardware. Sometime later the actual PMU exception is
+	 * delivered.
+	 *
+	 * If we context switch, or simply disable/enable, the PMU prior to the
+	 * exception arriving, the exception will be lost when we clear PMAO.
+	 *
+	 * When we reenable the PMU, we will write the saved MMCR0 with PMAO
+	 * set, and this _should_ generate an exception. However because of the
+	 * defect no exception is generated when we write PMAO, and we get
+	 * stuck with no counters counting but no exception delivered.
+	 *
+	 * The workaround is to detect this case and tweak the hardware to
+	 * create another pending PMU exception.
+	 *
+	 * We do that by setting up PMC6 (cycles) for an imminent overflow and
+	 * enabling the PMU. That causes a new exception to be generated in the
+	 * chip, but we don't take it yet because we have interrupts hard
+	 * disabled. We then write back the PMU state as we want it to be seen
+	 * by the exception handler. When we reenable interrupts the exception
+	 * handler will be called and see the correct state.
+	 *
+	 * The logic is the same for EBB, except that the exception is gated by
+	 * us having interrupts hard disabled as well as the fact that we are
+	 * not in userspace. The exception is finally delivered when we return
+	 * to userspace.
+	 */
+
+	/* Only if PMAO is set and PMAO_SYNC is clear */
+	if ((current->thread.mmcr0 & (MMCR0_PMAO | MMCR0_PMAO_SYNC)) != MMCR0_PMAO)
+		return;
+
+	/* If we're doing EBB, only if BESCR[GE] is set */
+	if (ebb && !(current->thread.bescr & BESCR_GE))
+		return;
+
+	/*
+	 * We are already soft-disabled in power_pmu_enable(). We need to hard
+	 * enable to actually prevent the PMU exception from firing.
+	 */
+	hard_irq_disable();
+
+	/*
+	 * This is a bit gross, but we know we're on POWER8E and have 6 PMCs.
+	 * Using read/write_pmc() in a for loop adds 12 function calls and
+	 * almost doubles our code size.
+	 */
+	pmcs[0] = mfspr(SPRN_PMC1);
+	pmcs[1] = mfspr(SPRN_PMC2);
+	pmcs[2] = mfspr(SPRN_PMC3);
+	pmcs[3] = mfspr(SPRN_PMC4);
+	pmcs[4] = mfspr(SPRN_PMC5);
+	pmcs[5] = mfspr(SPRN_PMC6);
+
+	/* Ensure all freeze bits are unset */
+	mtspr(SPRN_MMCR2, 0);
+
+	/* Set up PMC6 to overflow in one cycle */
+	mtspr(SPRN_PMC6, 0x7FFFFFFE);
+
+	/* Enable exceptions and unfreeze PMC6 */
+	mtspr(SPRN_MMCR0, MMCR0_PMXE | MMCR0_PMCjCE | MMCR0_PMAO);
+
+	/* Now we need to refreeze and restore the PMCs */
+	mtspr(SPRN_MMCR0, MMCR0_FC | MMCR0_PMAO);
+
+	mtspr(SPRN_PMC1, pmcs[0]);
+	mtspr(SPRN_PMC2, pmcs[1]);
+	mtspr(SPRN_PMC3, pmcs[2]);
+	mtspr(SPRN_PMC4, pmcs[3]);
+	mtspr(SPRN_PMC5, pmcs[4]);
+	mtspr(SPRN_PMC6, pmcs[5]);
+}
 #endif /* CONFIG_PPC64 */
 
 static void perf_event_interrupt(struct pt_regs *regs);
@@ -1191,6 +1285,8 @@ static void power_pmu_enable(struct pmu *pmu)
 	cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
 
  out_enable:
+	pmao_restore_workaround(ebb);
+
 	mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
 
 	mb();
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 96cee20..64f04cf 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -10,6 +10,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt)	"power8-pmu: " fmt
+
 #include <linux/kernel.h>
 #include <linux/perf_event.h>
 #include <asm/firmware.h>
@@ -774,6 +776,9 @@ static int __init init_power8_pmu(void)
 	/* Tell userspace that EBB is supported */
 	cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
 
+	if (cpu_has_feature(CPU_FTR_PMAO_BUG))
+		pr_info("PMAO restore workaround active.\n");
+
 	return 0;
 }
 early_initcall(init_power8_pmu);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 05/20] powerpc/perf: Reject EBB events which specify a sample_type
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (3 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 04/20] powerpc/perf: Add lost exception workaround Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 06/20] powerpc/perf: Clean up the EBB hash defines a little Michael Ellerman
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

Although we already block EBB events which request sampling using
sample_period, technically it's possible for an event to set sample_type
but not sample_period.

Nothing terrible will happen if an EBB event does specify sample_type,
but it signals a major confusion on the part of userspace, and so we do
them the favor of rejecting it.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/core-book3s.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 53ac1b2..1e095fd 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -503,8 +503,11 @@ static int ebb_event_check(struct perf_event *event)
 		if (!leader->attr.pinned || !leader->attr.exclusive)
 			return -EINVAL;
 
-		if (event->attr.inherit || event->attr.sample_period ||
-		    event->attr.enable_on_exec || event->attr.freq)
+		if (event->attr.freq ||
+		    event->attr.inherit ||
+		    event->attr.sample_type ||
+		    event->attr.sample_period ||
+		    event->attr.enable_on_exec)
 			return -EINVAL;
 	}
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 06/20] powerpc/perf: Clean up the EBB hash defines a little
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (4 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 05/20] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 07/20] powerpc/perf: Avoid mutating event in power8_get_constraint() Michael Ellerman
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, 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 64f04cf..1d7c442 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -119,6 +119,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) */
@@ -151,7 +152,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 */
@@ -267,10 +268,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] 21+ messages in thread

* [PATCH 07/20] powerpc/perf: Avoid mutating event in power8_get_constraint()
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (5 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 06/20] powerpc/perf: Clean up the EBB hash defines a little Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 08/20] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB Michael Ellerman
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, 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 1d7c442..67aab10 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -270,18 +270,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] 21+ messages in thread

* [PATCH 08/20] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (6 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 07/20] powerpc/perf: Avoid mutating event in power8_get_constraint() Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 09/20] powerpc/perf: Enable BHRB access for EBB events Michael Ellerman
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, 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 67aab10..3ad363d 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -64,9 +64,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
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
@@ -116,10 +118,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) */
@@ -144,6 +154,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)		|	\
@@ -152,7 +168,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 */
@@ -176,10 +192,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
@@ -198,6 +215,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)
 
@@ -244,6 +264,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)
@@ -277,7 +298,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;
@@ -347,6 +368,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
@@ -436,6 +466,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] 21+ messages in thread

* [PATCH 09/20] powerpc/perf: Enable BHRB access for EBB events
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (7 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 08/20] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 10/20] sysfs: create bin_attributes under the requested group Michael Ellerman
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, 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 3003472..980e8db 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 1e095fd..4520c93 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
 
@@ -546,8 +547,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 MMCR0, FC or PMAO. This is compatible
@@ -1117,11 +1118,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] 21+ messages in thread

* [PATCH 10/20] sysfs: create bin_attributes under the requested group
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (8 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 09/20] powerpc/perf: Enable BHRB access for EBB events Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 11/20] powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info) Michael Ellerman
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

bin_attributes created/updated in create_files() (such as those listed
via (struct device).attribute_groups) were not placed under the
specified group, and instead appeared in the base kobj directory.

Fix this by making bin_attributes use creating code similar to normal
attributes.

A quick grep shows that no one is using bin_attrs in a named attribute
group yet, so we can do this without breaking anything in usespace.

Note that I do not add is_visible() support to
bin_attributes, though that could be done as well.

This is a copy of the patch already merged in Greg's tree.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/sysfs/group.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 6b57938..aa04068 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -70,8 +70,11 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
 	if (grp->bin_attrs) {
 		for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
 			if (update)
-				sysfs_remove_bin_file(kobj, *bin_attr);
-			error = sysfs_create_bin_file(kobj, *bin_attr);
+				kernfs_remove_by_name(parent,
+						(*bin_attr)->attr.name);
+			error = sysfs_add_file_mode_ns(parent,
+					&(*bin_attr)->attr, true,
+					(*bin_attr)->attr.mode, NULL);
 			if (error)
 				break;
 		}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 11/20] powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info)
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (9 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 10/20] sysfs: create bin_attributes under the requested group Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 12/20] powerpc/perf: Add hv_gpci interface header Michael Ellerman
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/hvcall.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index d8b600b..5dbbb29 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -274,6 +274,11 @@
 /* Platform specific hcalls, used by KVM */
 #define H_RTAS			0xf000
 
+/* "Platform specific hcalls", provided by PHYP */
+#define H_GET_24X7_CATALOG_PAGE	0xF078
+#define H_GET_24X7_DATA		0xF07C
+#define H_GET_PERF_COUNTER_INFO	0xF080
+
 #ifndef __ASSEMBLY__
 
 /**
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 12/20] powerpc/perf: Add hv_gpci interface header
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (10 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 11/20] powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info) Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 13/20] powerpc/perf: Add 24x7 interface headers Michael Ellerman
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

"H_GetPerformanceCounterInfo" (refered to as hv_gpci or just gpci from
here on) is an interface to retrieve specific performance counters and
other data from the hypervisor. All outputs have a fixed format. This
header only describes the portions of the interface that we plan on
using in linux at this time.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/hv-gpci.h | 73 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 arch/powerpc/perf/hv-gpci.h

diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h
new file mode 100644
index 0000000..b25f460
--- /dev/null
+++ b/arch/powerpc/perf/hv-gpci.h
@@ -0,0 +1,73 @@
+#ifndef LINUX_POWERPC_PERF_HV_GPCI_H_
+#define LINUX_POWERPC_PERF_HV_GPCI_H_
+
+#include <linux/types.h>
+
+/* From the document "H_GetPerformanceCounterInfo Interface" v1.07 */
+
+/* H_GET_PERF_COUNTER_INFO argument */
+struct hv_get_perf_counter_info_params {
+	__be32 counter_request; /* I */
+	__be32 starting_index;  /* IO */
+	__be16 secondary_index; /* IO */
+	__be16 returned_values; /* O */
+	__be32 detail_rc; /* O, only needed when called via *_norets() */
+
+	/*
+	 * O, size each of counter_value element in bytes, only set for version
+	 * >= 0x3
+	 */
+	__be16 cv_element_size;
+
+	/* I, 0 (zero) for versions < 0x3 */
+	__u8 counter_info_version_in;
+
+	/* O, 0 (zero) if version < 0x3. Must be set to 0 when making hcall */
+	__u8 counter_info_version_out;
+	__u8 reserved[0xC];
+	__u8 counter_value[];
+} __packed;
+
+/*
+ * counter info version => fw version/reference (spec version)
+ *
+ * 8 => power8 (1.07)
+ * [7 is skipped by spec 1.07]
+ * 6 => TLBIE (1.07)
+ * 5 => v7r7m0.phyp (1.05)
+ * [4 skipped]
+ * 3 => v7r6m0.phyp (?)
+ * [1,2 skipped]
+ * 0 => v7r{2,3,4}m0.phyp (?)
+ */
+#define COUNTER_INFO_VERSION_CURRENT 0x8
+
+/*
+ * These determine the counter_value[] layout and the meaning of starting_index
+ * and secondary_index.
+ *
+ * Unless otherwise noted, @secondary_index is unused and ignored.
+ */
+enum counter_info_requests {
+
+	/* GENERAL */
+
+	/* @starting_index: must be -1 (to refer to the current partition)
+	 */
+	CIR_SYSTEM_PERFORMANCE_CAPABILITIES = 0X40,
+};
+
+struct cv_system_performance_capabilities {
+	/* If != 0, allowed to collect data from other partitions */
+	__u8 perf_collect_privileged;
+
+	/* These following are only valid if counter_info_version >= 0x3 */
+#define CV_CM_GA       (1 << 7)
+#define CV_CM_EXPANDED (1 << 6)
+#define CV_CM_LAB      (1 << 5)
+	/* remaining bits are reserved */
+	__u8 capability_mask;
+	__u8 reserved[0xE];
+} __packed;
+
+#endif
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 13/20] powerpc/perf: Add 24x7 interface headers
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (11 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 12/20] powerpc/perf: Add hv_gpci interface header Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 14/20] powerpc/perf: Add a shared interface to get gpci version and capabilities Michael Ellerman
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

24x7 (also called hv_24x7 or H_24X7) is an interface to obtain
performance counters from the hypervisor. These counters do not have a
fixed format/possition and are instead documented in a "24x7 Catalog",
which is provided by the hypervisor (that interface is also documented
paritialy in the included hv-24x7-catalog.h and fully in at
https://raw.githubusercontent.com/jmesmon/catalog-24x7/master/hv-24x7-catalog.h ).

The 24x7 data access is simply a copy operation into a 4 dimentional
array of 64bit counters (from hypervisor to kernel memory). There is no
interupt triggered on overflow, these are completely disjoint from the
typical power pmu.

This method of obtaining performance counters from the hypervisor is
intended to paritialy replace the gpci interface.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/hv-24x7-catalog.h |  33 +++++++++++
 arch/powerpc/perf/hv-24x7.h         | 109 ++++++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)
 create mode 100644 arch/powerpc/perf/hv-24x7-catalog.h
 create mode 100644 arch/powerpc/perf/hv-24x7.h

diff --git a/arch/powerpc/perf/hv-24x7-catalog.h b/arch/powerpc/perf/hv-24x7-catalog.h
new file mode 100644
index 0000000..21b19dd
--- /dev/null
+++ b/arch/powerpc/perf/hv-24x7-catalog.h
@@ -0,0 +1,33 @@
+#ifndef LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_
+#define LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_
+
+#include <linux/types.h>
+
+/* From document "24x7 Event and Group Catalog Formats Proposal" v0.15 */
+
+struct hv_24x7_catalog_page_0 {
+#define HV_24X7_CATALOG_MAGIC 0x32347837 /* "24x7" in ASCII */
+	__be32 magic;
+	__be32 length; /* In 4096 byte pages */
+	__be64 version; /* XXX: arbitrary? what's the meaning/useage/purpose? */
+	__u8 build_time_stamp[16]; /* "YYYYMMDDHHMMSS\0\0" */
+	__u8 reserved2[32];
+	__be16 schema_data_offs; /* in 4096 byte pages */
+	__be16 schema_data_len;  /* in 4096 byte pages */
+	__be16 schema_entry_count;
+	__u8 reserved3[2];
+	__be16 event_data_offs;
+	__be16 event_data_len;
+	__be16 event_entry_count;
+	__u8 reserved4[2];
+	__be16 group_data_offs; /* in 4096 byte pages */
+	__be16 group_data_len;  /* in 4096 byte pages */
+	__be16 group_entry_count;
+	__u8 reserved5[2];
+	__be16 formula_data_offs; /* in 4096 byte pages */
+	__be16 formula_data_len;  /* in 4096 byte pages */
+	__be16 formula_entry_count;
+	__u8 reserved6[2];
+} __packed;
+
+#endif
diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h
new file mode 100644
index 0000000..720ebce
--- /dev/null
+++ b/arch/powerpc/perf/hv-24x7.h
@@ -0,0 +1,109 @@
+#ifndef LINUX_POWERPC_PERF_HV_24X7_H_
+#define LINUX_POWERPC_PERF_HV_24X7_H_
+
+#include <linux/types.h>
+
+struct hv_24x7_request {
+	/* PHYSICAL domains require enabling via phyp/hmc. */
+#define HV_24X7_PERF_DOMAIN_PHYSICAL_CHIP 0x01
+#define HV_24X7_PERF_DOMAIN_PHYSICAL_CORE 0x02
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_CORE   0x03
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_CHIP   0x04
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_NODE   0x05
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_REMOTE_NODE 0x06
+	__u8 performance_domain;
+	__u8 reserved[0x1];
+
+	/* bytes to read starting at @data_offset. must be a multiple of 8 */
+	__be16 data_size;
+
+	/*
+	 * byte offset within the perf domain to read from. must be 8 byte
+	 * aligned
+	 */
+	__be32 data_offset;
+
+	/*
+	 * only valid for VIRTUAL_PROCESSOR domains, ignored for others.
+	 * -1 means "current partition only"
+	 *  Enabling via phyp/hmc required for non-"-1" values. 0 forbidden
+	 *  unless requestor is 0.
+	 */
+	__be16 starting_lpar_ix;
+
+	/*
+	 * Ignored when @starting_lpar_ix == -1
+	 * Ignored when @performance_domain is not VIRTUAL_PROCESSOR_*
+	 * -1 means "infinite" or all
+	 */
+	__be16 max_num_lpars;
+
+	/* chip, core, or virtual processor based on @performance_domain */
+	__be16 starting_ix;
+	__be16 max_ix;
+} __packed;
+
+struct hv_24x7_request_buffer {
+	/* 0 - ? */
+	/* 1 - ? */
+#define HV_24X7_IF_VERSION_CURRENT 0x01
+	__u8 interface_version;
+	__u8 num_requests;
+	__u8 reserved[0xE];
+	struct hv_24x7_request requests[];
+} __packed;
+
+struct hv_24x7_result_element {
+	__be16 lpar_ix;
+
+	/*
+	 * represents the core, chip, or virtual processor based on the
+	 * request's @performance_domain
+	 */
+	__be16 domain_ix;
+
+	/* -1 if @performance_domain does not refer to a virtual processor */
+	__be32 lpar_cfg_instance_id;
+
+	/* size = @result_element_data_size of cointaining result. */
+	__u8 element_data[];
+} __packed;
+
+struct hv_24x7_result {
+	__u8 result_ix;
+
+	/*
+	 * 0 = not all result elements fit into the buffer, additional requests
+	 *     required
+	 * 1 = all result elements were returned
+	 */
+	__u8 results_complete;
+	__be16 num_elements_returned;
+
+	/* This is a copy of @data_size from the coresponding hv_24x7_request */
+	__be16 result_element_data_size;
+	__u8 reserved[0x2];
+
+	/* WARNING: only valid for first result element due to variable sizes
+	 *          of result elements */
+	/* struct hv_24x7_result_element[@num_elements_returned] */
+	struct hv_24x7_result_element elements[];
+} __packed;
+
+struct hv_24x7_data_result_buffer {
+	/* See versioning for request buffer */
+	__u8 interface_version;
+
+	__u8 num_results;
+	__u8 reserved[0x1];
+	__u8 failing_request_ix;
+	__be32 detailed_rc;
+	__be64 cec_cfg_instance_id;
+	__be64 catalog_version_num;
+	__u8 reserved2[0x8];
+	/* WARNING: only valid for the first result due to variable sizes of
+	 *	    results */
+	struct hv_24x7_result results[]; /* [@num_results] */
+} __packed;
+
+#endif
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 14/20] powerpc/perf: Add a shared interface to get gpci version and capabilities
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (12 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 13/20] powerpc/perf: Add 24x7 interface headers Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 15/20] powerpc/perf: Add macros for defining event fields & formats Michael Ellerman
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

This exposes a simple way to grab the firmware provided
collect_priveliged, ga, expanded, and lab capability bits. All of these
bits come in from the same gpci request, so we've exposed all of them.

Only the collect_priveliged bit is really used by the hv-gpci/hv-24x7
code, the other bits are simply exposed in sysfs to inform the user.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/hv-common.c | 39 +++++++++++++++++++++++++++++++++++++++
 arch/powerpc/perf/hv-common.h | 17 +++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 arch/powerpc/perf/hv-common.c
 create mode 100644 arch/powerpc/perf/hv-common.h

diff --git a/arch/powerpc/perf/hv-common.c b/arch/powerpc/perf/hv-common.c
new file mode 100644
index 0000000..47e02b3
--- /dev/null
+++ b/arch/powerpc/perf/hv-common.c
@@ -0,0 +1,39 @@
+#include <asm/io.h>
+#include <asm/hvcall.h>
+
+#include "hv-gpci.h"
+#include "hv-common.h"
+
+unsigned long hv_perf_caps_get(struct hv_perf_caps *caps)
+{
+	unsigned long r;
+	struct p {
+		struct hv_get_perf_counter_info_params params;
+		struct cv_system_performance_capabilities caps;
+	} __packed __aligned(sizeof(uint64_t));
+
+	struct p arg = {
+		.params = {
+			.counter_request = cpu_to_be32(
+					CIR_SYSTEM_PERFORMANCE_CAPABILITIES),
+			.starting_index = cpu_to_be32(-1),
+			.counter_info_version_in = 0,
+		}
+	};
+
+	r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
+			       virt_to_phys(&arg), sizeof(arg));
+
+	if (r)
+		return r;
+
+	pr_devel("capability_mask: 0x%x\n", arg.caps.capability_mask);
+
+	caps->version = arg.params.counter_info_version_out;
+	caps->collect_privileged = !!arg.caps.perf_collect_privileged;
+	caps->ga = !!(arg.caps.capability_mask & CV_CM_GA);
+	caps->expanded = !!(arg.caps.capability_mask & CV_CM_EXPANDED);
+	caps->lab = !!(arg.caps.capability_mask & CV_CM_LAB);
+
+	return r;
+}
diff --git a/arch/powerpc/perf/hv-common.h b/arch/powerpc/perf/hv-common.h
new file mode 100644
index 0000000..7e615bd
--- /dev/null
+++ b/arch/powerpc/perf/hv-common.h
@@ -0,0 +1,17 @@
+#ifndef LINUX_POWERPC_PERF_HV_COMMON_H_
+#define LINUX_POWERPC_PERF_HV_COMMON_H_
+
+#include <linux/types.h>
+
+struct hv_perf_caps {
+	u16 version;
+	u16 collect_privileged:1,
+	    ga:1,
+	    expanded:1,
+	    lab:1,
+	    unused:12;
+};
+
+unsigned long hv_perf_caps_get(struct hv_perf_caps *caps);
+
+#endif
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 15/20] powerpc/perf: Add macros for defining event fields & formats
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (13 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 14/20] powerpc/perf: Add a shared interface to get gpci version and capabilities Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 16/20] powerpc/perf: Add support for the hv gpci (get performance counter info) interface Michael Ellerman
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

Add two macros which generate functions to extract the relevent bits
from event->attr.config{,1,2}.

EVENT_DEFINE_RANGE() defines an accessor for a range of bits in the
event, as well as a "max" function that gives the maximum value of the
field based on the bit width.

EVENT_DEFINE_RANGE_FORMAT() defines the accessor & max routine and also
a format attribute for use in the PMU's attr_groups.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
[mpe: move to powerpc, ugly but descriptive macro names]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/hv-common.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/powerpc/perf/hv-common.h b/arch/powerpc/perf/hv-common.h
index 7e615bd..5d79cec 100644
--- a/arch/powerpc/perf/hv-common.h
+++ b/arch/powerpc/perf/hv-common.h
@@ -1,6 +1,7 @@
 #ifndef LINUX_POWERPC_PERF_HV_COMMON_H_
 #define LINUX_POWERPC_PERF_HV_COMMON_H_
 
+#include <linux/perf_event.h>
 #include <linux/types.h>
 
 struct hv_perf_caps {
@@ -14,4 +15,22 @@ struct hv_perf_caps {
 
 unsigned long hv_perf_caps_get(struct hv_perf_caps *caps);
 
+
+#define EVENT_DEFINE_RANGE_FORMAT(name, attr_var, bit_start, bit_end)	\
+PMU_FORMAT_ATTR(name, #attr_var ":" #bit_start "-" #bit_end);		\
+EVENT_DEFINE_RANGE(name, attr_var, bit_start, bit_end)
+
+#define EVENT_DEFINE_RANGE(name, attr_var, bit_start, bit_end)	\
+static u64 event_get_##name##_max(void)					\
+{									\
+	BUILD_BUG_ON((bit_start > bit_end)				\
+		    || (bit_end >= (sizeof(1ull) * 8)));		\
+	return (((1ull << (bit_end - bit_start)) - 1) << 1) + 1;	\
+}									\
+static u64 event_get_##name(struct perf_event *event)			\
+{									\
+	return (event->attr.attr_var >> (bit_start)) &			\
+		event_get_##name##_max();				\
+}
+
 #endif
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 16/20] powerpc/perf: Add support for the hv gpci (get performance counter info) interface
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (14 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 15/20] powerpc/perf: Add macros for defining event fields & formats Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 17/20] powerpc/perf: Add support for the hv 24x7 interface Michael Ellerman
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

This provides a basic link between perf and hv_gpci. Notably, it does
not yet support transactions and does not list any events (they can
still be manually composed).

Example usage via perf tool:

	perf stat -e 'hv_gpci/counter_info_version=3,offset=0,length=8,secondary_index=0,starting_index=0xffffffff,request=0x10/' -r 0 -C 0 -x ' ' sleep 0.1

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/hv-gpci.c | 294 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 294 insertions(+)
 create mode 100644 arch/powerpc/perf/hv-gpci.c

diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
new file mode 100644
index 0000000..278ba7b
--- /dev/null
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -0,0 +1,294 @@
+/*
+ * Hypervisor supplied "gpci" ("get performance counter info") performance
+ * counter support
+ *
+ * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
+ * Copyright 2014 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "hv-gpci: " fmt
+
+#include <linux/init.h>
+#include <linux/perf_event.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/io.h>
+
+#include "hv-gpci.h"
+#include "hv-common.h"
+
+/*
+ * Example usage:
+ *  perf stat -e 'hv_gpci/counter_info_version=3,offset=0,length=8,
+ *		  secondary_index=0,starting_index=0xffffffff,request=0x10/' ...
+ */
+
+/* u32 */
+EVENT_DEFINE_RANGE_FORMAT(request, config, 0, 31);
+/* u32 */
+EVENT_DEFINE_RANGE_FORMAT(starting_index, config, 32, 63);
+/* u16 */
+EVENT_DEFINE_RANGE_FORMAT(secondary_index, config1, 0, 15);
+/* u8 */
+EVENT_DEFINE_RANGE_FORMAT(counter_info_version, config1, 16, 23);
+/* u8, bytes of data (1-8) */
+EVENT_DEFINE_RANGE_FORMAT(length, config1, 24, 31);
+/* u32, byte offset */
+EVENT_DEFINE_RANGE_FORMAT(offset, config1, 32, 63);
+
+static struct attribute *format_attrs[] = {
+	&format_attr_request.attr,
+	&format_attr_starting_index.attr,
+	&format_attr_secondary_index.attr,
+	&format_attr_counter_info_version.attr,
+
+	&format_attr_offset.attr,
+	&format_attr_length.attr,
+	NULL,
+};
+
+static struct attribute_group format_group = {
+	.name = "format",
+	.attrs = format_attrs,
+};
+
+#define HV_CAPS_ATTR(_name, _format)				\
+static ssize_t _name##_show(struct device *dev,			\
+			    struct device_attribute *attr,	\
+			    char *page)				\
+{								\
+	struct hv_perf_caps caps;				\
+	unsigned long hret = hv_perf_caps_get(&caps);		\
+	if (hret)						\
+		return -EIO;					\
+								\
+	return sprintf(page, _format, caps._name);		\
+}								\
+static struct device_attribute hv_caps_attr_##_name = __ATTR_RO(_name)
+
+static ssize_t kernel_version_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *page)
+{
+	return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT);
+}
+
+DEVICE_ATTR_RO(kernel_version);
+HV_CAPS_ATTR(version, "0x%x\n");
+HV_CAPS_ATTR(ga, "%d\n");
+HV_CAPS_ATTR(expanded, "%d\n");
+HV_CAPS_ATTR(lab, "%d\n");
+HV_CAPS_ATTR(collect_privileged, "%d\n");
+
+static struct attribute *interface_attrs[] = {
+	&dev_attr_kernel_version.attr,
+	&hv_caps_attr_version.attr,
+	&hv_caps_attr_ga.attr,
+	&hv_caps_attr_expanded.attr,
+	&hv_caps_attr_lab.attr,
+	&hv_caps_attr_collect_privileged.attr,
+	NULL,
+};
+
+static struct attribute_group interface_group = {
+	.name = "interface",
+	.attrs = interface_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+	&format_group,
+	&interface_group,
+	NULL,
+};
+
+#define GPCI_MAX_DATA_BYTES \
+	(1024 - sizeof(struct hv_get_perf_counter_info_params))
+
+static unsigned long single_gpci_request(u32 req, u32 starting_index,
+		u16 secondary_index, u8 version_in, u32 offset, u8 length,
+		u64 *value)
+{
+	unsigned long ret;
+	size_t i;
+	u64 count;
+
+	struct {
+		struct hv_get_perf_counter_info_params params;
+		uint8_t bytes[GPCI_MAX_DATA_BYTES];
+	} __packed __aligned(sizeof(uint64_t)) arg = {
+		.params = {
+			.counter_request = cpu_to_be32(req),
+			.starting_index = cpu_to_be32(starting_index),
+			.secondary_index = cpu_to_be16(secondary_index),
+			.counter_info_version_in = version_in,
+		}
+	};
+
+	ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
+			virt_to_phys(&arg), sizeof(arg));
+	if (ret) {
+		pr_devel("hcall failed: 0x%lx\n", ret);
+		return ret;
+	}
+
+	/*
+	 * we verify offset and length are within the zeroed buffer at event
+	 * init.
+	 */
+	count = 0;
+	for (i = offset; i < offset + length; i++)
+		count |= arg.bytes[i] << (i - offset);
+
+	*value = count;
+	return ret;
+}
+
+static u64 h_gpci_get_value(struct perf_event *event)
+{
+	u64 count;
+	unsigned long ret = single_gpci_request(event_get_request(event),
+					event_get_starting_index(event),
+					event_get_secondary_index(event),
+					event_get_counter_info_version(event),
+					event_get_offset(event),
+					event_get_length(event),
+					&count);
+	if (ret)
+		return 0;
+	return count;
+}
+
+static void h_gpci_event_update(struct perf_event *event)
+{
+	s64 prev;
+	u64 now = h_gpci_get_value(event);
+	prev = local64_xchg(&event->hw.prev_count, now);
+	local64_add(now - prev, &event->count);
+}
+
+static void h_gpci_event_start(struct perf_event *event, int flags)
+{
+	local64_set(&event->hw.prev_count, h_gpci_get_value(event));
+}
+
+static void h_gpci_event_stop(struct perf_event *event, int flags)
+{
+	h_gpci_event_update(event);
+}
+
+static int h_gpci_event_add(struct perf_event *event, int flags)
+{
+	if (flags & PERF_EF_START)
+		h_gpci_event_start(event, flags);
+
+	return 0;
+}
+
+static int h_gpci_event_init(struct perf_event *event)
+{
+	u64 count;
+	u8 length;
+
+	/* Not our event */
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/* config2 is unused */
+	if (event->attr.config2) {
+		pr_devel("config2 set when reserved\n");
+		return -EINVAL;
+	}
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    is_sampling_event(event)) /* no sampling */
+		return -EINVAL;
+
+	/* no branch sampling */
+	if (has_branch_stack(event))
+		return -EOPNOTSUPP;
+
+	length = event_get_length(event);
+	if (length < 1 || length > 8) {
+		pr_devel("length invalid\n");
+		return -EINVAL;
+	}
+
+	/* last byte within the buffer? */
+	if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) {
+		pr_devel("request outside of buffer: %zu > %zu\n",
+				(size_t)event_get_offset(event) + length,
+				GPCI_MAX_DATA_BYTES);
+		return -EINVAL;
+	}
+
+	/* check if the request works... */
+	if (single_gpci_request(event_get_request(event),
+				event_get_starting_index(event),
+				event_get_secondary_index(event),
+				event_get_counter_info_version(event),
+				event_get_offset(event),
+				length,
+				&count)) {
+		pr_devel("gpci hcall failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int h_gpci_event_idx(struct perf_event *event)
+{
+	return 0;
+}
+
+static struct pmu h_gpci_pmu = {
+	.task_ctx_nr = perf_invalid_context,
+
+	.name = "hv_gpci",
+	.attr_groups = attr_groups,
+	.event_init  = h_gpci_event_init,
+	.add         = h_gpci_event_add,
+	.del         = h_gpci_event_stop,
+	.start       = h_gpci_event_start,
+	.stop        = h_gpci_event_stop,
+	.read        = h_gpci_event_update,
+	.event_idx   = h_gpci_event_idx,
+};
+
+static int hv_gpci_init(void)
+{
+	int r;
+	unsigned long hret;
+	struct hv_perf_caps caps;
+
+	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+		pr_info("not a virtualized system, not enabling\n");
+		return -ENODEV;
+	}
+
+	hret = hv_perf_caps_get(&caps);
+	if (hret) {
+		pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
+				hret);
+		return -ENODEV;
+	}
+
+	r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+device_initcall(hv_gpci_init);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 17/20] powerpc/perf: Add support for the hv 24x7 interface
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (15 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 16/20] powerpc/perf: Add support for the hv gpci (get performance counter info) interface Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 18/20] powerpc/perf: Add kconfig option for hypervisor provided counters Michael Ellerman
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

This provides a basic interface between hv_24x7 and perf. Similar to
the one provided for gpci, it lacks transaction support and does not
list any events.

Example usage via perf tool:

	perf stat -e 'hv_24x7/domain=2,offset=8,starting_index=0,lpar=0xffffffff/' -r 0 -C 0 -x ' ' sleep 0.1

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/hv-24x7.c | 510 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 510 insertions(+)
 create mode 100644 arch/powerpc/perf/hv-24x7.c

diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
new file mode 100644
index 0000000..297c9105
--- /dev/null
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -0,0 +1,510 @@
+/*
+ * Hypervisor supplied "24x7" performance counter support
+ *
+ * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
+ * Copyright 2014 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "hv-24x7: " fmt
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/io.h>
+
+#include "hv-24x7.h"
+#include "hv-24x7-catalog.h"
+#include "hv-common.h"
+
+/*
+ * TODO: Merging events:
+ * - Think of the hcall as an interface to a 4d array of counters:
+ *   - x = domains
+ *   - y = indexes in the domain (core, chip, vcpu, node, etc)
+ *   - z = offset into the counter space
+ *   - w = lpars (guest vms, "logical partitions")
+ * - A single request is: x,y,y_last,z,z_last,w,w_last
+ *   - this means we can retrieve a rectangle of counters in y,z for a single x.
+ *
+ * - Things to consider (ignoring w):
+ *   - input  cost_per_request = 16
+ *   - output cost_per_result(ys,zs)  = 8 + 8 * ys + ys * zs
+ *   - limited number of requests per hcall (must fit into 4K bytes)
+ *     - 4k = 16 [buffer header] - 16 [request size] * request_count
+ *     - 255 requests per hcall
+ *   - sometimes it will be more efficient to read extra data and discard
+ */
+
+/*
+ * Example usage:
+ *  perf stat -e 'hv_24x7/domain=2,offset=8,starting_index=0,lpar=0xffffffff/'
+ */
+
+/* u3 0-6, one of HV_24X7_PERF_DOMAIN */
+EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
+/* u16 */
+EVENT_DEFINE_RANGE_FORMAT(starting_index, config, 16, 31);
+/* u32, see "data_offset" */
+EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63);
+/* u16 */
+EVENT_DEFINE_RANGE_FORMAT(lpar, config1, 0, 15);
+
+EVENT_DEFINE_RANGE(reserved1, config,   4, 15);
+EVENT_DEFINE_RANGE(reserved2, config1, 16, 63);
+EVENT_DEFINE_RANGE(reserved3, config2,  0, 63);
+
+static struct attribute *format_attrs[] = {
+	&format_attr_domain.attr,
+	&format_attr_offset.attr,
+	&format_attr_starting_index.attr,
+	&format_attr_lpar.attr,
+	NULL,
+};
+
+static struct attribute_group format_group = {
+	.name = "format",
+	.attrs = format_attrs,
+};
+
+static struct kmem_cache *hv_page_cache;
+
+/*
+ * read_offset_data - copy data from one buffer to another while treating the
+ *                    source buffer as a small view on the total avaliable
+ *                    source data.
+ *
+ * @dest: buffer to copy into
+ * @dest_len: length of @dest in bytes
+ * @requested_offset: the offset within the source data we want. Must be > 0
+ * @src: buffer to copy data from
+ * @src_len: length of @src in bytes
+ * @source_offset: the offset in the sorce data that (src,src_len) refers to.
+ *                 Must be > 0
+ *
+ * returns the number of bytes copied.
+ *
+ * The following ascii art shows the various buffer possitioning we need to
+ * handle, assigns some arbitrary varibles to points on the buffer, and then
+ * shows how we fiddle with those values to get things we care about (copy
+ * start in src and copy len)
+ *
+ * s = @src buffer
+ * d = @dest buffer
+ * '.' areas in d are written to.
+ *
+ *                       u
+ *   x         w	 v  z
+ * d           |.........|
+ * s |----------------------|
+ *
+ *                      u
+ *   x         w	z     v
+ * d           |........------|
+ * s |------------------|
+ *
+ *   x         w        u,z,v
+ * d           |........|
+ * s |------------------|
+ *
+ *   x,w                u,v,z
+ * d |..................|
+ * s |------------------|
+ *
+ *   x        u
+ *   w        v		z
+ * d |........|
+ * s |------------------|
+ *
+ *   x      z   w      v
+ * d            |------|
+ * s |------|
+ *
+ * x = source_offset
+ * w = requested_offset
+ * z = source_offset + src_len
+ * v = requested_offset + dest_len
+ *
+ * w_offset_in_s = w - x = requested_offset - source_offset
+ * z_offset_in_s = z - x = src_len
+ * v_offset_in_s = v - x = request_offset + dest_len - src_len
+ */
+static ssize_t read_offset_data(void *dest, size_t dest_len,
+				loff_t requested_offset, void *src,
+				size_t src_len, loff_t source_offset)
+{
+	size_t w_offset_in_s = requested_offset - source_offset;
+	size_t z_offset_in_s = src_len;
+	size_t v_offset_in_s = requested_offset + dest_len - src_len;
+	size_t u_offset_in_s = min(z_offset_in_s, v_offset_in_s);
+	size_t copy_len = u_offset_in_s - w_offset_in_s;
+
+	if (requested_offset < 0 || source_offset < 0)
+		return -EINVAL;
+
+	if (z_offset_in_s <= w_offset_in_s)
+		return 0;
+
+	memcpy(dest, src + w_offset_in_s, copy_len);
+	return copy_len;
+}
+
+static unsigned long h_get_24x7_catalog_page(char page[static 4096],
+					     u32 version, u32 index)
+{
+	WARN_ON(!IS_ALIGNED((unsigned long)page, 4096));
+	return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE,
+			virt_to_phys(page),
+			version,
+			index);
+}
+
+static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
+			    struct bin_attribute *bin_attr, char *buf,
+			    loff_t offset, size_t count)
+{
+	unsigned long hret;
+	ssize_t ret = 0;
+	size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
+	loff_t page_offset = 0;
+	uint32_t catalog_version_num = 0;
+	void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
+	struct hv_24x7_catalog_page_0 *page_0 = page;
+	if (!page)
+		return -ENOMEM;
+
+	hret = h_get_24x7_catalog_page(page, 0, 0);
+	if (hret) {
+		ret = -EIO;
+		goto e_free;
+	}
+
+	catalog_version_num = be32_to_cpu(page_0->version);
+	catalog_page_len = be32_to_cpu(page_0->length);
+	catalog_len = catalog_page_len * 4096;
+
+	page_offset = offset / 4096;
+	page_count  = count  / 4096;
+
+	if (page_offset >= catalog_page_len)
+		goto e_free;
+
+	if (page_offset != 0) {
+		hret = h_get_24x7_catalog_page(page, catalog_version_num,
+					       page_offset);
+		if (hret) {
+			ret = -EIO;
+			goto e_free;
+		}
+	}
+
+	ret = read_offset_data(buf, count, offset,
+				page, 4096, page_offset * 4096);
+e_free:
+	if (hret)
+		pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n",
+				catalog_version_num, page_offset, hret);
+	kfree(page);
+
+	pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n",
+			offset, page_offset, count, page_count, catalog_len,
+			catalog_page_len, ret);
+
+	return ret;
+}
+
+#define PAGE_0_ATTR(_name, _fmt, _expr)				\
+static ssize_t _name##_show(struct device *dev,			\
+			    struct device_attribute *dev_attr,	\
+			    char *buf)				\
+{								\
+	unsigned long hret;					\
+	ssize_t ret = 0;					\
+	void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);	\
+	struct hv_24x7_catalog_page_0 *page_0 = page;		\
+	if (!page)						\
+		return -ENOMEM;					\
+	hret = h_get_24x7_catalog_page(page, 0, 0);		\
+	if (hret) {						\
+		ret = -EIO;					\
+		goto e_free;					\
+	}							\
+	ret = sprintf(buf, _fmt, _expr);			\
+e_free:								\
+	kfree(page);						\
+	return ret;						\
+}								\
+static DEVICE_ATTR_RO(_name)
+
+PAGE_0_ATTR(catalog_version, "%lld\n",
+		(unsigned long long)be32_to_cpu(page_0->version));
+PAGE_0_ATTR(catalog_len, "%lld\n",
+		(unsigned long long)be32_to_cpu(page_0->length) * 4096);
+static BIN_ATTR_RO(catalog, 0/* real length varies */);
+
+static struct bin_attribute *if_bin_attrs[] = {
+	&bin_attr_catalog,
+	NULL,
+};
+
+static struct attribute *if_attrs[] = {
+	&dev_attr_catalog_len.attr,
+	&dev_attr_catalog_version.attr,
+	NULL,
+};
+
+static struct attribute_group if_group = {
+	.name = "interface",
+	.bin_attrs = if_bin_attrs,
+	.attrs = if_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+	&format_group,
+	&if_group,
+	NULL,
+};
+
+static bool is_physical_domain(int domain)
+{
+	return  domain == HV_24X7_PERF_DOMAIN_PHYSICAL_CHIP ||
+		domain == HV_24X7_PERF_DOMAIN_PHYSICAL_CORE;
+}
+
+static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
+					 u16 lpar, u64 *res,
+					 bool success_expected)
+{
+	unsigned long ret;
+
+	/*
+	 * request_buffer and result_buffer are not required to be 4k aligned,
+	 * but are not allowed to cross any 4k boundary. Aligning them to 4k is
+	 * the simplest way to ensure that.
+	 */
+	struct reqb {
+		struct hv_24x7_request_buffer buf;
+		struct hv_24x7_request req;
+	} __packed __aligned(4096) request_buffer = {
+		.buf = {
+			.interface_version = HV_24X7_IF_VERSION_CURRENT,
+			.num_requests = 1,
+		},
+		.req = {
+			.performance_domain = domain,
+			.data_size = cpu_to_be16(8),
+			.data_offset = cpu_to_be32(offset),
+			.starting_lpar_ix = cpu_to_be16(lpar),
+			.max_num_lpars = cpu_to_be16(1),
+			.starting_ix = cpu_to_be16(ix),
+			.max_ix = cpu_to_be16(1),
+		}
+	};
+
+	struct resb {
+		struct hv_24x7_data_result_buffer buf;
+		struct hv_24x7_result res;
+		struct hv_24x7_result_element elem;
+		__be64 result;
+	} __packed __aligned(4096) result_buffer = {};
+
+	ret = plpar_hcall_norets(H_GET_24X7_DATA,
+			virt_to_phys(&request_buffer), sizeof(request_buffer),
+			virt_to_phys(&result_buffer),  sizeof(result_buffer));
+
+	if (ret) {
+		if (success_expected)
+			pr_err_ratelimited("hcall failed: %d %#x %#x %d => 0x%lx (%ld) detail=0x%x failing ix=%x\n",
+					domain, offset, ix, lpar,
+					ret, ret,
+					result_buffer.buf.detailed_rc,
+					result_buffer.buf.failing_request_ix);
+		return ret;
+	}
+
+	*res = be64_to_cpu(result_buffer.result);
+	return ret;
+}
+
+static unsigned long event_24x7_request(struct perf_event *event, u64 *res,
+		bool success_expected)
+{
+	return single_24x7_request(event_get_domain(event),
+				event_get_offset(event),
+				event_get_starting_index(event),
+				event_get_lpar(event),
+				res,
+				success_expected);
+}
+
+static int h_24x7_event_init(struct perf_event *event)
+{
+	struct hv_perf_caps caps;
+	unsigned domain;
+	unsigned long hret;
+	u64 ct;
+
+	/* Not our event */
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/* Unused areas must be 0 */
+	if (event_get_reserved1(event) ||
+	    event_get_reserved2(event) ||
+	    event_get_reserved3(event)) {
+		pr_devel("reserved set when forbidden 0x%llx(0x%llx) 0x%llx(0x%llx) 0x%llx(0x%llx)\n",
+				event->attr.config,
+				event_get_reserved1(event),
+				event->attr.config1,
+				event_get_reserved2(event),
+				event->attr.config2,
+				event_get_reserved3(event));
+		return -EINVAL;
+	}
+
+	/* unsupported modes and filters */
+	if (event->attr.exclude_user   ||
+	    event->attr.exclude_kernel ||
+	    event->attr.exclude_hv     ||
+	    event->attr.exclude_idle   ||
+	    event->attr.exclude_host   ||
+	    event->attr.exclude_guest  ||
+	    is_sampling_event(event)) /* no sampling */
+		return -EINVAL;
+
+	/* no branch sampling */
+	if (has_branch_stack(event))
+		return -EOPNOTSUPP;
+
+	/* offset must be 8 byte aligned */
+	if (event_get_offset(event) % 8) {
+		pr_devel("bad alignment\n");
+		return -EINVAL;
+	}
+
+	/* Domains above 6 are invalid */
+	domain = event_get_domain(event);
+	if (domain > 6) {
+		pr_devel("invalid domain %d\n", domain);
+		return -EINVAL;
+	}
+
+	hret = hv_perf_caps_get(&caps);
+	if (hret) {
+		pr_devel("could not get capabilities: rc=%ld\n", hret);
+		return -EIO;
+	}
+
+	/* PHYSICAL domains & other lpars require extra capabilities */
+	if (!caps.collect_privileged && (is_physical_domain(domain) ||
+		(event_get_lpar(event) != event_get_lpar_max()))) {
+		pr_devel("hv permisions disallow: is_physical_domain:%d, lpar=0x%llx\n",
+				is_physical_domain(domain),
+				event_get_lpar(event));
+		return -EACCES;
+	}
+
+	/* see if the event complains */
+	if (event_24x7_request(event, &ct, false)) {
+		pr_devel("test hcall failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static u64 h_24x7_get_value(struct perf_event *event)
+{
+	unsigned long ret;
+	u64 ct;
+	ret = event_24x7_request(event, &ct, true);
+	if (ret)
+		/* We checked this in event init, shouldn't fail here... */
+		return 0;
+
+	return ct;
+}
+
+static void h_24x7_event_update(struct perf_event *event)
+{
+	s64 prev;
+	u64 now;
+	now = h_24x7_get_value(event);
+	prev = local64_xchg(&event->hw.prev_count, now);
+	local64_add(now - prev, &event->count);
+}
+
+static void h_24x7_event_start(struct perf_event *event, int flags)
+{
+	if (flags & PERF_EF_RELOAD)
+		local64_set(&event->hw.prev_count, h_24x7_get_value(event));
+}
+
+static void h_24x7_event_stop(struct perf_event *event, int flags)
+{
+	h_24x7_event_update(event);
+}
+
+static int h_24x7_event_add(struct perf_event *event, int flags)
+{
+	if (flags & PERF_EF_START)
+		h_24x7_event_start(event, flags);
+
+	return 0;
+}
+
+static int h_24x7_event_idx(struct perf_event *event)
+{
+	return 0;
+}
+
+static struct pmu h_24x7_pmu = {
+	.task_ctx_nr = perf_invalid_context,
+
+	.name = "hv_24x7",
+	.attr_groups = attr_groups,
+	.event_init  = h_24x7_event_init,
+	.add         = h_24x7_event_add,
+	.del         = h_24x7_event_stop,
+	.start       = h_24x7_event_start,
+	.stop        = h_24x7_event_stop,
+	.read        = h_24x7_event_update,
+	.event_idx   = h_24x7_event_idx,
+};
+
+static int hv_24x7_init(void)
+{
+	int r;
+	unsigned long hret;
+	struct hv_perf_caps caps;
+
+	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+		pr_info("not a virtualized system, not enabling\n");
+		return -ENODEV;
+	}
+
+	hret = hv_perf_caps_get(&caps);
+	if (hret) {
+		pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
+				hret);
+		return -ENODEV;
+	}
+
+	hv_page_cache = kmem_cache_create("hv-page-4096", 4096, 4096, 0, NULL);
+	if (!hv_page_cache)
+		return -ENOMEM;
+
+	r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+device_initcall(hv_24x7_init);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 18/20] powerpc/perf: Add kconfig option for hypervisor provided counters
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (16 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 17/20] powerpc/perf: Add support for the hv 24x7 interface Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 19/20] powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes Michael Ellerman
  2014-03-14  5:00 ` [PATCH 20/20] powerpc/perf: Fix handling of L3 events with bank == 1 Michael Ellerman
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

The commit adds a Kconfig option which allows the hv_gpci and hv_24x7
PMUs, added in the preceeding commits, to be built.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/Makefile             |  2 ++
 arch/powerpc/platforms/pseries/Kconfig | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 60d71ee..f9c083a 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -11,5 +11,7 @@ obj32-$(CONFIG_PPC_PERF_CTRS)	+= mpc7450-pmu.o
 obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
 obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o
 
+obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o
+
 obj-$(CONFIG_PPC64)		+= $(obj64-y)
 obj-$(CONFIG_PPC32)		+= $(obj32-y)
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 80b1d57..2cb8b77 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -111,6 +111,18 @@ config CMM
 	  will be reused for other LPARs. The interface allows firmware to
 	  balance memory across many LPARs.
 
+config HV_PERF_CTRS
+       bool "Hypervisor supplied PMU events (24x7 & GPCI)"
+       default y
+       depends on PERF_EVENTS && PPC_PSERIES
+       help
+	  Enable access to hypervisor supplied counters in perf. Currently,
+	  this enables code that uses the hcall GetPerfCounterInfo and 24x7
+	  interfaces to retrieve counters. GPCI exists on Power 6 and later
+	  systems. 24x7 is available on Power 8 systems.
+
+          If unsure, select Y.
+
 config DTL
 	bool "Dispatch Trace Log"
 	depends on PPC_SPLPAR && DEBUG_FS
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 19/20] powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (17 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 18/20] powerpc/perf: Add kconfig option for hypervisor provided counters Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  2014-03-14  5:00 ` [PATCH 20/20] powerpc/perf: Fix handling of L3 events with bank == 1 Michael Ellerman
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

From: Cody P Schafer <cody@linux.vnet.ibm.com>

gpci and 24x7 expose some device specific attributes. Add some
documentation for them.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 .../testing/sysfs-bus-event_source-devices-hv_24x7 | 23 ++++++++++++
 .../testing/sysfs-bus-event_source-devices-hv_gpci | 43 ++++++++++++++++++++++
 2 files changed, 66 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
 create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci

diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
new file mode 100644
index 0000000..e78ee79
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
@@ -0,0 +1,23 @@
+What:		/sys/bus/event_source/devices/hv_24x7/interface/catalog
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		Provides access to the binary "24x7 catalog" provided by the
+		hypervisor on POWER7 and 8 systems. This catalog lists events
+		avaliable from the powerpc "hv_24x7" pmu. Its format is
+		documented here:
+		https://raw.githubusercontent.com/jmesmon/catalog-24x7/master/hv-24x7-catalog.h
+
+What:		/sys/bus/event_source/devices/hv_24x7/interface/catalog_length
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		A number equal to the length in bytes of the catalog. This is
+		also extractable from the provided binary "catalog" sysfs entry.
+
+What:		/sys/bus/event_source/devices/hv_24x7/interface/catalog_version
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		Exposes the "version" field of the 24x7 catalog. This is also
+		extractable from the provided binary "catalog" sysfs entry.
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
new file mode 100644
index 0000000..3fa58c2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
@@ -0,0 +1,43 @@
+What:		/sys/bus/event_source/devices/hv_gpci/interface/collect_privileged
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		'0' if the hypervisor is configured to forbid access to event
+		counters being accumulated by other guests and to physical
+		domain event counters.
+		'1' if that access is allowed.
+
+What:		/sys/bus/event_source/devices/hv_gpci/interface/ga
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		0 or 1. Indicates whether we have access to "GA" events (listed
+		in arch/powerpc/perf/hv-gpci.h).
+
+What:		/sys/bus/event_source/devices/hv_gpci/interface/expanded
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		0 or 1. Indicates whether we have access to "EXPANDED" events (listed
+		in arch/powerpc/perf/hv-gpci.h).
+
+What:		/sys/bus/event_source/devices/hv_gpci/interface/lab
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		0 or 1. Indicates whether we have access to "LAB" events (listed
+		in arch/powerpc/perf/hv-gpci.h).
+
+What:		/sys/bus/event_source/devices/hv_gpci/interface/version
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		A number indicating the version of the gpci interface that the
+		hypervisor reports supporting.
+
+What:		/sys/bus/event_source/devices/hv_gpci/interface/kernel_version
+Date:		February 2014
+Contact:	Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+		A number indicating the latest version of the gpci interface
+		that the kernel is aware of.
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 20/20] powerpc/perf: Fix handling of L3 events with bank == 1
  2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
                   ` (18 preceding siblings ...)
  2014-03-14  5:00 ` [PATCH 19/20] powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes Michael Ellerman
@ 2014-03-14  5:00 ` Michael Ellerman
  19 siblings, 0 replies; 21+ messages in thread
From: Michael Ellerman @ 2014-03-14  5:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cody, khandual

Currently we reject events which have the L3 bank == 1, such as
0x000084918F, because the cache field is non-zero.

However that is incorrect, because although the bank is non-zero, the
value we would write into MMCRC is zero, and so we can count the event.

So fix the check to ignore the bank selector when checking whether the
cache selector is non-zero.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/perf/power8-pmu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 3ad363d..fe2763b 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -325,9 +325,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
 		 * HV writable, and there is no API for guest kernels to modify
 		 * it. The solution is for the hypervisor to initialise the
 		 * field to zeroes, and for us to only ever allow events that
-		 * have a cache selector of zero.
+		 * have a cache selector of zero. The bank selector (bit 3) is
+		 * irrelevant, as long as the rest of the value is 0.
 		 */
-		if (cache)
+		if (cache & 0x7)
 			return -1;
 
 	} else if (event & EVENT_IS_L1) {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-03-14  5:00 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-14  5:00 powerpc/perf: patches for 3.15 Michael Ellerman
2014-03-14  5:00 ` [PATCH 01/20] powerpc/perf: Make some new raw event codes available in sysfs Michael Ellerman
2014-03-14  5:00 ` [PATCH 02/20] powerpc/perf: Define perf_event_print_debug() to print PMU register values Michael Ellerman
2014-03-14  5:00 ` [PATCH 03/20] powerpc: Add a cpu feature CPU_FTR_PMAO_BUG Michael Ellerman
2014-03-14  5:00 ` [PATCH 04/20] powerpc/perf: Add lost exception workaround Michael Ellerman
2014-03-14  5:00 ` [PATCH 05/20] powerpc/perf: Reject EBB events which specify a sample_type Michael Ellerman
2014-03-14  5:00 ` [PATCH 06/20] powerpc/perf: Clean up the EBB hash defines a little Michael Ellerman
2014-03-14  5:00 ` [PATCH 07/20] powerpc/perf: Avoid mutating event in power8_get_constraint() Michael Ellerman
2014-03-14  5:00 ` [PATCH 08/20] powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB Michael Ellerman
2014-03-14  5:00 ` [PATCH 09/20] powerpc/perf: Enable BHRB access for EBB events Michael Ellerman
2014-03-14  5:00 ` [PATCH 10/20] sysfs: create bin_attributes under the requested group Michael Ellerman
2014-03-14  5:00 ` [PATCH 11/20] powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info) Michael Ellerman
2014-03-14  5:00 ` [PATCH 12/20] powerpc/perf: Add hv_gpci interface header Michael Ellerman
2014-03-14  5:00 ` [PATCH 13/20] powerpc/perf: Add 24x7 interface headers Michael Ellerman
2014-03-14  5:00 ` [PATCH 14/20] powerpc/perf: Add a shared interface to get gpci version and capabilities Michael Ellerman
2014-03-14  5:00 ` [PATCH 15/20] powerpc/perf: Add macros for defining event fields & formats Michael Ellerman
2014-03-14  5:00 ` [PATCH 16/20] powerpc/perf: Add support for the hv gpci (get performance counter info) interface Michael Ellerman
2014-03-14  5:00 ` [PATCH 17/20] powerpc/perf: Add support for the hv 24x7 interface Michael Ellerman
2014-03-14  5:00 ` [PATCH 18/20] powerpc/perf: Add kconfig option for hypervisor provided counters Michael Ellerman
2014-03-14  5:00 ` [PATCH 19/20] powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes Michael Ellerman
2014-03-14  5:00 ` [PATCH 20/20] powerpc/perf: Fix handling of L3 events with bank == 1 Michael Ellerman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).