This patchset adds support for some perf events features,
targeted at ARM64, implemented in a generic fashion.
The two main features are as follows:
- support for arch/vendor/platform pmu events directory structure
- support for parsing standard architecture pmu events
On the back of these, the Cavium ThunderX2, ARM Cortex-A53,
and HiSilicon hip08 JSONs are relocated/added/updated.
In addition, there are a patch to drop mutli-mapfile.csv support.
Differences to RFC:
- reworked patch for arch standard events
- added arch standard event keyword support
- use some macros to make the code more condense
- use <linux/list_head.h>
- standardised some function names
- updated README
- for patch to support vendor subdir, add check for
unknown dirent type
-add patch to drop mutliple mapfile.csv support
- dealt with new cortex a53 JSONs
John Garry (9):
perf vendor events: drop incomplete multiple mapfile support
perf utils: add support for pmu events vendor sub-directory
perf vendor events arm64: Relocate ThunderX2 JSON
perf vendor events arm64: Relocate Cortex A53 JSONs
perf utils: add support for arch standard events
perf utils: add armv8-recommended.json
perf utils: fixup Cavium ThunderX2 JSON to use ARMv8 recommended
events
perf utils: fixup ARM Cortex A53 JSONs to use ARMv8 recommended events
perf utils: add HiSilicon hip08 JSON file
tools/perf/pmu-events/Build | 1 +
tools/perf/pmu-events/README | 15 +-
.../arch/arm64/arm/cortex-a53/branch.json | 26 ++
.../pmu-events/arch/arm64/arm/cortex-a53/bus.json | 10 +
.../arch/arm64/arm/cortex-a53/cache.json | 27 ++
.../arch/arm64/arm/cortex-a53/memory.json | 12 +
.../arch/arm64/arm/cortex-a53/other.json | 30 ++
.../arch/arm64/arm/cortex-a53/pipeline.json | 52 +++
.../pmu-events/arch/arm64/armv8-recommended.json | 452 +++++++++++++++++++++
.../arch/arm64/cavium/thunderx2-imp-def.json | 62 ---
.../arch/arm64/cavium/thunderx2/core-imp-def.json | 42 ++
.../pmu-events/arch/arm64/cortex-a53/branch.json | 27 --
.../perf/pmu-events/arch/arm64/cortex-a53/bus.json | 22 -
.../pmu-events/arch/arm64/cortex-a53/cache.json | 27 --
.../pmu-events/arch/arm64/cortex-a53/memory.json | 22 -
.../pmu-events/arch/arm64/cortex-a53/other.json | 32 --
.../pmu-events/arch/arm64/cortex-a53/pipeline.json | 52 ---
.../arch/arm64/hisilicon/hip08/core-imp-def.json | 140 +++++++
tools/perf/pmu-events/arch/arm64/mapfile.csv | 5 +-
tools/perf/pmu-events/jevents.c | 265 +++++++++++-
20 files changed, 1050 insertions(+), 271 deletions(-)
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
create mode 100644 tools/perf/pmu-events/arch/arm64/armv8-recommended.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cavium/thunderx2-imp-def.json
create mode 100644 tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/other.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json
create mode 100644 tools/perf/pmu-events/arch/arm64/hisilicon/hip08/core-imp-def.json
--
1.9.1
Add JSON for ARMv8 IMPLEMENTATION DEFINED recommended events.
The JSON is copied from ARMv8 architecture reference manual,
available here:
https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf
Signed-off-by: John Garry <[email protected]>
Signed-off-by: Shaokun Zhang <[email protected]>
---
.../pmu-events/arch/arm64/armv8-recommended.json | 452 +++++++++++++++++++++
1 file changed, 452 insertions(+)
create mode 100644 tools/perf/pmu-events/arch/arm64/armv8-recommended.json
diff --git a/tools/perf/pmu-events/arch/arm64/armv8-recommended.json b/tools/perf/pmu-events/arch/arm64/armv8-recommended.json
new file mode 100644
index 0000000..6328828
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/armv8-recommended.json
@@ -0,0 +1,452 @@
+[
+ {
+ "PublicDescription": "Attributable Level 1 data cache access, read",
+ "EventCode": "0x40",
+ "EventName": "L1D_CACHE_RD",
+ "BriefDescription": "L1D cache access, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache access, write",
+ "EventCode": "0x41",
+ "EventName": "L1D_CACHE_WR",
+ "BriefDescription": "L1D cache access, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache refill, read",
+ "EventCode": "0x42",
+ "EventName": "L1D_CACHE_REFILL_RD",
+ "BriefDescription": "L1D cache refill, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache refill, write",
+ "EventCode": "0x43",
+ "EventName": "L1D_CACHE_REFILL_WR",
+ "BriefDescription": "L1D cache refill, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache refill, inner",
+ "EventCode": "0x44",
+ "EventName": "L1D_CACHE_REFILL_INNER",
+ "BriefDescription": "L1D cache refill, inner"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache refill, outer",
+ "EventCode": "0x45",
+ "EventName": "L1D_CACHE_REFILL_OUTER",
+ "BriefDescription": "L1D cache refill, outer"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache Write-Back, victim",
+ "EventCode": "0x46",
+ "EventName": "L1D_CACHE_WB_VICTIM",
+ "BriefDescription": "L1D cache Write-Back, victim"
+ },
+ {
+ "PublicDescription": "Level 1 data cache Write-Back, cleaning and coherency",
+ "EventCode": "0x47",
+ "EventName": "L1D_CACHE_WB_CLEAN",
+ "BriefDescription": "L1D cache Write-Back, cleaning and coherency"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache invalidate",
+ "EventCode": "0x48",
+ "EventName": "L1D_CACHE_INVAL",
+ "BriefDescription": "L1D cache invalidate"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data TLB refill, read",
+ "EventCode": "0x4C",
+ "EventName": "L1D_TLB_REFILL_RD",
+ "BriefDescription": "L1D tlb refill, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data TLB refill, write",
+ "EventCode": "0x4D",
+ "EventName": "L1D_TLB_REFILL_WR",
+ "BriefDescription": "L1D tlb refill, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data or unified TLB access, read",
+ "EventCode": "0x4E",
+ "EventName": "L1D_TLB_RD",
+ "BriefDescription": "L1D tlb access, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data or unified TLB access, write",
+ "EventCode": "0x4F",
+ "EventName": "L1D_TLB_WR",
+ "BriefDescription": "L1D tlb access, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data cache access, read",
+ "EventCode": "0x50",
+ "EventName": "L2D_CACHE_RD",
+ "BriefDescription": "L2D cache access, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data cache access, write",
+ "EventCode": "0x51",
+ "EventName": "L2D_CACHE_WR",
+ "BriefDescription": "L2D cache access, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data cache refill, read",
+ "EventCode": "0x52",
+ "EventName": "L2D_CACHE_REFILL_RD",
+ "BriefDescription": "L2D cache refill, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data cache refill, write",
+ "EventCode": "0x53",
+ "EventName": "L2D_CACHE_REFILL_WR",
+ "BriefDescription": "L2D cache refill, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data cache Write-Back, victim",
+ "EventCode": "0x56",
+ "EventName": "L2D_CACHE_WB_VICTIM",
+ "BriefDescription": "L2D cache Write-Back, victim"
+ },
+ {
+ "PublicDescription": "Level 2 data cache Write-Back, cleaning and coherency",
+ "EventCode": "0x57",
+ "EventName": "L2D_CACHE_WB_CLEAN",
+ "BriefDescription": "L2D cache Write-Back, cleaning and coherency"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data cache invalidate",
+ "EventCode": "0x58",
+ "EventName": "L2D_CACHE_INVAL",
+ "BriefDescription": "L2D cache invalidate"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data or unified TLB refill, read",
+ "EventCode": "0x5c",
+ "EventName": "L2D_TLB_REFILL_RD",
+ "BriefDescription": "L2D cache refill, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data or unified TLB refill, write",
+ "EventCode": "0x5d",
+ "EventName": "L2D_TLB_REFILL_WR",
+ "BriefDescription": "L2D cache refill, write"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data or unified TLB access, read",
+ "EventCode": "0x5e",
+ "EventName": "L2D_TLB_RD",
+ "BriefDescription": "L2D cache access, read"
+ },
+ {
+ "PublicDescription": "Attributable Level 2 data or unified TLB access, write",
+ "EventCode": "0x5f",
+ "EventName": "L2D_TLB_WR",
+ "BriefDescription": "L2D cache access, write"
+ },
+ {
+ "PublicDescription": "Bus access read",
+ "EventCode": "0x60",
+ "EventName": "BUS_ACCESS_RD",
+ "BriefDescription": "Bus access read"
+ },
+ {
+ "PublicDescription": "Bus access write",
+ "EventCode": "0x61",
+ "EventName": "BUS_ACCESS_WR",
+ "BriefDescription": "Bus access write"
+ }
+ {
+ "PublicDescription": "Bus access, Normal, Cacheable, Shareable",
+ "EventCode": "0x62",
+ "EventName": "BUS_ACCESS_SHARED",
+ "BriefDescription": "Bus access, Normal, Cacheable, Shareable"
+ }
+ {
+ "PublicDescription": "Bus access, not Normal, Cacheable, Shareable",
+ "EventCode": "0x63",
+ "EventName": "BUS_ACCESS_NOT_SHARED",
+ "BriefDescription": "Bus access, not Normal, Cacheable, Shareable"
+ }
+ {
+ "PublicDescription": "Bus access, Normal",
+ "EventCode": "0x64",
+ "EventName": "BUS_ACCESS_NORMAL",
+ "BriefDescription": "Bus access, Normal"
+ }
+ {
+ "PublicDescription": "Bus access, peripheral",
+ "EventCode": "0x65",
+ "EventName": "BUS_ACCESS_PERIPH",
+ "BriefDescription": "Bus access, peripheral"
+ }
+ {
+ "PublicDescription": "Data memory access, read",
+ "EventCode": "0x66",
+ "EventName": "MEM_ACCESS_RD",
+ "BriefDescription": "Data memory access, read"
+ }
+ {
+ "PublicDescription": "Data memory access, write",
+ "EventCode": "0x67",
+ "EventName": "MEM_ACCESS_WR",
+ "BriefDescription": "Data memory access, write"
+ }
+ {
+ "PublicDescription": "Unaligned access, read",
+ "EventCode": "0x68",
+ "EventName": "UNALIGNED_LD_SPEC",
+ "BriefDescription": "Unaligned access, read"
+ }
+ {
+ "PublicDescription": "Unaligned access, write",
+ "EventCode": "0x69",
+ "EventName": "UNALIGNED_ST_SPEC",
+ "BriefDescription": "Unaligned access, write"
+ }
+ {
+ "PublicDescription": "Unaligned access",
+ "EventCode": "0x6a",
+ "EventName": "UNALIGNED_LDST_SPEC",
+ "BriefDescription": "Unaligned access"
+ }
+ {
+ "PublicDescription": "Exclusive operation speculatively executed, LDREX or LDX",
+ "EventCode": "0x6c",
+ "EventName": "LDREX_SPEC",
+ "BriefDescription": "Exclusive operation speculatively executed, LDREX or LDX"
+ }
+ {
+ "PublicDescription": "Exclusive operation speculatively executed, STREX or STX pass",
+ "EventCode": "0x6d",
+ "EventName": "STREX_PASS_SPEC",
+ "BriefDescription": "Exclusive operation speculatively executed, STREX or STX pass"
+ }
+ {
+ "PublicDescription": "Exclusive operation speculatively executed, STREX or STX fail",
+ "EventCode": "0x6e",
+ "EventName": "STREX_FAIL_SPEC",
+ "BriefDescription": "Exclusive operation speculatively executed, STREX or STX fail"
+ }
+ {
+ "PublicDescription": "Exclusive operation speculatively executed, STREX or STX",
+ "EventCode": "0x6f",
+ "EventName": "STREX_SPEC",
+ "BriefDescription": "Exclusive operation speculatively executed, STREX or STX"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, load",
+ "EventCode": "0x70",
+ "EventName": "LD_SPEC",
+ "BriefDescription": "Operation speculatively executed, load"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, store"
+ "EventCode": "0x71",
+ "EventName": "ST_SPEC",
+ "BriefDescription": "Operation speculatively executed, store"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, load or store",
+ "EventCode": "0x72",
+ "EventName": "LDST_SPEC",
+ "BriefDescription": "Operation speculatively executed, load or store"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, integer data processing",
+ "EventCode": "0x73",
+ "EventName": "DP_SPEC",
+ "BriefDescription": "Operation speculatively executed, integer data processing"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, Advanced SIMD instruction",
+ "EventCode": "0x74",
+ "EventName": "ASE_SPEC",
+ "BriefDescription": "Operation speculatively executed, Advanced SIMD instruction",
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, floating-point instruction",
+ "EventCode": "0x75",
+ "EventName": "VFP_SPEC",
+ "BriefDescription": "Operation speculatively executed, floating-point instruction"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, software change of the PC",
+ "EventCode": "0x76",
+ "EventName": "PC_WRITE_SPEC",
+ "BriefDescription": "Operation speculatively executed, software change of the PC"
+ }
+ {
+ "PublicDescription": "Operation speculatively executed, Cryptographic instruction",
+ "EventCode": "0x77",
+ "EventName": "CRYPTO_SPEC",
+ "BriefDescription": "Operation speculatively executed, Cryptographic instruction"
+ }
+ {
+ "PublicDescription": "Branch speculatively executed, immediate branch"
+ "EventCode": "0x78",
+ "EventName": "BR_IMMED_SPEC",
+ "BriefDescription": "Branch speculatively executed, immediate branch"
+ }
+ {
+ "PublicDescription": "Branch speculatively executed, procedure return"
+ "EventCode": "0x79",
+ "EventName": "BR_RETURN_SPEC",
+ "BriefDescription": "Branch speculatively executed, procedure return"
+ }
+ {
+ "PublicDescription": "Branch speculatively executed, indirect branch"
+ "EventCode": "0x7a",
+ "EventName": "BR_INDIRECT_SPEC",
+ "BriefDescription": "Branch speculatively executed, indirect branch"
+ }
+ {
+ "PublicDescription": "Barrier speculatively executed, ISB"
+ "EventCode": "0x7c",
+ "EventName": "ISB_SPEC",
+ "BriefDescription": "Barrier speculatively executed, ISB"
+ }
+ {
+ "PublicDescription": "Barrier speculatively executed, DSB"
+ "EventCode": "0x7d",
+ "EventName": "DSB_SPEC",
+ "BriefDescription": "Barrier speculatively executed, DSB"
+ }
+ {
+ "PublicDescription": "Barrier speculatively executed, DMB"
+ "EventCode": "0x7e",
+ "EventName": "DMB_SPEC",
+ "BriefDescription": "Barrier speculatively executed, DMB"
+ }
+ {
+ "PublicDescription": "Exception taken, Other synchronous"
+ "EventCode": "0x81",
+ "EventName": "EXC_UNDEF",
+ "BriefDescription": "Exception taken, Other synchronous"
+ }
+ {
+ "PublicDescription": "Exception taken, Supervisor Call"
+ "EventCode": "0x82",
+ "EventName": "EXC_SVC",
+ "BriefDescription": "Exception taken, Supervisor Call"
+ }
+ {
+ "PublicDescription": "Exception taken, Instruction Abort"
+ "EventCode": "0x83",
+ "EventName": "EXC_PABORT",
+ "BriefDescription": "Exception taken, Instruction Abort"
+ }
+ {
+ "PublicDescription": "Exception taken, Data Abort and SError"
+ "EventCode": "0x84",
+ "EventName": "EXC_DABORT",
+ "BriefDescription": "Exception taken, Data Abort and SError"
+ }
+ {
+ "PublicDescription": "Exception taken, IRQ"
+ "EventCode": "0x86",
+ "EventName": "EXC_IRQ",
+ "BriefDescription": "Exception taken, IRQ"
+ }
+ {
+ "PublicDescription": "Exception taken, FIQ"
+ "EventCode": "0x87",
+ "EventName": "EXC_FIQ",
+ "BriefDescription": "Exception taken, FIQ"
+ }
+ {
+ "PublicDescription": "Exception taken, Secure Monitor Call"
+ "EventCode": "0x88",
+ "EventName": "EXC_SMC",
+ "BriefDescription": "Exception taken, Secure Monitor Call"
+ }
+ {
+ "PublicDescription": "Exception taken, Hypervisor Call"
+ "EventCode": "0x8a",
+ "EventName": "EXC_HVC",
+ "BriefDescription": "Exception taken, Hypervisor Call"
+ }
+ {
+ "PublicDescription": "Exception taken, Instruction Abort not taken locally"
+ "EventCode": "0x8b",
+ "EventName": "EXC_TRAP_PABORT",
+ "BriefDescription": "Exception taken, Instruction Abort not taken locally"
+ }
+ {
+ "PublicDescription": "Exception taken, Data Abort or SError not taken locally"
+ "EventCode": "0x8c",
+ "EventName": "EXC_TRAP_DABORT",
+ "BriefDescription": "Exception taken, Data Abort or SError not taken locally"
+ }
+ {
+ "PublicDescription": "Exception taken, Other traps not taken locally"
+ "EventCode": "0x8d",
+ "EventName": "EXC_TRAP_OTHER",
+ "BriefDescription": "Exception taken, Other traps not taken locally"
+ }
+ {
+ "PublicDescription": "Exception taken, IRQ not taken locally"
+ "EventCode": "0x8e",
+ "EventName": "EXC_TRAP_IRQ",
+ "BriefDescription": "Exception taken, IRQ not taken locally"
+ }
+ {
+ "PublicDescription": "Exception taken, FIQ not taken locally"
+ "EventCode": "0x8f",
+ "EventName": "EXC_TRAP_FIQ",
+ "BriefDescription": "Exception taken, FIQ not taken locally"
+ }
+ {
+ "PublicDescription": "Release consistency operation speculatively executed, Load-Acquire"
+ "EventCode": "0x90",
+ "EventName": "RC_LD_SPEC",
+ "BriefDescription": "Release consistency operation speculatively executed, Load-Acquire"
+ }
+ {
+ "PublicDescription": "Release consistency operation speculatively executed, Store-Release"
+ "EventCode": "0x91",
+ "EventName": "RC_ST_SPEC",
+ "BriefDescription": "Release consistency operation speculatively executed, Store-Release"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache access, read"
+ "EventCode": "0xa0",
+ "EventName": "L3D_CACHE_RD",
+ "BriefDescription": "Attributable Level 3 data or unified cache access, read"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache access, write"
+ "EventCode": "0xa1",
+ "EventName": "L3D_CACHE_WR",
+ "BriefDescription": "Attributable Level 3 data or unified cache access, write"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache refill, read"
+ "EventCode": "0xa2",
+ "EventName": "L3D_CACHE_REFILL_RD",
+ "BriefDescription": "Attributable Level 3 data or unified cache refill, read"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache refill, write"
+ "EventCode": "0xa3",
+ "EventName": "L3D_CACHE_REFILL_WR",
+ "BriefDescription": "Attributable Level 3 data or unified cache refill, write"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache Write-Back, victim"
+ "EventCode": "0xa6",
+ "EventName": "L3D_CACHE_WB_VICTIM",
+ "BriefDescription": "Attributable Level 3 data or unified cache Write-Back, victim"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache Write-Back, cache clean"
+ "EventCode": "0xa7",
+ "EventName": "L3D_CACHE_WB_CLEAN",
+ "BriefDescription": "Attributable Level 3 data or unified cache Write-Back, cache clean"
+ }
+ {
+ "PublicDescription": "Attributable Level 3 data or unified cache access, invalidate"
+ "EventCode": "0xa8",
+ "EventName": "L3D_CACHE_INVAL",
+ "BriefDescription": "Attributable Level 3 data or unified cache access, invalidate"
+ }
+]
--
1.9.1
This patch fixes the ARM Cortex-A53 json to use event definitions
from the ARMv8 recommended events.
The brief description is kept for readability for arch standard events,
but is not strictly required.
In addition to this change, other changes were made:
- remove stray ','
- remove mirrored events in memory.json and bus.json
- fixed indentation to be consistent with other ARM
JSONs
Signed-off-by: John Garry <[email protected]>
---
.../arch/arm64/arm/cortex-a53/branch.json | 15 ++++---
.../pmu-events/arch/arm64/arm/cortex-a53/bus.json | 24 +++--------
.../arch/arm64/arm/cortex-a53/cache.json | 40 +++++++++----------
.../arch/arm64/arm/cortex-a53/memory.json | 14 +------
.../arch/arm64/arm/cortex-a53/other.json | 46 +++++++++++-----------
.../arch/arm64/arm/cortex-a53/pipeline.json | 20 +++++-----
6 files changed, 67 insertions(+), 92 deletions(-)
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
index 3b62087..efcebaa 100644
--- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
@@ -1,25 +1,24 @@
[
- {,
- "EventCode": "0x7A",
- "EventName": "BR_INDIRECT_SPEC",
- "BriefDescription": "Branch speculatively executed - Indirect branch"
+ {
+ "ArchStdEvent": "0x7A",
+ "BriefDescription": "Branch speculatively executed, indirect branch"
},
- {,
+ {
"EventCode": "0xC9",
"EventName": "BR_COND",
"BriefDescription": "Conditional branch executed"
},
- {,
+ {
"EventCode": "0xCA",
"EventName": "BR_INDIRECT_MISPRED",
"BriefDescription": "Indirect branch mispredicted"
},
- {,
+ {
"EventCode": "0xCB",
"EventName": "BR_INDIRECT_MISPRED_ADDR",
"BriefDescription": "Indirect branch mispredicted because of address miscompare"
},
- {,
+ {
"EventCode": "0xCC",
"EventName": "BR_COND_MISPRED",
"BriefDescription": "Conditional branch mispredicted"
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
index 480d9f7..bbbc930 100644
--- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
@@ -1,22 +1,10 @@
[
- {,
- "EventCode": "0x60",
- "EventName": "BUS_ACCESS_LD",
- "BriefDescription": "Bus access - Read"
+ {
+ "ArchStdEvent": "0x60",
+ "BriefDescription": "Bus access read"
},
- {,
- "EventCode": "0x61",
- "EventName": "BUS_ACCESS_ST",
- "BriefDescription": "Bus access - Write"
- },
- {,
- "EventCode": "0xC0",
- "EventName": "EXT_MEM_REQ",
- "BriefDescription": "External memory request"
- },
- {,
- "EventCode": "0xC1",
- "EventName": "EXT_MEM_REQ_NC",
- "BriefDescription": "Non-cacheable external memory request"
+ {
+ "ArchStdEvent": "0x61",
+ "BriefDescription": "Bus access write"
}
]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
index 11baad6..5dfbec4 100644
--- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
@@ -1,27 +1,27 @@
[
- {,
- "EventCode": "0xC2",
- "EventName": "PREFETCH_LINEFILL",
- "BriefDescription": "Linefill because of prefetch"
+ {
+ "EventCode": "0xC2",
+ "EventName": "PREFETCH_LINEFILL",
+ "BriefDescription": "Linefill because of prefetch"
},
- {,
- "EventCode": "0xC3",
- "EventName": "PREFETCH_LINEFILL_DROP",
- "BriefDescription": "Instruction Cache Throttle occurred"
+ {
+ "EventCode": "0xC3",
+ "EventName": "PREFETCH_LINEFILL_DROP",
+ "BriefDescription": "Instruction Cache Throttle occurred"
},
- {,
- "EventCode": "0xC4",
- "EventName": "READ_ALLOC_ENTER",
- "BriefDescription": "Entering read allocate mode"
+ {
+ "EventCode": "0xC4",
+ "EventName": "READ_ALLOC_ENTER",
+ "BriefDescription": "Entering read allocate mode"
},
- {,
- "EventCode": "0xC5",
- "EventName": "READ_ALLOC",
- "BriefDescription": "Read allocate mode"
+ {
+ "EventCode": "0xC5",
+ "EventName": "READ_ALLOC",
+ "BriefDescription": "Read allocate mode"
},
- {,
- "EventCode": "0xC8",
- "EventName": "EXT_SNOOP",
- "BriefDescription": "SCU Snooped data from another CPU for this CPU"
+ {
+ "EventCode": "0xC8",
+ "EventName": "EXT_SNOOP",
+ "BriefDescription": "SCU Snooped data from another CPU for this CPU"
}
]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
index 480d9f7..25ae642 100644
--- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
@@ -1,20 +1,10 @@
[
- {,
- "EventCode": "0x60",
- "EventName": "BUS_ACCESS_LD",
- "BriefDescription": "Bus access - Read"
- },
- {,
- "EventCode": "0x61",
- "EventName": "BUS_ACCESS_ST",
- "BriefDescription": "Bus access - Write"
- },
- {,
+ {
"EventCode": "0xC0",
"EventName": "EXT_MEM_REQ",
"BriefDescription": "External memory request"
},
- {,
+ {
"EventCode": "0xC1",
"EventName": "EXT_MEM_REQ_NC",
"BriefDescription": "Non-cacheable external memory request"
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
index 73a2240..4eb17a8 100644
--- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
@@ -1,32 +1,30 @@
[
- {,
- "EventCode": "0x86",
- "EventName": "EXC_IRQ",
- "BriefDescription": "Exception taken, IRQ"
+ {
+ "ArchStdEvent": "0x86",
+ "BriefDescription": "Exception taken, IRQ"
},
- {,
- "EventCode": "0x87",
- "EventName": "EXC_FIQ",
- "BriefDescription": "Exception taken, FIQ"
+ {
+ "ArchStdEvent": "0x87",
+ "BriefDescription": "Exception taken, FIQ"
},
- {,
- "EventCode": "0xC6",
- "EventName": "PRE_DECODE_ERR",
- "BriefDescription": "Pre-decode error"
+ {
+ "EventCode": "0xC6",
+ "EventName": "PRE_DECODE_ERR",
+ "BriefDescription": "Pre-decode error"
},
- {,
- "EventCode": "0xD0",
- "EventName": "L1I_CACHE_ERR",
- "BriefDescription": "L1 Instruction Cache (data or tag) memory error"
+ {
+ "EventCode": "0xD0",
+ "EventName": "L1I_CACHE_ERR",
+ "BriefDescription": "L1 Instruction Cache (data or tag) memory error"
},
- {,
- "EventCode": "0xD1",
- "EventName": "L1D_CACHE_ERR",
- "BriefDescription": "L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable"
+ {
+ "EventCode": "0xD1",
+ "EventName": "L1D_CACHE_ERR",
+ "BriefDescription": "L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable"
},
- {,
- "EventCode": "0xD2",
- "EventName": "TLB_ERR",
- "BriefDescription": "TLB memory error"
+ {
+ "EventCode": "0xD2",
+ "EventName": "TLB_ERR",
+ "BriefDescription": "TLB memory error"
}
]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
index 3149fb9..f45a6b5 100644
--- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
@@ -1,50 +1,50 @@
[
- {,
+ {
"EventCode": "0xC7",
"EventName": "STALL_SB_FULL",
"BriefDescription": "Data Write operation that stalls the pipeline because the store buffer is full"
},
- {,
+ {
"EventCode": "0xE0",
"EventName": "OTHER_IQ_DEP_STALL",
"BriefDescription": "Cycles that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error"
},
- {,
+ {
"EventCode": "0xE1",
"EventName": "IC_DEP_STALL",
"BriefDescription": "Cycles the DPU IQ is empty and there is an instruction cache miss being processed"
},
- {,
+ {
"EventCode": "0xE2",
"EventName": "IUTLB_DEP_STALL",
"BriefDescription": "Cycles the DPU IQ is empty and there is an instruction micro-TLB miss being processed"
},
- {,
+ {
"EventCode": "0xE3",
"EventName": "DECODE_DEP_STALL",
"BriefDescription": "Cycles the DPU IQ is empty and there is a pre-decode error being processed"
},
- {,
+ {
"EventCode": "0xE4",
"EventName": "OTHER_INTERLOCK_STALL",
"BriefDescription": "Cycles there is an interlock other than Advanced SIMD/Floating-point instructions or load/store instruction"
},
- {,
+ {
"EventCode": "0xE5",
"EventName": "AGU_DEP_STALL",
"BriefDescription": "Cycles there is an interlock for a load/store instruction waiting for data to calculate the address in the AGU"
},
- {,
+ {
"EventCode": "0xE6",
"EventName": "SIMD_DEP_STALL",
"BriefDescription": "Cycles there is an interlock for an Advanced SIMD/Floating-point operation."
},
- {,
+ {
"EventCode": "0xE7",
"EventName": "LD_DEP_STALL",
"BriefDescription": "Cycles there is a stall in the Wr stage because of a load miss"
},
- {,
+ {
"EventCode": "0xE8",
"EventName": "ST_DEP_STALL",
"BriefDescription": "Cycles there is a stall in the Wr stage because of a store"
--
1.9.1
For some architectures (like arm), it is required to support
a vendor sub-directory and not locate all the JSONs for a
specific vendor in the same folder.
This is because all the events for the same vendor will be
placed in the same pmu events table, which may cause conflict.
This conflict would be in the instance that a vendor's custom
implemented events do have the same meaning on different platforms,
so events in the pmu table would conflict. In addition, per list
command may show events which are not even supported for a given
platform.
This patch adds support for a arch/vendor/platform directory
hierarchy, while maintaining backwards-compatibility for existing
arch/platform structure. In this, each platform would always have
its own pmu events table.
In generated file pmu_events.c, each platform table name is in
the format pme{_vendor}_platform, like this:
struct pmu_events_map pmu_events_map[] = {
{
.cpuid = "0x00000000420f5160",
.version = "v1",
.type = "core",
.table = pme_cavium_thunderx2
},
{
.cpuid = 0,
.version = 0,
.type = 0,
.table = 0,
},
};
Signed-off-by: John Garry <[email protected]>
---
tools/perf/pmu-events/README | 4 +++
tools/perf/pmu-events/jevents.c | 70 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
index 2407abc..655286f 100644
--- a/tools/perf/pmu-events/README
+++ b/tools/perf/pmu-events/README
@@ -28,6 +28,10 @@ sub directory. Thus for the Silvermont X86 CPU:
Cache.json Memory.json Virtual-Memory.json
Frontend.json Pipeline.json
+The JSONs folder for a CPU model/family may be placed in the root arch
+folder, or may be placed in a vendor sub-folder under the arch folder
+for instances where the arch and vendor are not the same.
+
Using the JSON files and the mapfile, 'jevents' generates the C source file,
'pmu-events.c', which encodes the two sets of tables:
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 9e0a21e..eb183b1 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -588,7 +588,7 @@ static char *file_name_to_table_name(char *fname)
* Derive rest of table name from basename of the JSON file,
* replacing hyphens and stripping out .json suffix.
*/
- n = asprintf(&tblname, "pme_%s", basename(fname));
+ n = asprintf(&tblname, "pme_%s", fname);
if (n < 0) {
pr_info("%s: asprintf() error %s for file %s\n", prog,
strerror(errno), fname);
@@ -598,7 +598,7 @@ static char *file_name_to_table_name(char *fname)
for (i = 0; i < strlen(tblname); i++) {
c = tblname[i];
- if (c == '-')
+ if (c == '-' || c == '/')
tblname[i] = '_';
else if (c == '.') {
tblname[i] = '\0';
@@ -755,15 +755,65 @@ static int get_maxfds(void)
static FILE *eventsfp;
static char *mapfile;
+static int is_leaf_dir(const char *fpath)
+{
+ DIR *d;
+ struct dirent *dir;
+ int res = 1;
+
+ d = opendir(fpath);
+ if (!d)
+ return 0;
+
+ while ((dir = readdir(d)) != NULL) {
+ if (dir->d_type == DT_DIR && dir->d_name[0] != '.') {
+ res = 0;
+ break;
+ } else if (dir->d_type == DT_UNKNOWN) {
+ char path[PATH_MAX];
+ struct stat st;
+
+ sprintf(path, "%s/%s", fpath, dir->d_name);
+ if (stat(path, &st))
+ break;
+
+ if (S_ISDIR(st.st_mode)) {
+ res = 0;
+ break;
+ }
+ }
+ }
+
+ closedir(d);
+
+ return res;
+}
+
static int process_one_file(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
- char *tblname, *bname = (char *) fpath + ftwbuf->base;
+ char *tblname, *bname;
int is_dir = typeflag == FTW_D;
int is_file = typeflag == FTW_F;
int level = ftwbuf->level;
int err = 0;
+ if (level == 2 && is_dir) {
+ /*
+ * For level 2 directory, bname will include parent name,
+ * like vendor/platform. So search back from platform dir
+ * to find this.
+ */
+ bname = (char *) fpath + ftwbuf->base - 2;
+ for (;;) {
+ if (*bname == '/')
+ break;
+ bname--;
+ }
+ bname++;
+ } else
+ bname = (char *) fpath + ftwbuf->base;
+
pr_debug("%s %d %7jd %-20s %s\n",
is_file ? "f" : is_dir ? "d" : "x",
level, sb->st_size, bname, fpath);
@@ -773,7 +823,7 @@ static int process_one_file(const char *fpath, const struct stat *sb,
return 0;
/* model directory, reset topic */
- if (level == 1 && is_dir) {
+ if (level == 1 && is_dir && is_leaf_dir(fpath)) {
if (close_table)
print_events_table_suffix(eventsfp);
@@ -791,6 +841,18 @@ static int process_one_file(const char *fpath, const struct stat *sb,
print_events_table_prefix(eventsfp, tblname);
return 0;
+ } else if (level == 2 && is_dir) {
+ if (close_table)
+ print_events_table_suffix(eventsfp);
+
+ tblname = file_name_to_table_name(bname);
+ if (!tblname) {
+ pr_info("%s: Error determining table name for %s, exiting\n",
+ prog, bname);
+ return -1;
+ }
+
+ print_events_table_prefix(eventsfp, tblname);
}
/*
--
1.9.1
Currently jevents supports multiple mapfiles, but this
is only in the form where mapfile basename starts with
'mapfile.csv'
At the moment, no architectures actually use multiple mapfiles,
so drop the support for now.
This patch also solves a nuisance where, when the mapfile is
edited and the text editor may create a backup, jevents may
use the backup, as shown:
jevents: Many mapfiles? Using pmu-events/arch/arm64/mapfile.csv~, ignoring pmu-events/arch/arm64/mapfile.csv
Signed-off-by: John Garry <[email protected]>
---
tools/perf/pmu-events/README | 5 ++---
tools/perf/pmu-events/jevents.c | 10 ++--------
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
index c2ee3e4..2407abc 100644
--- a/tools/perf/pmu-events/README
+++ b/tools/perf/pmu-events/README
@@ -11,9 +11,8 @@ tree tools/perf/pmu-events/arch/foo.
- Regular files with '.json' extension in the name are assumed to be
JSON files, each of which describes a set of PMU events.
- - Regular files with basename starting with 'mapfile.csv' are assumed
- to be a CSV file that maps a specific CPU to its set of PMU events.
- (see below for mapfile format)
+ - The CSV file that maps a specific CPU to its set of PMU events is to
+ be named 'mapfile.csv' (see below for mapfile format).
- Directories are traversed, but all other files are ignored.
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index b578aa2..9e0a21e 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -798,16 +798,10 @@ static int process_one_file(const char *fpath, const struct stat *sb,
* after processing all JSON files (so we can write out the
* mapping table after all PMU events tables).
*
- * TODO: Allow for multiple mapfiles? Punt for now.
*/
if (level == 1 && is_file) {
- if (!strncmp(bname, "mapfile.csv", 11)) {
- if (mapfile) {
- pr_info("%s: Many mapfiles? Using %s, ignoring %s\n",
- prog, mapfile, fpath);
- } else {
- mapfile = strdup(fpath);
- }
+ if (!strcmp(bname, "mapfile.csv")) {
+ mapfile = strdup(fpath);
return 0;
}
--
1.9.1
Since jevents now supports vendor subdirectory, relocate
the ThunderX2 JSON to Cavium subdirectory.
Signed-off-by: John Garry <[email protected]>
---
.../arch/arm64/cavium/thunderx2-imp-def.json | 62 ----------------------
.../arch/arm64/cavium/thunderx2/core-imp-def.json | 62 ++++++++++++++++++++++
tools/perf/pmu-events/arch/arm64/mapfile.csv | 2 +-
3 files changed, 63 insertions(+), 63 deletions(-)
delete mode 100644 tools/perf/pmu-events/arch/arm64/cavium/thunderx2-imp-def.json
create mode 100644 tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
diff --git a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2-imp-def.json b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2-imp-def.json
deleted file mode 100644
index 2db45c4..0000000
--- a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2-imp-def.json
+++ /dev/null
@@ -1,62 +0,0 @@
-[
- {
- "PublicDescription": "Attributable Level 1 data cache access, read",
- "EventCode": "0x40",
- "EventName": "l1d_cache_rd",
- "BriefDescription": "L1D cache read",
- },
- {
- "PublicDescription": "Attributable Level 1 data cache access, write ",
- "EventCode": "0x41",
- "EventName": "l1d_cache_wr",
- "BriefDescription": "L1D cache write",
- },
- {
- "PublicDescription": "Attributable Level 1 data cache refill, read",
- "EventCode": "0x42",
- "EventName": "l1d_cache_refill_rd",
- "BriefDescription": "L1D cache refill read",
- },
- {
- "PublicDescription": "Attributable Level 1 data cache refill, write",
- "EventCode": "0x43",
- "EventName": "l1d_cache_refill_wr",
- "BriefDescription": "L1D refill write",
- },
- {
- "PublicDescription": "Attributable Level 1 data TLB refill, read",
- "EventCode": "0x4C",
- "EventName": "l1d_tlb_refill_rd",
- "BriefDescription": "L1D tlb refill read",
- },
- {
- "PublicDescription": "Attributable Level 1 data TLB refill, write",
- "EventCode": "0x4D",
- "EventName": "l1d_tlb_refill_wr",
- "BriefDescription": "L1D tlb refill write",
- },
- {
- "PublicDescription": "Attributable Level 1 data or unified TLB access, read",
- "EventCode": "0x4E",
- "EventName": "l1d_tlb_rd",
- "BriefDescription": "L1D tlb read",
- },
- {
- "PublicDescription": "Attributable Level 1 data or unified TLB access, write",
- "EventCode": "0x4F",
- "EventName": "l1d_tlb_wr",
- "BriefDescription": "L1D tlb write",
- },
- {
- "PublicDescription": "Bus access read",
- "EventCode": "0x60",
- "EventName": "bus_access_rd",
- "BriefDescription": "Bus access read",
- },
- {
- "PublicDescription": "Bus access write",
- "EventCode": "0x61",
- "EventName": "bus_access_wr",
- "BriefDescription": "Bus access write",
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
new file mode 100644
index 0000000..2db45c4
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
@@ -0,0 +1,62 @@
+[
+ {
+ "PublicDescription": "Attributable Level 1 data cache access, read",
+ "EventCode": "0x40",
+ "EventName": "l1d_cache_rd",
+ "BriefDescription": "L1D cache read",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache access, write ",
+ "EventCode": "0x41",
+ "EventName": "l1d_cache_wr",
+ "BriefDescription": "L1D cache write",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache refill, read",
+ "EventCode": "0x42",
+ "EventName": "l1d_cache_refill_rd",
+ "BriefDescription": "L1D cache refill read",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data cache refill, write",
+ "EventCode": "0x43",
+ "EventName": "l1d_cache_refill_wr",
+ "BriefDescription": "L1D refill write",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data TLB refill, read",
+ "EventCode": "0x4C",
+ "EventName": "l1d_tlb_refill_rd",
+ "BriefDescription": "L1D tlb refill read",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data TLB refill, write",
+ "EventCode": "0x4D",
+ "EventName": "l1d_tlb_refill_wr",
+ "BriefDescription": "L1D tlb refill write",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data or unified TLB access, read",
+ "EventCode": "0x4E",
+ "EventName": "l1d_tlb_rd",
+ "BriefDescription": "L1D tlb read",
+ },
+ {
+ "PublicDescription": "Attributable Level 1 data or unified TLB access, write",
+ "EventCode": "0x4F",
+ "EventName": "l1d_tlb_wr",
+ "BriefDescription": "L1D tlb write",
+ },
+ {
+ "PublicDescription": "Bus access read",
+ "EventCode": "0x60",
+ "EventName": "bus_access_rd",
+ "BriefDescription": "Bus access read",
+ },
+ {
+ "PublicDescription": "Bus access write",
+ "EventCode": "0x61",
+ "EventName": "bus_access_wr",
+ "BriefDescription": "Bus access write",
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv
index e61c9ca..952a05c 100644
--- a/tools/perf/pmu-events/arch/arm64/mapfile.csv
+++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv
@@ -12,5 +12,5 @@
#
#
#Family-model,Version,Filename,EventType
-0x00000000420f5160,v1,cavium,core
+0x00000000420f5160,v1,cavium/thunderx2,core
0x00000000410fd03[[:xdigit:]],v1,cortex-a53,core
--
1.9.1
The arm64 pmu-events folder structure has become
disorganised, since now we have core and also vendor
folders at the same level folder.
Since jevents now supports vendor subdirectory, relocate
the Cortex-A53 JSONs to arm vendor subdirectory.
Signed-off-by: John Garry <[email protected]>
---
.../arch/arm64/arm/cortex-a53/branch.json | 27 +++++++++++
.../pmu-events/arch/arm64/arm/cortex-a53/bus.json | 22 +++++++++
.../arch/arm64/arm/cortex-a53/cache.json | 27 +++++++++++
.../arch/arm64/arm/cortex-a53/memory.json | 22 +++++++++
.../arch/arm64/arm/cortex-a53/other.json | 32 +++++++++++++
.../arch/arm64/arm/cortex-a53/pipeline.json | 52 ++++++++++++++++++++++
.../pmu-events/arch/arm64/cortex-a53/branch.json | 27 -----------
.../perf/pmu-events/arch/arm64/cortex-a53/bus.json | 22 ---------
.../pmu-events/arch/arm64/cortex-a53/cache.json | 27 -----------
.../pmu-events/arch/arm64/cortex-a53/memory.json | 22 ---------
.../pmu-events/arch/arm64/cortex-a53/other.json | 32 -------------
.../pmu-events/arch/arm64/cortex-a53/pipeline.json | 52 ----------------------
tools/perf/pmu-events/arch/arm64/mapfile.csv | 2 +-
13 files changed, 183 insertions(+), 183 deletions(-)
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/other.json
delete mode 100644 tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
new file mode 100644
index 0000000..3b62087
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/branch.json
@@ -0,0 +1,27 @@
+[
+ {,
+ "EventCode": "0x7A",
+ "EventName": "BR_INDIRECT_SPEC",
+ "BriefDescription": "Branch speculatively executed - Indirect branch"
+ },
+ {,
+ "EventCode": "0xC9",
+ "EventName": "BR_COND",
+ "BriefDescription": "Conditional branch executed"
+ },
+ {,
+ "EventCode": "0xCA",
+ "EventName": "BR_INDIRECT_MISPRED",
+ "BriefDescription": "Indirect branch mispredicted"
+ },
+ {,
+ "EventCode": "0xCB",
+ "EventName": "BR_INDIRECT_MISPRED_ADDR",
+ "BriefDescription": "Indirect branch mispredicted because of address miscompare"
+ },
+ {,
+ "EventCode": "0xCC",
+ "EventName": "BR_COND_MISPRED",
+ "BriefDescription": "Conditional branch mispredicted"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
new file mode 100644
index 0000000..480d9f7
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/bus.json
@@ -0,0 +1,22 @@
+[
+ {,
+ "EventCode": "0x60",
+ "EventName": "BUS_ACCESS_LD",
+ "BriefDescription": "Bus access - Read"
+ },
+ {,
+ "EventCode": "0x61",
+ "EventName": "BUS_ACCESS_ST",
+ "BriefDescription": "Bus access - Write"
+ },
+ {,
+ "EventCode": "0xC0",
+ "EventName": "EXT_MEM_REQ",
+ "BriefDescription": "External memory request"
+ },
+ {,
+ "EventCode": "0xC1",
+ "EventName": "EXT_MEM_REQ_NC",
+ "BriefDescription": "Non-cacheable external memory request"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
new file mode 100644
index 0000000..11baad6
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/cache.json
@@ -0,0 +1,27 @@
+[
+ {,
+ "EventCode": "0xC2",
+ "EventName": "PREFETCH_LINEFILL",
+ "BriefDescription": "Linefill because of prefetch"
+ },
+ {,
+ "EventCode": "0xC3",
+ "EventName": "PREFETCH_LINEFILL_DROP",
+ "BriefDescription": "Instruction Cache Throttle occurred"
+ },
+ {,
+ "EventCode": "0xC4",
+ "EventName": "READ_ALLOC_ENTER",
+ "BriefDescription": "Entering read allocate mode"
+ },
+ {,
+ "EventCode": "0xC5",
+ "EventName": "READ_ALLOC",
+ "BriefDescription": "Read allocate mode"
+ },
+ {,
+ "EventCode": "0xC8",
+ "EventName": "EXT_SNOOP",
+ "BriefDescription": "SCU Snooped data from another CPU for this CPU"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
new file mode 100644
index 0000000..480d9f7
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/memory.json
@@ -0,0 +1,22 @@
+[
+ {,
+ "EventCode": "0x60",
+ "EventName": "BUS_ACCESS_LD",
+ "BriefDescription": "Bus access - Read"
+ },
+ {,
+ "EventCode": "0x61",
+ "EventName": "BUS_ACCESS_ST",
+ "BriefDescription": "Bus access - Write"
+ },
+ {,
+ "EventCode": "0xC0",
+ "EventName": "EXT_MEM_REQ",
+ "BriefDescription": "External memory request"
+ },
+ {,
+ "EventCode": "0xC1",
+ "EventName": "EXT_MEM_REQ_NC",
+ "BriefDescription": "Non-cacheable external memory request"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
new file mode 100644
index 0000000..73a2240
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/other.json
@@ -0,0 +1,32 @@
+[
+ {,
+ "EventCode": "0x86",
+ "EventName": "EXC_IRQ",
+ "BriefDescription": "Exception taken, IRQ"
+ },
+ {,
+ "EventCode": "0x87",
+ "EventName": "EXC_FIQ",
+ "BriefDescription": "Exception taken, FIQ"
+ },
+ {,
+ "EventCode": "0xC6",
+ "EventName": "PRE_DECODE_ERR",
+ "BriefDescription": "Pre-decode error"
+ },
+ {,
+ "EventCode": "0xD0",
+ "EventName": "L1I_CACHE_ERR",
+ "BriefDescription": "L1 Instruction Cache (data or tag) memory error"
+ },
+ {,
+ "EventCode": "0xD1",
+ "EventName": "L1D_CACHE_ERR",
+ "BriefDescription": "L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable"
+ },
+ {,
+ "EventCode": "0xD2",
+ "EventName": "TLB_ERR",
+ "BriefDescription": "TLB memory error"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
new file mode 100644
index 0000000..3149fb9
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a53/pipeline.json
@@ -0,0 +1,52 @@
+[
+ {,
+ "EventCode": "0xC7",
+ "EventName": "STALL_SB_FULL",
+ "BriefDescription": "Data Write operation that stalls the pipeline because the store buffer is full"
+ },
+ {,
+ "EventCode": "0xE0",
+ "EventName": "OTHER_IQ_DEP_STALL",
+ "BriefDescription": "Cycles that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error"
+ },
+ {,
+ "EventCode": "0xE1",
+ "EventName": "IC_DEP_STALL",
+ "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction cache miss being processed"
+ },
+ {,
+ "EventCode": "0xE2",
+ "EventName": "IUTLB_DEP_STALL",
+ "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction micro-TLB miss being processed"
+ },
+ {,
+ "EventCode": "0xE3",
+ "EventName": "DECODE_DEP_STALL",
+ "BriefDescription": "Cycles the DPU IQ is empty and there is a pre-decode error being processed"
+ },
+ {,
+ "EventCode": "0xE4",
+ "EventName": "OTHER_INTERLOCK_STALL",
+ "BriefDescription": "Cycles there is an interlock other than Advanced SIMD/Floating-point instructions or load/store instruction"
+ },
+ {,
+ "EventCode": "0xE5",
+ "EventName": "AGU_DEP_STALL",
+ "BriefDescription": "Cycles there is an interlock for a load/store instruction waiting for data to calculate the address in the AGU"
+ },
+ {,
+ "EventCode": "0xE6",
+ "EventName": "SIMD_DEP_STALL",
+ "BriefDescription": "Cycles there is an interlock for an Advanced SIMD/Floating-point operation."
+ },
+ {,
+ "EventCode": "0xE7",
+ "EventName": "LD_DEP_STALL",
+ "BriefDescription": "Cycles there is a stall in the Wr stage because of a load miss"
+ },
+ {,
+ "EventCode": "0xE8",
+ "EventName": "ST_DEP_STALL",
+ "BriefDescription": "Cycles there is a stall in the Wr stage because of a store"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json
deleted file mode 100644
index 3b62087..0000000
--- a/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json
+++ /dev/null
@@ -1,27 +0,0 @@
-[
- {,
- "EventCode": "0x7A",
- "EventName": "BR_INDIRECT_SPEC",
- "BriefDescription": "Branch speculatively executed - Indirect branch"
- },
- {,
- "EventCode": "0xC9",
- "EventName": "BR_COND",
- "BriefDescription": "Conditional branch executed"
- },
- {,
- "EventCode": "0xCA",
- "EventName": "BR_INDIRECT_MISPRED",
- "BriefDescription": "Indirect branch mispredicted"
- },
- {,
- "EventCode": "0xCB",
- "EventName": "BR_INDIRECT_MISPRED_ADDR",
- "BriefDescription": "Indirect branch mispredicted because of address miscompare"
- },
- {,
- "EventCode": "0xCC",
- "EventName": "BR_COND_MISPRED",
- "BriefDescription": "Conditional branch mispredicted"
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json
deleted file mode 100644
index 480d9f7..0000000
--- a/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
- {,
- "EventCode": "0x60",
- "EventName": "BUS_ACCESS_LD",
- "BriefDescription": "Bus access - Read"
- },
- {,
- "EventCode": "0x61",
- "EventName": "BUS_ACCESS_ST",
- "BriefDescription": "Bus access - Write"
- },
- {,
- "EventCode": "0xC0",
- "EventName": "EXT_MEM_REQ",
- "BriefDescription": "External memory request"
- },
- {,
- "EventCode": "0xC1",
- "EventName": "EXT_MEM_REQ_NC",
- "BriefDescription": "Non-cacheable external memory request"
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json
deleted file mode 100644
index 11baad6..0000000
--- a/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json
+++ /dev/null
@@ -1,27 +0,0 @@
-[
- {,
- "EventCode": "0xC2",
- "EventName": "PREFETCH_LINEFILL",
- "BriefDescription": "Linefill because of prefetch"
- },
- {,
- "EventCode": "0xC3",
- "EventName": "PREFETCH_LINEFILL_DROP",
- "BriefDescription": "Instruction Cache Throttle occurred"
- },
- {,
- "EventCode": "0xC4",
- "EventName": "READ_ALLOC_ENTER",
- "BriefDescription": "Entering read allocate mode"
- },
- {,
- "EventCode": "0xC5",
- "EventName": "READ_ALLOC",
- "BriefDescription": "Read allocate mode"
- },
- {,
- "EventCode": "0xC8",
- "EventName": "EXT_SNOOP",
- "BriefDescription": "SCU Snooped data from another CPU for this CPU"
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json
deleted file mode 100644
index 480d9f7..0000000
--- a/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
- {,
- "EventCode": "0x60",
- "EventName": "BUS_ACCESS_LD",
- "BriefDescription": "Bus access - Read"
- },
- {,
- "EventCode": "0x61",
- "EventName": "BUS_ACCESS_ST",
- "BriefDescription": "Bus access - Write"
- },
- {,
- "EventCode": "0xC0",
- "EventName": "EXT_MEM_REQ",
- "BriefDescription": "External memory request"
- },
- {,
- "EventCode": "0xC1",
- "EventName": "EXT_MEM_REQ_NC",
- "BriefDescription": "Non-cacheable external memory request"
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json
deleted file mode 100644
index 73a2240..0000000
--- a/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json
+++ /dev/null
@@ -1,32 +0,0 @@
-[
- {,
- "EventCode": "0x86",
- "EventName": "EXC_IRQ",
- "BriefDescription": "Exception taken, IRQ"
- },
- {,
- "EventCode": "0x87",
- "EventName": "EXC_FIQ",
- "BriefDescription": "Exception taken, FIQ"
- },
- {,
- "EventCode": "0xC6",
- "EventName": "PRE_DECODE_ERR",
- "BriefDescription": "Pre-decode error"
- },
- {,
- "EventCode": "0xD0",
- "EventName": "L1I_CACHE_ERR",
- "BriefDescription": "L1 Instruction Cache (data or tag) memory error"
- },
- {,
- "EventCode": "0xD1",
- "EventName": "L1D_CACHE_ERR",
- "BriefDescription": "L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable"
- },
- {,
- "EventCode": "0xD2",
- "EventName": "TLB_ERR",
- "BriefDescription": "TLB memory error"
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json
deleted file mode 100644
index 3149fb9..0000000
--- a/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json
+++ /dev/null
@@ -1,52 +0,0 @@
-[
- {,
- "EventCode": "0xC7",
- "EventName": "STALL_SB_FULL",
- "BriefDescription": "Data Write operation that stalls the pipeline because the store buffer is full"
- },
- {,
- "EventCode": "0xE0",
- "EventName": "OTHER_IQ_DEP_STALL",
- "BriefDescription": "Cycles that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error"
- },
- {,
- "EventCode": "0xE1",
- "EventName": "IC_DEP_STALL",
- "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction cache miss being processed"
- },
- {,
- "EventCode": "0xE2",
- "EventName": "IUTLB_DEP_STALL",
- "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction micro-TLB miss being processed"
- },
- {,
- "EventCode": "0xE3",
- "EventName": "DECODE_DEP_STALL",
- "BriefDescription": "Cycles the DPU IQ is empty and there is a pre-decode error being processed"
- },
- {,
- "EventCode": "0xE4",
- "EventName": "OTHER_INTERLOCK_STALL",
- "BriefDescription": "Cycles there is an interlock other than Advanced SIMD/Floating-point instructions or load/store instruction"
- },
- {,
- "EventCode": "0xE5",
- "EventName": "AGU_DEP_STALL",
- "BriefDescription": "Cycles there is an interlock for a load/store instruction waiting for data to calculate the address in the AGU"
- },
- {,
- "EventCode": "0xE6",
- "EventName": "SIMD_DEP_STALL",
- "BriefDescription": "Cycles there is an interlock for an Advanced SIMD/Floating-point operation."
- },
- {,
- "EventCode": "0xE7",
- "EventName": "LD_DEP_STALL",
- "BriefDescription": "Cycles there is a stall in the Wr stage because of a load miss"
- },
- {,
- "EventCode": "0xE8",
- "EventName": "ST_DEP_STALL",
- "BriefDescription": "Cycles there is a stall in the Wr stage because of a store"
- }
-]
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv
index 952a05c..cf14e23 100644
--- a/tools/perf/pmu-events/arch/arm64/mapfile.csv
+++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv
@@ -12,5 +12,5 @@
#
#
#Family-model,Version,Filename,EventType
+0x00000000410fd03[[:xdigit:]],v1,arm/cortex-a53,core
0x00000000420f5160,v1,cavium/thunderx2,core
-0x00000000410fd03[[:xdigit:]],v1,cortex-a53,core
--
1.9.1
For some architectures (like arm), there are architecture-
defined events. Sometimes these events may be "recommended"
according to the architecture standard, in that the
implementer is free ignore the "recommendation" and create
its custom event.
This patch adds support for parsing standard events from
arch-defined JSONs, and fixing up vendor events when they
have implemented these events as standard.
Support is also ensured that the vendor may implement their
own custom events.
A new step is added to the pmu events parsing to fix up the
vendor events with the arch-standard events.
The arch-defined JSONs must be placed in the arch root
folder for preprocessing prior to tree JSON processing.
In the vendor JSON, to specify that the arch event is
supported, the keyword "ArchStdEvent" should be used,
like this:
[
{
"ArchStdEvent": "0x41",
"BriefDescription": "L1D cache access, write"
},
]
No other JSON objects are strictly required. However,
for other objects added, these take precedence over
architecture defined standard events, thus supporting
separate events which have the same event code.
Signed-off-by: John Garry <[email protected]>
---
tools/perf/pmu-events/Build | 1 +
tools/perf/pmu-events/README | 6 ++
tools/perf/pmu-events/jevents.c | 185 +++++++++++++++++++++++++++++++++++++---
3 files changed, 182 insertions(+), 10 deletions(-)
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index 999a4e8..f9e8466 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -1,5 +1,6 @@
hostprogs := jevents
+CHOSTFLAGS = -I$(srctree)/tools/include
jevents-y += json.o jsmn.o jevents.o
pmu-events-y += pmu-events.o
JDIR = pmu-events/arch/$(SRCARCH)
diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
index 655286f..cff4c91 100644
--- a/tools/perf/pmu-events/README
+++ b/tools/perf/pmu-events/README
@@ -16,6 +16,12 @@ tree tools/perf/pmu-events/arch/foo.
- Directories are traversed, but all other files are ignored.
+ - To reduce JSON event duplication per architecture, platform JSONs may
+ use "ArchStdEvent" keyword to dereference an "Architecture standard
+ events", defined in architecture standard JSONs.
+ Architecture standard JSONs must be located in the architecture root
+ folder.
+
The PMU events supported by a CPU model are expected to grouped into topics
such as Pipelining, Cache, Memory, Floating-point etc. All events for a topic
should be placed in a separate JSON file - where the file name identifies
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index eb183b1..19e30cd 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -44,6 +44,7 @@
#include <sys/resource.h> /* getrlimit */
#include <ftw.h>
#include <sys/stat.h>
+#include <linux/list.h>
#include "jsmn.h"
#include "json.h"
#include "jevents.h"
@@ -366,6 +367,67 @@ static int print_events_table_entry(void *data, char *name, char *event,
return 0;
}
+struct event_struct {
+ char *name;
+ char *event;
+ char *desc;
+ char *long_desc;
+ char *pmu;
+ char *filter;
+ char *perpkg;
+ char *unit;
+ char *metric_expr;
+ char *metric_name;
+ char *metric_group;
+ struct list_head list;
+ char strings[];
+};
+
+static LIST_HEAD(arch_std_events);
+
+#define ADD_EVENT_STRING(string) do { if (string) { \
+ es->string = strings; \
+ strings += snprintf(strings, len, "%s", string) + 1; \
+} } while (0)
+
+static int save_arch_std_events(void *data, char *name, char *event,
+ char *desc, char *long_desc, char *pmu,
+ char *unit, char *perpkg, char *metric_expr,
+ char *metric_name, char *metric_group)
+{
+ struct event_struct *es;
+ struct stat *sb = data;
+ int len;
+ char *strings;
+
+ /*
+ * Lazily allocate size of the json file to hold the
+ * strings, which would be more than large enough.
+ */
+ len = sb->st_size;
+
+ es = malloc(sizeof(*es) + len);
+ if (!es)
+ return -ENOMEM;
+ memset(es, 0, sizeof(*es));
+ list_add_tail(&es->list, &arch_std_events);
+
+ strings = &es->strings[0];
+
+ ADD_EVENT_STRING(name);
+ ADD_EVENT_STRING(event);
+ ADD_EVENT_STRING(desc);
+ ADD_EVENT_STRING(long_desc);
+ ADD_EVENT_STRING(pmu);
+ ADD_EVENT_STRING(unit);
+ ADD_EVENT_STRING(perpkg);
+ ADD_EVENT_STRING(metric_expr);
+ ADD_EVENT_STRING(metric_name);
+ ADD_EVENT_STRING(metric_group);
+
+ return 0;
+}
+
static void print_events_table_suffix(FILE *outfp)
{
fprintf(outfp, "{\n");
@@ -407,6 +469,52 @@ static char *real_event(const char *name, char *event)
return event;
}
+static void fixup_field(char *from, char **to)
+{
+ *to = malloc(strlen(from));
+
+ strcpy(*to, from);
+}
+
+#define EVENT_PREFIX "event="
+
+#define TRY_FIXUP_FIELD(string) do { if (es->string && !*string)\
+ fixup_field(es->string, string); \
+} while (0)
+
+static int
+try_fixup(const char *fn, char *arch_std, char **event, char **desc,
+ char **name, char **long_desc, char **pmu, char **filter,
+ char **perpkg, char **unit, char **metric_expr, char **metric_name,
+ char **metric_group)
+{
+ /* try to find matching event from arch standard values */
+ struct event_struct *es;
+
+ list_for_each_entry(es, &arch_std_events, list) {
+ if (!strcmp(arch_std, es->event+strlen(EVENT_PREFIX))) {
+ /* now fixup */
+ fixup_field(es->event, event);
+ TRY_FIXUP_FIELD(desc);
+ TRY_FIXUP_FIELD(name);
+ TRY_FIXUP_FIELD(long_desc);
+ TRY_FIXUP_FIELD(pmu);
+ TRY_FIXUP_FIELD(filter);
+ TRY_FIXUP_FIELD(perpkg);
+ TRY_FIXUP_FIELD(unit);
+ TRY_FIXUP_FIELD(metric_expr);
+ TRY_FIXUP_FIELD(metric_name);
+ TRY_FIXUP_FIELD(metric_group);
+
+ return 0;
+ }
+ }
+
+ pr_err("%s: could not find matching %s for %s\n",
+ prog, arch_std, fn);
+ return -1;
+}
+
/* Call func with each event in the json file */
int json_events(const char *fn,
int (*func)(void *data, char *name, char *event, char *desc,
@@ -442,6 +550,7 @@ int json_events(const char *fn,
char *metric_expr = NULL;
char *metric_name = NULL;
char *metric_group = NULL;
+ char *arch_std = NULL;
unsigned long long eventcode = 0;
struct msrmap *msr = NULL;
jsmntok_t *msrval = NULL;
@@ -527,6 +636,10 @@ int json_events(const char *fn,
addfield(map, &metric_expr, "", "", val);
for (s = metric_expr; *s; s++)
*s = tolower(*s);
+ } else if (json_streq(map, field, "ArchStdEvent")) {
+ addfield(map, &arch_std, "", "", val);
+ for (s = arch_std; *s; s++)
+ *s = tolower(*s);
}
/* ignore unknown fields */
}
@@ -538,7 +651,7 @@ int json_events(const char *fn,
addfield(map, &extra_desc, " ",
"(Precise event)", NULL);
}
- snprintf(buf, sizeof buf, "event=%#llx", eventcode);
+ snprintf(buf, sizeof(buf), "%s%#llx", EVENT_PREFIX, eventcode);
addfield(map, &event, ",", buf, NULL);
if (desc && extra_desc)
addfield(map, &desc, " ", extra_desc, NULL);
@@ -550,9 +663,21 @@ int json_events(const char *fn,
addfield(map, &event, ",", msr->pname, msrval);
if (name)
fixname(name);
-
- err = func(data, name, real_event(name, event), desc, long_desc,
- pmu, unit, perpkg, metric_expr, metric_name, metric_group);
+ err = 0;
+ if (arch_std) {
+ /*
+ * An arch standard event is referenced, so try to
+ * fixup any unassigned values.
+ */
+ err = try_fixup(fn, arch_std, &event, &desc, &name,
+ &long_desc, &pmu, &filter, &perpkg,
+ &unit, &metric_expr, &metric_name,
+ &metric_group);
+ }
+ if (!err)
+ err = func(data, name, real_event(name, event), desc,
+ long_desc, pmu, unit, perpkg, metric_expr,
+ metric_name, metric_group);
free(event);
free(desc);
free(name);
@@ -565,6 +690,7 @@ int json_events(const char *fn,
free(metric_expr);
free(metric_name);
free(metric_group);
+
if (err)
break;
tok += j;
@@ -789,6 +915,32 @@ static int is_leaf_dir(const char *fpath)
return res;
}
+static int is_json_file(const char *name)
+{
+ const char *suffix;
+
+ if (strlen(name) < 5)
+ return 0;
+
+ suffix = name + strlen(name) - 5;
+
+ if (strncmp(suffix, ".json", 5) == 0)
+ return 1;
+ return 0;
+}
+
+static int preprocess_arch_std_files(const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ int level = ftwbuf->level;
+ int is_file = typeflag == FTW_F;
+
+ if (level == 1 && is_file && is_json_file(fpath))
+ return json_events(fpath, save_arch_std_events, (void *)sb);
+
+ return 0;
+}
+
static int process_one_file(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
@@ -876,9 +1028,7 @@ static int process_one_file(const char *fpath, const struct stat *sb,
* ignore it. It could be a readme.txt for instance.
*/
if (is_file) {
- char *suffix = bname + strlen(bname) - 5;
-
- if (strncmp(suffix, ".json", 5)) {
+ if (!is_json_file(bname)) {
pr_info("%s: Ignoring file without .json suffix %s\n", prog,
fpath);
return 0;
@@ -940,6 +1090,7 @@ int main(int argc, char *argv[])
const char *output_file;
const char *start_dirname;
struct stat stbuf;
+ struct event_struct *es1, *es2;
prog = basename(argv[0]);
if (argc < 4) {
@@ -984,17 +1135,28 @@ int main(int argc, char *argv[])
maxfds = get_maxfds();
mapfile = NULL;
+ rc = nftw(ldirname, preprocess_arch_std_files, get_maxfds(), 0);
+ if (rc && verbose) {
+ pr_info("%s: Error preprocessing arch standard files %s\n",
+ prog, ldirname);
+ goto empty_map;
+ } else if (rc < 0) {
+ /* Make build fail */
+ return 1;
+ }
rc = nftw(ldirname, process_one_file, maxfds, 0);
if (rc && verbose) {
pr_info("%s: Error walking file tree %s\n", prog, ldirname);
- goto empty_map;
+ goto free_standard_arch_events;
} else if (rc < 0) {
/* Make build fail */
return 1;
- } else if (rc) {
- goto empty_map;
}
+ /* Free memories for architecture standard events */
+ list_for_each_entry_safe(es1, es2, &arch_std_events, list)
+ free(es1);
+
if (close_table)
print_events_table_suffix(eventsfp);
@@ -1011,6 +1173,9 @@ int main(int argc, char *argv[])
return 0;
+free_standard_arch_events:
+ list_for_each_entry_safe(es1, es2, &arch_std_events, list)
+ free(es1);
empty_map:
fclose(eventsfp);
create_empty_mapping(output_file);
--
1.9.1
This patch fixes the Cavium ThunderX2 JSON to use event definitions
from the ARMv8 recommended events.
The brief description is kept for readability for arch standard events,
but is not strictly required.
Signed-off-by: John Garry <[email protected]>
---
.../arch/arm64/cavium/thunderx2/core-imp-def.json | 60 ++++++++--------------
1 file changed, 20 insertions(+), 40 deletions(-)
diff --git a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
index 2db45c4..f47bf0f 100644
--- a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
+++ b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
@@ -1,62 +1,42 @@
[
{
- "PublicDescription": "Attributable Level 1 data cache access, read",
- "EventCode": "0x40",
- "EventName": "l1d_cache_rd",
- "BriefDescription": "L1D cache read",
+ "ArchStdEvent": "0x40",
+ "BriefDescription": "L1D cache access, read"
},
{
- "PublicDescription": "Attributable Level 1 data cache access, write ",
- "EventCode": "0x41",
- "EventName": "l1d_cache_wr",
- "BriefDescription": "L1D cache write",
+ "ArchStdEvent": "0x41",
+ "BriefDescription": "L1D cache access, write"
},
{
- "PublicDescription": "Attributable Level 1 data cache refill, read",
- "EventCode": "0x42",
- "EventName": "l1d_cache_refill_rd",
- "BriefDescription": "L1D cache refill read",
+ "ArchStdEvent": "0x42",
+ "BriefDescription": "L1D cache refill, read"
},
{
- "PublicDescription": "Attributable Level 1 data cache refill, write",
- "EventCode": "0x43",
- "EventName": "l1d_cache_refill_wr",
- "BriefDescription": "L1D refill write",
+ "ArchStdEvent": "0x43",
+ "BriefDescription": "L1D cache refill, write"
},
{
- "PublicDescription": "Attributable Level 1 data TLB refill, read",
- "EventCode": "0x4C",
- "EventName": "l1d_tlb_refill_rd",
- "BriefDescription": "L1D tlb refill read",
+ "ArchStdEvent": "0x4C",
+ "BriefDescription": "L1D cache refill, inner"
},
{
- "PublicDescription": "Attributable Level 1 data TLB refill, write",
- "EventCode": "0x4D",
- "EventName": "l1d_tlb_refill_wr",
- "BriefDescription": "L1D tlb refill write",
+ "ArchStdEvent": "0x4D",
+ "BriefDescription": "L1D tlb refill, write"
},
{
- "PublicDescription": "Attributable Level 1 data or unified TLB access, read",
- "EventCode": "0x4E",
- "EventName": "l1d_tlb_rd",
- "BriefDescription": "L1D tlb read",
+ "ArchStdEvent": "0x4E",
+ "BriefDescription": "L1D tlb access, read"
},
{
- "PublicDescription": "Attributable Level 1 data or unified TLB access, write",
- "EventCode": "0x4F",
- "EventName": "l1d_tlb_wr",
- "BriefDescription": "L1D tlb write",
+ "ArchStdEvent": "0x4F",
+ "BriefDescription": "L1D tlb access, write"
},
{
- "PublicDescription": "Bus access read",
- "EventCode": "0x60",
- "EventName": "bus_access_rd",
- "BriefDescription": "Bus access read",
+ "ArchStdEvent": "0x60",
+ "BriefDescription": "Bus access read"
},
{
- "PublicDescription": "Bus access write",
- "EventCode": "0x61",
- "EventName": "bus_access_wr",
- "BriefDescription": "Bus access write",
+ "ArchStdEvent": "0x61",
+ "BriefDescription": "Bus access write"
}
]
--
1.9.1
This patch adds the HiSilicon hip08 JSON file. This platform
follows the ARMv8 recommended IMPLEMENTATION DEFINED events,
where applicable.
The brief description is kept for readability for arch defined
events, but is not strictly required.
Signed-off-by: John Garry <[email protected]>
---
.../arch/arm64/hisilicon/hip08/core-imp-def.json | 140 +++++++++++++++++++++
tools/perf/pmu-events/arch/arm64/mapfile.csv | 1 +
2 files changed, 141 insertions(+)
create mode 100644 tools/perf/pmu-events/arch/arm64/hisilicon/hip08/core-imp-def.json
diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/core-imp-def.json
new file mode 100644
index 0000000..ca0be5e
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/core-imp-def.json
@@ -0,0 +1,140 @@
+[
+ {
+ "ArchStdEvent": "0x40",
+ "BriefDescription": "L1D cache access, read"
+ },
+ {
+ "ArchStdEvent": "0x41",
+ "BriefDescription": "L1D cache access, write"
+ },
+ {
+ "ArchStdEvent": "0x42",
+ "BriefDescription": "L1D cache refill, read"
+ },
+ {
+ "ArchStdEvent": "0x43",
+ "BriefDescription": "L1D cache refill, write"
+ },
+ {
+ "ArchStdEvent": "0x46",
+ "BriefDescription": "L1D cache Write-Back, victim"
+ },
+ {
+ "ArchStdEvent": "0x47",
+ "BriefDescription": "L1D cache Write-Back, cleaning and coherency"
+ },
+ {
+ "ArchStdEvent": "0x48",
+ "BriefDescription": "L1D cache invalidate"
+ },
+ {
+ "ArchStdEvent": "0x4C",
+ "BriefDescription": "L1D tlb refill, read"
+ },
+ {
+ "ArchStdEvent": "0x4D",
+ "BriefDescription": "L1D tlb refill, write"
+ },
+ {
+ "ArchStdEvent": "0x4E",
+ "BriefDescription": "L1D tlb access, read"
+ },
+ {
+ "ArchStdEvent": "0x4F",
+ "BriefDescription": "L1D tlb access, write"
+ },
+ {
+ "ArchStdEvent": "0x50",
+ "BriefDescription": "L2D cache access, read"
+ },
+ {
+ "ArchStdEvent": "0x51",
+ "BriefDescription": "L2D cache access, write"
+ },
+ {
+ "ArchStdEvent": "0x52",
+ "BriefDescription": "L2D cache refill, read"
+ },
+ {
+ "ArchStdEvent": "0x53",
+ "BriefDescription": "L2D cache refill, write"
+ },
+ {
+ "ArchStdEvent": "0x56",
+ "BriefDescription": "L2D cache Write-Back, victim"
+ },
+ {
+ "ArchStdEvent": "0x57",
+ "BriefDescription": "L2D cache Write-Back, cleaning and coherency"
+ },
+ {
+ "ArchStdEvent": "0x58",
+ "BriefDescription": "L2D cache invalidate"
+ },
+ {
+ "PublicDescription": "Level 1 instruction cache prefetch access count",
+ "EventCode": "0x102e",
+ "EventName": "L1I_CACHE_PRF",
+ "BriefDescription": "L1I cache prefetch access count",
+ },
+ {
+ "PublicDescription": "Level 1 instruction cache miss due to prefetch access count",
+ "EventCode": "0x102f",
+ "EventName": "L1I_CACHE_PRF_REFILL",
+ "BriefDescription": "L1I cache miss due to prefetch access count",
+ },
+ {
+ "PublicDescription": "Instruction queue is empty",
+ "EventCode": "0x1043",
+ "EventName": "IQ_IS_EMPTY",
+ "BriefDescription": "Instruction queue is empty",
+ },
+ {
+ "PublicDescription": "Instruction fetch stall cycles",
+ "EventCode": "0x1044",
+ "EventName": "IF_IS_STALL",
+ "BriefDescription": "Instruction fetch stall cycles",
+ },
+ {
+ "PublicDescription": "Instructions can receive, but not send",
+ "EventCode": "0x2014",
+ "EventName": "FETCH_BUBBLE",
+ "BriefDescription": "Instructions can receive, but not send",
+ },
+ {
+ "PublicDescription": "Prefetch request from LSU",
+ "EventCode": "0x6013",
+ "EventName": "PRF_REQ",
+ "BriefDescription": "Prefetch request from LSU",
+ },
+ {
+ "PublicDescription": "Hit on prefetched data",
+ "EventCode": "0x6014",
+ "EventName": "HIT_ON_PRF",
+ "BriefDescription": "Hit on prefetched data",
+ },
+ {
+ "PublicDescription": "Cycles of that the number of issuing micro operations are less than 4",
+ "EventCode": "0x7001",
+ "EventName": "EXE_STALL_CYCLE",
+ "BriefDescription": "Cycles of that the number of issue ups are less than 4",
+ },
+ {
+ "PublicDescription": "No any micro operation is issued and meanwhile any load operation is not resolved",
+ "EventCode": "0x7004",
+ "EventName": "MEM_STALL_ANYLOAD",
+ "BriefDescription": "No any micro operation is issued and meanwhile any load operation is not resolved",
+ },
+ {
+ "PublicDescription": "No any micro operation is issued and meanwhile there is any load operation missing L1 cache and pending data refill",
+ "EventCode": "0x7006",
+ "EventName": "MEM_STALL_L1MISS",
+ "BriefDescription": "No any micro operation is issued and meanwhile there is any load operation missing L1 cache and pending data refill",
+ },
+ {
+ "PublicDescription": "No any micro operation is issued and meanwhile there is any load operation missing both L1 and L2 cache and pending data refill from L3 cache",
+ "EventCode": "0x7007",
+ "EventName": "MEM_STALL_L2MISS",
+ "BriefDescription": "No any micro operation is issued and meanwhile there is any load operation missing both L1 and L2 cache and pending data refill from L3 cache",
+ },
+]
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv
index cf14e23..8f11aeb 100644
--- a/tools/perf/pmu-events/arch/arm64/mapfile.csv
+++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv
@@ -14,3 +14,4 @@
#Family-model,Version,Filename,EventType
0x00000000410fd03[[:xdigit:]],v1,arm/cortex-a53,core
0x00000000420f5160,v1,cavium/thunderx2,core
+0x00000000480fd010,v1,hisilicon/hip08,core
--
1.9.1
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> +static void fixup_field(char *from, char **to)
> +{
> + *to = malloc(strlen(from));
> +
> + strcpy(*to, from);
> +}
> +
> +#define EVENT_PREFIX "event="
> +
> +#define TRY_FIXUP_FIELD(string) do { if (es->string && !*string)\
> + fixup_field(es->string, string); \
> +} while (0)
please indent the code in the macro like normal code
> +
> +static int
> +try_fixup(const char *fn, char *arch_std, char **event, char **desc,
> + char **name, char **long_desc, char **pmu, char **filter,
> + char **perpkg, char **unit, char **metric_expr, char **metric_name,
> + char **metric_group)
> +{
> + /* try to find matching event from arch standard values */
> + struct event_struct *es;
> +
> + list_for_each_entry(es, &arch_std_events, list) {
> + if (!strcmp(arch_std, es->event+strlen(EVENT_PREFIX))) {
you could use just sizeof(EVENT_PREFIX). no need to call strlen
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> @@ -366,6 +367,67 @@ static int print_events_table_entry(void *data, char *name, char *event,
> return 0;
> }
>
> +struct event_struct {
> + char *name;
> + char *event;
> + char *desc;
> + char *long_desc;
> + char *pmu;
> + char *filter;
> + char *perpkg;
> + char *unit;
> + char *metric_expr;
> + char *metric_name;
> + char *metric_group;
> + struct list_head list;
> + char strings[];
> +};
> +
> +static LIST_HEAD(arch_std_events);
> +
> +#define ADD_EVENT_STRING(string) do { if (string) { \
> + es->string = strings; \
> + strings += snprintf(strings, len, "%s", string) + 1; \
> +} } while (0)
please indent the code in macro like normal code
thanks,
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> static void print_events_table_suffix(FILE *outfp)
> {
> fprintf(outfp, "{\n");
> @@ -407,6 +469,52 @@ static char *real_event(const char *name, char *event)
> return event;
> }
>
> +static void fixup_field(char *from, char **to)
> +{
> + *to = malloc(strlen(from));
> +
> + strcpy(*to, from);
> +}
could you just call '*to = strdup(from)' in here?
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> @@ -940,6 +1090,7 @@ int main(int argc, char *argv[])
> const char *output_file;
> const char *start_dirname;
> struct stat stbuf;
> + struct event_struct *es1, *es2;
>
> prog = basename(argv[0]);
> if (argc < 4) {
> @@ -984,17 +1135,28 @@ int main(int argc, char *argv[])
>
> maxfds = get_maxfds();
> mapfile = NULL;
> + rc = nftw(ldirname, preprocess_arch_std_files, get_maxfds(), 0);
you could use maxfds variable in here
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> + char *perpkg;
> + char *unit;
> + char *metric_expr;
> + char *metric_name;
> + char *metric_group;
> + struct list_head list;
> + char strings[];
> +};
> +
> +static LIST_HEAD(arch_std_events);
> +
> +#define ADD_EVENT_STRING(string) do { if (string) { \
> + es->string = strings; \
> + strings += snprintf(strings, len, "%s", string) + 1; \
> +} } while (0)
> +
> +static int save_arch_std_events(void *data, char *name, char *event,
> + char *desc, char *long_desc, char *pmu,
> + char *unit, char *perpkg, char *metric_expr,
> + char *metric_name, char *metric_group)
> +{
> + struct event_struct *es;
> + struct stat *sb = data;
> + int len;
> + char *strings;
> +
> + /*
> + * Lazily allocate size of the json file to hold the
> + * strings, which would be more than large enough.
> + */
> + len = sb->st_size;
> +
> + es = malloc(sizeof(*es) + len);
hum, so for single event you allocate buffer of the size
of the entire file this event is defined in?
what do I miss? I assume there're more of those arch-defined
events defined in the single file..
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> rc = nftw(ldirname, process_one_file, maxfds, 0);
> if (rc && verbose) {
> pr_info("%s: Error walking file tree %s\n", prog, ldirname);
> - goto empty_map;
> + goto free_standard_arch_events;
> } else if (rc < 0) {
> /* Make build fail */
> return 1;
> - } else if (rc) {
> - goto empty_map;
> }
please put this change into separate patch
thanks,
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
>
> +static int is_json_file(const char *name)
> +{
> + const char *suffix;
> +
> + if (strlen(name) < 5)
> + return 0;
> +
> + suffix = name + strlen(name) - 5;
> +
> + if (strncmp(suffix, ".json", 5) == 0)
> + return 1;
> + return 0;
> +}
> +
> +static int preprocess_arch_std_files(const char *fpath, const struct stat *sb,
> + int typeflag, struct FTW *ftwbuf)
> +{
> + int level = ftwbuf->level;
> + int is_file = typeflag == FTW_F;
> +
> + if (level == 1 && is_file && is_json_file(fpath))
> + return json_events(fpath, save_arch_std_events, (void *)sb);
so any .json file will pass.. just wondering you'd want to put
some name restriction for recomended events file like this -recomended
suffix you used later.. but that can be added later in case we'll
need some other json files in here ;-)
jirka
On Wed, Feb 07, 2018 at 01:44:56AM +0800, John Garry wrote:
> Currently jevents supports multiple mapfiles, but this
> is only in the form where mapfile basename starts with
> 'mapfile.csv'
>
> At the moment, no architectures actually use multiple mapfiles,
> so drop the support for now.
>
> This patch also solves a nuisance where, when the mapfile is
> edited and the text editor may create a backup, jevents may
> use the backup, as shown:
> jevents: Many mapfiles? Using pmu-events/arch/arm64/mapfile.csv~, ignoring pmu-events/arch/arm64/mapfile.csv
>
> Signed-off-by: John Garry <[email protected]>
Acked-by: Jiri Olsa <[email protected]>
thanks,
jirka
On Wed, Feb 07, 2018 at 01:44:57AM +0800, John Garry wrote:
> For some architectures (like arm), it is required to support
> a vendor sub-directory and not locate all the JSONs for a
> specific vendor in the same folder.
>
> This is because all the events for the same vendor will be
> placed in the same pmu events table, which may cause conflict.
> This conflict would be in the instance that a vendor's custom
> implemented events do have the same meaning on different platforms,
> so events in the pmu table would conflict. In addition, per list
> command may show events which are not even supported for a given
> platform.
>
> This patch adds support for a arch/vendor/platform directory
> hierarchy, while maintaining backwards-compatibility for existing
> arch/platform structure. In this, each platform would always have
> its own pmu events table.
>
> In generated file pmu_events.c, each platform table name is in
> the format pme{_vendor}_platform, like this:
>
> struct pmu_events_map pmu_events_map[] = {
> {
> .cpuid = "0x00000000420f5160",
> .version = "v1",
> .type = "core",
> .table = pme_cavium_thunderx2
> },
> {
> .cpuid = 0,
> .version = 0,
> .type = 0,
> .table = 0,
> },
> };
>
> Signed-off-by: John Garry <[email protected]>
Acked-by: Jiri Olsa <[email protected]>
thanks,
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> + rc = nftw(ldirname, preprocess_arch_std_files, get_maxfds(), 0);
> + if (rc && verbose) {
> + pr_info("%s: Error preprocessing arch standard files %s\n",
> + prog, ldirname);
> + goto empty_map;
> + } else if (rc < 0) {
> + /* Make build fail */
> + return 1;
> + }
> rc = nftw(ldirname, process_one_file, maxfds, 0);
> if (rc && verbose) {
> pr_info("%s: Error walking file tree %s\n", prog, ldirname);
> - goto empty_map;
> + goto free_standard_arch_events;
> } else if (rc < 0) {
> /* Make build fail */
> return 1;
> - } else if (rc) {
> - goto empty_map;
> }
>
> + /* Free memories for architecture standard events */
> + list_for_each_entry_safe(es1, es2, &arch_std_events, list)
> + free(es1);
> +
> if (close_table)
> print_events_table_suffix(eventsfp);
>
> @@ -1011,6 +1173,9 @@ int main(int argc, char *argv[])
>
> return 0;
>
> +free_standard_arch_events:
> + list_for_each_entry_safe(es1, es2, &arch_std_events, list)
> + free(es1);
that could go into a function and be used also above
thanks,
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
SNIP
> /* Call func with each event in the json file */
> int json_events(const char *fn,
> int (*func)(void *data, char *name, char *event, char *desc,
> @@ -442,6 +550,7 @@ int json_events(const char *fn,
> char *metric_expr = NULL;
> char *metric_name = NULL;
> char *metric_group = NULL;
> + char *arch_std = NULL;
> unsigned long long eventcode = 0;
> struct msrmap *msr = NULL;
> jsmntok_t *msrval = NULL;
> @@ -527,6 +636,10 @@ int json_events(const char *fn,
> addfield(map, &metric_expr, "", "", val);
> for (s = metric_expr; *s; s++)
> *s = tolower(*s);
> + } else if (json_streq(map, field, "ArchStdEvent")) {
> + addfield(map, &arch_std, "", "", val);
> + for (s = arch_std; *s; s++)
> + *s = tolower(*s);
> }
> /* ignore unknown fields */
> }
> @@ -538,7 +651,7 @@ int json_events(const char *fn,
> addfield(map, &extra_desc, " ",
> "(Precise event)", NULL);
> }
> - snprintf(buf, sizeof buf, "event=%#llx", eventcode);
> + snprintf(buf, sizeof(buf), "%s%#llx", EVENT_PREFIX, eventcode);
> addfield(map, &event, ",", buf, NULL);
> if (desc && extra_desc)
> addfield(map, &desc, " ", extra_desc, NULL);
> @@ -550,9 +663,21 @@ int json_events(const char *fn,
> addfield(map, &event, ",", msr->pname, msrval);
> if (name)
> fixname(name);
> -
> - err = func(data, name, real_event(name, event), desc, long_desc,
> - pmu, unit, perpkg, metric_expr, metric_name, metric_group);
> + err = 0;
> + if (arch_std) {
> + /*
> + * An arch standard event is referenced, so try to
> + * fixup any unassigned values.
> + */
> + err = try_fixup(fn, arch_std, &event, &desc, &name,
> + &long_desc, &pmu, &filter, &perpkg,
> + &unit, &metric_expr, &metric_name,
> + &metric_group);
> + }
> + if (!err)
> + err = func(data, name, real_event(name, event), desc,
> + long_desc, pmu, unit, perpkg, metric_expr,
> + metric_name, metric_group);
> free(event);
> free(desc);
> free(name);
> @@ -565,6 +690,7 @@ int json_events(const char *fn,
> free(metric_expr);
> free(metric_name);
> free(metric_group);
> +
should you call free(arch_std) in here?
jirka
On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
> For some architectures (like arm), there are architecture-
> defined events. Sometimes these events may be "recommended"
> according to the architecture standard, in that the
> implementer is free ignore the "recommendation" and create
> its custom event.
>
> This patch adds support for parsing standard events from
> arch-defined JSONs, and fixing up vendor events when they
> have implemented these events as standard.
>
> Support is also ensured that the vendor may implement their
> own custom events.
>
> A new step is added to the pmu events parsing to fix up the
> vendor events with the arch-standard events.
>
> The arch-defined JSONs must be placed in the arch root
> folder for preprocessing prior to tree JSON processing.
>
> In the vendor JSON, to specify that the arch event is
> supported, the keyword "ArchStdEvent" should be used,
> like this:
> [
> {
> "ArchStdEvent": "0x41",
> "BriefDescription": "L1D cache access, write"
> },
> ]
>
> No other JSON objects are strictly required. However,
> for other objects added, these take precedence over
> architecture defined standard events, thus supporting
> separate events which have the same event code.
>
> Signed-off-by: John Garry <[email protected]>
> ---
> tools/perf/pmu-events/Build | 1 +
> tools/perf/pmu-events/README | 6 ++
> tools/perf/pmu-events/jevents.c | 185 +++++++++++++++++++++++++++++++++++++---
> 3 files changed, 182 insertions(+), 10 deletions(-)
>
> diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
> index 999a4e8..f9e8466 100644
> --- a/tools/perf/pmu-events/Build
> +++ b/tools/perf/pmu-events/Build
> @@ -1,5 +1,6 @@
> hostprogs := jevents
>
> +CHOSTFLAGS = -I$(srctree)/tools/include
Ithink this could be just CHOSTFLAGS_jevents.o = -I$(srctree)/tools/include
it's just for the list.h right?
jirka
On Thu, 8 Feb 2018 14:54:23 +0100
Jiri Olsa <[email protected]> wrote:
> On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
>
> SNIP
>
> > static void print_events_table_suffix(FILE *outfp)
> > {
> > fprintf(outfp, "{\n");
> > @@ -407,6 +469,52 @@ static char *real_event(const char *name, char *event)
> > return event;
> > }
> >
> > +static void fixup_field(char *from, char **to)
> > +{
> > + *to = malloc(strlen(from));
> > +
> > + strcpy(*to, from);
> > +}
>
> could you just call '*to = strdup(from)' in here?
And check for malloc returning NULL.
Alan
On 08/02/2018 13:55, Jiri Olsa wrote:
> On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
>
> SNIP
>
>> + char *perpkg;
>> + char *unit;
>> + char *metric_expr;
>> + char *metric_name;
>> + char *metric_group;
>> + struct list_head list;
>> + char strings[];
>> +};
>> +
>> +static LIST_HEAD(arch_std_events);
>> +
>> +#define ADD_EVENT_STRING(string) do { if (string) { \
>> + es->string = strings; \
>> + strings += snprintf(strings, len, "%s", string) + 1; \
>> +} } while (0)
>> +
>> +static int save_arch_std_events(void *data, char *name, char *event,
>> + char *desc, char *long_desc, char *pmu,
>> + char *unit, char *perpkg, char *metric_expr,
>> + char *metric_name, char *metric_group)
>> +{
>> + struct event_struct *es;
>> + struct stat *sb = data;
>> + int len;
>> + char *strings;
>> +
>> + /*
>> + * Lazily allocate size of the json file to hold the
>> + * strings, which would be more than large enough.
>> + */
>> + len = sb->st_size;
>> +
>> + es = malloc(sizeof(*es) + len);
>
> hum, so for single event you allocate buffer of the size
> of the entire file this event is defined in?
>
> what do I miss? I assume there're more of those arch-defined
> events defined in the single file..
Hi Jirka,
Yes, allocating the file size per event was just to make the code more
concise (instead of finding each string length), but obviously it is an
inefficient practice in terms of memory usage.
But since the JSONs are generally not huge, and in practice we would
only be accessing a fraction of the buffer's physical memory to save the
event strings, I thought it ok.
Anyway, I'll see if there is something more efficient I can do.
Thanks,
John
>
> jirka
>
> .
>
On Thu, Feb 08, 2018 at 02:45:37PM +0000, John Garry wrote:
> On 08/02/2018 13:55, Jiri Olsa wrote:
> > On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
> >
> > SNIP
> >
> > > + char *perpkg;
> > > + char *unit;
> > > + char *metric_expr;
> > > + char *metric_name;
> > > + char *metric_group;
> > > + struct list_head list;
> > > + char strings[];
> > > +};
> > > +
> > > +static LIST_HEAD(arch_std_events);
> > > +
> > > +#define ADD_EVENT_STRING(string) do { if (string) { \
> > > + es->string = strings; \
> > > + strings += snprintf(strings, len, "%s", string) + 1; \
> > > +} } while (0)
> > > +
> > > +static int save_arch_std_events(void *data, char *name, char *event,
> > > + char *desc, char *long_desc, char *pmu,
> > > + char *unit, char *perpkg, char *metric_expr,
> > > + char *metric_name, char *metric_group)
> > > +{
> > > + struct event_struct *es;
> > > + struct stat *sb = data;
> > > + int len;
> > > + char *strings;
> > > +
> > > + /*
> > > + * Lazily allocate size of the json file to hold the
> > > + * strings, which would be more than large enough.
> > > + */
> > > + len = sb->st_size;
> > > +
> > > + es = malloc(sizeof(*es) + len);
> >
> > hum, so for single event you allocate buffer of the size
> > of the entire file this event is defined in?
> >
> > what do I miss? I assume there're more of those arch-defined
> > events defined in the single file..
>
> Hi Jirka,
>
> Yes, allocating the file size per event was just to make the code more
> concise (instead of finding each string length), but obviously it is an
> inefficient practice in terms of memory usage.
>
> But since the JSONs are generally not huge, and in practice we would only be
> accessing a fraction of the buffer's physical memory to save the event
> strings, I thought it ok.
>
> Anyway, I'll see if there is something more efficient I can do.
maybe the json parser could provide the overall lenght?
jirka
On 08/02/2018 13:55, Jiri Olsa wrote:
> On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
>> For some architectures (like arm), there are architecture-
>> defined events. Sometimes these events may be "recommended"
>> according to the architecture standard, in that the
>> implementer is free ignore the "recommendation" and create
>> its custom event.
>>
>> This patch adds support for parsing standard events from
>> arch-defined JSONs, and fixing up vendor events when they
>> have implemented these events as standard.
>>
>> Support is also ensured that the vendor may implement their
>> own custom events.
>>
>> A new step is added to the pmu events parsing to fix up the
>> vendor events with the arch-standard events.
>>
>> The arch-defined JSONs must be placed in the arch root
>> folder for preprocessing prior to tree JSON processing.
>>
>> In the vendor JSON, to specify that the arch event is
>> supported, the keyword "ArchStdEvent" should be used,
>> like this:
>> [
>> {
>> "ArchStdEvent": "0x41",
>> "BriefDescription": "L1D cache access, write"
>> },
>> ]
>>
>> No other JSON objects are strictly required. However,
>> for other objects added, these take precedence over
>> architecture defined standard events, thus supporting
>> separate events which have the same event code.
>>
>> Signed-off-by: John Garry <[email protected]>
>> ---
>> tools/perf/pmu-events/Build | 1 +
>> tools/perf/pmu-events/README | 6 ++
>> tools/perf/pmu-events/jevents.c | 185 +++++++++++++++++++++++++++++++++++++---
>> 3 files changed, 182 insertions(+), 10 deletions(-)
>>
>> diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
>> index 999a4e8..f9e8466 100644
>> --- a/tools/perf/pmu-events/Build
>> +++ b/tools/perf/pmu-events/Build
>> @@ -1,5 +1,6 @@
>> hostprogs := jevents
>>
>> +CHOSTFLAGS = -I$(srctree)/tools/include
>
> Ithink this could be just CHOSTFLAGS_jevents.o = -I$(srctree)/tools/include
Fine, it could be argued to keep as is, but not a big deal
> it's just for the list.h right?
>
Right, for linux/list.h
John
> jirka
>
> .
>
On 08/02/2018 13:55, Jiri Olsa wrote:
> On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
>
> SNIP
>
>>
>> +static int is_json_file(const char *name)
>> +{
>> + const char *suffix;
>> +
>> + if (strlen(name) < 5)
>> + return 0;
>> +
>> + suffix = name + strlen(name) - 5;
>> +
>> + if (strncmp(suffix, ".json", 5) == 0)
>> + return 1;
>> + return 0;
>> +}
>> +
>> +static int preprocess_arch_std_files(const char *fpath, const struct stat *sb,
>> + int typeflag, struct FTW *ftwbuf)
>> +{
>> + int level = ftwbuf->level;
>> + int is_file = typeflag == FTW_F;
>> +
>> + if (level == 1 && is_file && is_json_file(fpath))
>> + return json_events(fpath, save_arch_std_events, (void *)sb);
>
> so any .json file will pass..
Yes, so according to the scheme any architecture JSONs should be placed
in the arch root folder.
just wondering you'd want to put
> some name restriction for recomended events file like this -recomended
> suffix you used later.. but that can be added later in case we'll
> need some other json files in here ;-)
Sorry, but I don't see what the naming restriction would mean in practice.
Thanks,
John
>
> jirka
>
> .
>
On 08/02/2018 14:02, Alan Cox wrote:
> On Thu, 8 Feb 2018 14:54:23 +0100
> Jiri Olsa <[email protected]> wrote:
>
>> On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
>>
>> SNIP
>>
>>> static void print_events_table_suffix(FILE *outfp)
>>> {
>>> fprintf(outfp, "{\n");
>>> @@ -407,6 +469,52 @@ static char *real_event(const char *name, char *event)
>>> return event;
>>> }
>>>
>>> +static void fixup_field(char *from, char **to)
>>> +{
>>> + *to = malloc(strlen(from));
>>> +
>>> + strcpy(*to, from);
>>> +}
>>
>> could you just call '*to = strdup(from)' in here?
Right
>
> And check for malloc returning NULL.
>
Right again,
> Alan
>
I should have concentrated on the coding as much as the feature being
added...
Thanks,
John
> .
>
On 08/02/2018 13:54, Jiri Olsa wrote:
> On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
>
Hi Jirka,
I'll try to combine some responses, below:
> SNIP
>
>> +static void fixup_field(char *from, char **to)
>> +{
>> + *to = malloc(strlen(from));
>> +
>> + strcpy(*to, from);
>> +}
>> +
>> +#define EVENT_PREFIX "event="
>> +
>> +#define TRY_FIXUP_FIELD(string) do { if (es->string && !*string)\
>> + fixup_field(es->string, string); \
>> +} while (0)
>
> please indent the code in the macro like normal code
>
Ok
>> +
>> +static int
>> +try_fixup(const char *fn, char *arch_std, char **event, char **desc,
>> + char **name, char **long_desc, char **pmu, char **filter,
>> + char **perpkg, char **unit, char **metric_expr, char **metric_name,
>> + char **metric_group)
>> +{
>> + /* try to find matching event from arch standard values */
>> + struct event_struct *es;
>> +
>> + list_for_each_entry(es, &arch_std_events, list) {
>> + if (!strcmp(arch_std, es->event+strlen(EVENT_PREFIX))) {
>
> you could use just sizeof(EVENT_PREFIX). no need to call strlen
>
Right,
>> +
>> +static LIST_HEAD(arch_std_events);
>> +
>> +#define ADD_EVENT_STRING(string) do { if (string) { \
>> + es->string = strings; \
>> + strings += snprintf(strings, len, "%s", string) + 1; \
>> +} } while (0)
>
> please indent the code in macro like normal code
This looked ok, with a single tab indent. It is same style as "EXPECT"
macro.
>> mapfile = NULL;
>> + rc = nftw(ldirname, preprocess_arch_std_files, get_maxfds(), 0);
>
> you could use maxfds variable in here
sure
>>
>> +free_standard_arch_events:
>> + list_for_each_entry_safe(es1, es2, &arch_std_events, list)
>> + free(es1);
>
> that could go into a function and be used also above
fine
>> free(metric_name);
>> free(metric_group);
>> +
>
> should you call free(arch_std) in here?
Right, that's sloppy
>> if (rc && verbose) {
>> pr_info("%s: Error walking file tree %s\n", prog, ldirname);
>> - goto empty_map;
>> + goto free_standard_arch_events;
>> } else if (rc < 0) {
>> /* Make build fail */
>> return 1;
>> - } else if (rc) {
>> - goto empty_map;
>> }
>
> please put this change into separate patch
>
> thanks,
Sure, I just couldn't see how a value > 0 could be returned in the
current code paths.
> jirka
>
> .
>
Thanks,
John
On Thu, Feb 08, 2018 at 03:25:30PM +0000, John Garry wrote:
> On 08/02/2018 13:55, Jiri Olsa wrote:
> > On Wed, Feb 07, 2018 at 01:45:00AM +0800, John Garry wrote:
> >
> > SNIP
> >
> > >
> > > +static int is_json_file(const char *name)
> > > +{
> > > + const char *suffix;
> > > +
> > > + if (strlen(name) < 5)
> > > + return 0;
> > > +
> > > + suffix = name + strlen(name) - 5;
> > > +
> > > + if (strncmp(suffix, ".json", 5) == 0)
> > > + return 1;
> > > + return 0;
> > > +}
> > > +
> > > +static int preprocess_arch_std_files(const char *fpath, const struct stat *sb,
> > > + int typeflag, struct FTW *ftwbuf)
> > > +{
> > > + int level = ftwbuf->level;
> > > + int is_file = typeflag == FTW_F;
> > > +
> > > + if (level == 1 && is_file && is_json_file(fpath))
> > > + return json_events(fpath, save_arch_std_events, (void *)sb);
> >
> > so any .json file will pass..
>
> Yes, so according to the scheme any architecture JSONs should be placed in
> the arch root folder.
>
> just wondering you'd want to put
> > some name restriction for recomended events file like this -recomended
> > suffix you used later.. but that can be added later in case we'll
> > need some other json files in here ;-)
>
> Sorry, but I don't see what the naming restriction would mean in practice.
now any file you add there will be treated as 'recomended' events file,
having them with '-recomended.json' suffix would separate them.. but
as I said it's ok for now
jirka