1

I want to use the PAPI library to record hardware performance counters during benchmarks, but it does not seem to work on my Raspberry Pi 4 B.

Installing PAPI was not a problem, but there are no events available. Calling papi_event, all the events are listed as not available. papi_event suggests to call papi_component_avail, which says:

Available components and hardware information.
--------------------------------------------------------------------------------
PAPI version             : 5.7.0.0
Operating system         : Linux 4.19.97-v7l+
Vendor string and code   : ARM (7, 0x7)
Model string and code    : ARMv7 Processor rev 3 (v7l) (3, 0x3)
CPU revision             : 3.000000
CPUID                    : Family/Model/Stepping 7/3336/0, 0x07/0xd08/0x00
CPU Max MHz              : 1500
CPU Min MHz              : 600
Total cores              : 4
SMT threads per core     : 1
Cores per socket         : 4
Sockets                  : 1
Cores per NUMA region    : 4
NUMA regions             : 0
Running in a VM          : no
Number Hardware Counters : 0
Max Multiplex Counters   : 384
Fast counter read (rdpmc): no
--------------------------------------------------------------------------------

Compiled-in components:
Name:   perf_event              Linux perf_event CPU counters
   \-> Disabled: Unknown libpfm4 related error
Name:   perf_event_uncore       Linux perf_event CPU uncore and northbridge
   \-> Disabled: No uncore PMUs or events found

Active components:

--------------------------------------------------------------------------------

I am guessing it has something to do with libpfm4, but I don't know how I would fix this.

Can we use perf instead?

I was wondering perf worked, but there is no version of perf in the repositories that matches the kernel version.

  • Kernel: 4.19
  • Perf: 4.18, or 4.9

In another thread in which a package was suggested, with the right version. It seemed to work but perf test shows a number of failures.

0

Cortex A72, the arm core used in Raspberry Pi 4 is not on the support list of libpfm. It seems the PMU of Cortex A72 is similar to Cortex A57, so you can add support for Cortex A72 by duplicating the code for Cortex A57.

Here is a patch I made on papi 6.0.0.1 release, so after clone the repo, git checkout to tag papi-6-0-0-1-t, then git am to apply this patch.

From d330ba03c1f4ae2c819c48095ffc9c0fea1e0ef2 Mon Sep 17 00:00:00 2001
From: BamboWu <qw2699@utexas.edu>
Date: Thu, 14 May 2020 06:52:16 +0000
Subject: [PATCH] Add support for Cortex A72

---
 src/libpfm4/include/perfmon/pfmlib.h          |   1 +
 src/libpfm4/lib/Makefile                      |   4 +-
 .../lib/events/arm_cortex_a72_events.h        | 440 ++++++++++++++++++
 src/libpfm4/lib/pfmlib_arm_armv8.c            |  42 ++
 src/libpfm4/lib/pfmlib_common.c               |   2 +
 src/libpfm4/lib/pfmlib_priv.h                 |   1 +
 src/papi_events.csv                           |   1 +
 7 files changed, 490 insertions(+), 1 deletion(-)
 create mode 100644 src/libpfm4/lib/events/arm_cortex_a72_events.h

diff --git a/src/libpfm4/include/perfmon/pfmlib.h b/src/libpfm4/include/perfmon/pfmlib.h
index 35d2e5795..d2b70daa2 100644
--- a/src/libpfm4/include/perfmon/pfmlib.h
+++ b/src/libpfm4/include/perfmon/pfmlib.h
@@ -239,6 +239,7 @@ typedef enum {

    PFM_PMU_S390X_CPUM_SF,      /* s390x: CPU-M sampling facility */

+   PFM_PMU_ARM_CORTEX_A72,     /* ARM Cortex A72 (ARMv8) */
    PFM_PMU_ARM_CORTEX_A57,     /* ARM Cortex A57 (ARMv8) */
    PFM_PMU_ARM_CORTEX_A53,     /* ARM Cortex A53 (ARMv8) */

diff --git a/src/libpfm4/lib/Makefile b/src/libpfm4/lib/Makefile
index 055696761..6e4d33233 100644
--- a/src/libpfm4/lib/Makefile
+++ b/src/libpfm4/lib/Makefile
@@ -359,12 +359,14 @@ INC_ARM=pfmlib_arm_priv.h         \
    events/arm_cortex_a8_events.h       \
    events/arm_cortex_a9_events.h       \
    events/arm_cortex_a15_events.h      \
+   events/arm_cortex_a72_events.h      \
    events/arm_cortex_a57_events.h      \
    events/arm_cortex_a53_events.h      \
    events/arm_cavium_tx2_events.h      \
    events/arm_marvell_tx2_unc_events.h

-INC_ARM64=events/arm_cortex_a57_events.h   \
+INC_ARM64=events/arm_cortex_a72_events.h \
+   events/arm_cortex_a57_events.h  \
    events/arm_cortex_a53_events.h  \
    events/arm_cavium_tx2_events.h  \
    events/arm_marvell_tx2_unc_events.h
diff --git a/src/libpfm4/lib/events/arm_cortex_a72_events.h b/src/libpfm4/lib/events/arm_cortex_a72_events.h
new file mode 100644
index 000000000..f695ac4a3
--- /dev/null
+++ b/src/libpfm4/lib/events/arm_cortex_a72_events.h
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2020 University of Texas at Austin. All rights reserved
+ * Contributed by Qinzhe Wu <qw2699@utexas.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Cortex A72 r0p3
+ * based on Table 11-24 from the "Cortex A72 Technical Reference Manual"
+ */
+
+static const arm_entry_t arm_cortex_a72_pe[]={
+   {.name = "SW_INCR",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x00,
+    .desc = "Instruction architecturally executed (condition check pass) Software increment"
+   },
+   {.name = "L1I_CACHE_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x01,
+    .desc = "Level 1 instruction cache refill"
+   },
+   {.name = "L1I_TLB_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x02,
+    .desc = "Level 1 instruction TLB refill"
+   },
+   {.name = "L1D_CACHE_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x03,
+    .desc = "Level 1 data cache refill"
+   },
+   {.name = "L1D_CACHE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x04,
+    .desc = "Level 1 data cache access"
+   },
+   {.name = "L1D_TLB_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x05,
+    .desc = "Level 1 data TLB refill"
+   },
+
+   {.name = "INST_RETIRED",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x08,
+    .desc = "Instruction architecturally executed"
+   },
+   {.name = "EXCEPTION_TAKEN",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x09,
+    .desc = "Exception taken"
+   },
+   {.name = "EXCEPTION_RETURN",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x0a,
+    .desc = "Instruction architecturally executed (condition check pass) Exception return"
+   },
+   {.name = "CID_WRITE_RETIRED",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x0b,
+    .desc = "Instruction architecturally executed (condition check pass)  Write to CONTEXTIDR"
+   },
+
+   {.name = "BRANCH_MISPRED",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x10,
+    .desc = "Mispredicted or not predicted branch speculatively executed"
+   },
+   {.name = "CPU_CYCLES",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x11,
+    .desc = "Cycles"
+   },
+   {.name = "BRANCH_PRED",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x12,
+    .desc = "Predictable branch speculatively executed"
+   },
+   {.name = "DATA_MEM_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x13,
+    .desc = "Data memory access"
+   },
+   {.name = "L1I_CACHE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x14,
+    .desc = "Level 1 instruction cache access"
+   },
+   {.name = "L1D_CACHE_WB",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x15,
+    .desc = "Level 1 data cache WriteBack"
+   },
+   {.name = "L2D_CACHE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x16,
+    .desc = "Level 2 data cache access"
+   },
+   {.name = "L2D_CACHE_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x17,
+    .desc = "Level 2 data cache refill"
+   },
+   {.name = "L2D_CACHE_WB",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x18,
+    .desc = "Level 2 data cache WriteBack"
+   },
+   {.name = "BUS_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x19,
+    .desc = "Bus access"
+   },
+   {.name = "LOCAL_MEMORY_ERROR",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x1a,
+    .desc = "Local memory error"
+   },
+   {.name = "INST_SPEC_EXEC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x1b,
+    .desc = "Instruction speculatively executed"
+   },
+   {.name = "TTBR_WRITE_RETIRED",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x1c,
+    .desc = "Instruction architecturally executed (condition check pass)  Write to translation table base"
+   },
+   {.name = "BUS_CYCLES",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x1d,
+    .desc = "Bus cycle"
+   },
+   {.name = "L1D_READ_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x40,
+    .desc = "Level 1 data cache read access"
+   },
+   {.name = "L1D_WRITE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x41,
+    .desc = "Level 1 data cache write access"
+   },
+   {.name = "L1D_READ_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x42,
+    .desc = "Level 1 data cache read refill"
+   },
+   {.name = "L1D_WRITE_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x43,
+    .desc = "Level 1 data cache write refill"
+   },
+   {.name = "L1D_WB_VICTIM",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x46,
+    .desc = "Level 1 data cache writeback victim"
+   },
+   {.name = "L1D_WB_CLEAN_COHERENCY",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x47,
+    .desc = "Level 1 data cache writeback cleaning and coherency"
+   },
+   {.name = "L1D_INVALIDATE",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x48,
+    .desc = "Level 1 data cache invalidate"
+   },
+   {.name = "L1D_TLB_READ_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x4c,
+    .desc = "Level 1 data TLB read refill"
+   },
+   {.name = "L1D_TLB_WRITE_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x4d,
+    .desc = "Level 1 data TLB write refill"
+   },
+   {.name = "L2D_READ_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x50,
+    .desc = "Level 2 data cache read access"
+   },
+   {.name = "L2D_WRITE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x51,
+    .desc = "Level 2 data cache write access"
+   },
+   {.name = "L2D_READ_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x52,
+    .desc = "Level 2 data cache read refill"
+   },
+   {.name = "L2D_WRITE_REFILL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x53,
+    .desc = "Level 2 data cache write refill"
+   },
+   {.name = "L2D_WB_VICTIM",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x56,
+    .desc = "Level 2 data cache writeback victim"
+   },
+   {.name = "L2D_WB_CLEAN_COHERENCY",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x57,
+    .desc = "Level 2 data cache writeback cleaning and coherency"
+   },
+   {.name = "L2D_INVALIDATE",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x58,
+    .desc = "Level 2 data cache invalidate"
+   },
+   {.name = "BUS_READ_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x60,
+    .desc = "Bus read access"
+   },
+   {.name = "BUS_WRITE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x61,
+    .desc = "Bus write access"
+   },
+   {.name = "BUS_NORMAL_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x62,
+    .desc = "Bus normal access"
+   },
+   {.name = "BUS_NOT_NORMAL_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x63,
+    .desc = "Bus not normal access"
+   },
+   {.name = "BUS_NORMAL_ACCESS_2",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x64,
+    .desc = "Bus normal access"
+   },
+   {.name = "BUS_PERIPH_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x65,
+    .desc = "Bus peripheral access"
+   },
+   {.name = "DATA_MEM_READ_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x66,
+    .desc = "Data memory read access"
+   },
+   {.name = "DATA_MEM_WRITE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x67,
+    .desc = "Data memory write access"
+   },
+   {.name = "UNALIGNED_READ_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x68,
+    .desc = "Unaligned read access"
+   },
+   {.name = "UNALIGNED_WRITE_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x69,
+    .desc = "Unaligned read access"
+   },
+   {.name = "UNALIGNED_ACCESS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x6a,
+    .desc = "Unaligned access"
+   },
+   {.name = "INST_SPEC_EXEC_LDREX",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x6c,
+    .desc = "LDREX exclusive instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_STREX_PASS",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x6d,
+    .desc = "STREX pass exclusive instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_STREX_FAIL",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x6e,
+    .desc = "STREX fail exclusive instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_LOAD",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x70,
+    .desc = "Load instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_STORE",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x71,
+    .desc = "Store instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_LOAD_STORE",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x72,
+    .desc = "Load or store instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_INTEGER_INST",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x73,
+    .desc = "Integer data processing instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_SIMD",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x74,
+    .desc = "Advanced SIMD instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_VFP",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x75,
+    .desc = "VFP instruction speculatively executed"
+   },
+   {.name = "INST_SPEC_EXEC_SOFT_PC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x76,
+    .desc = "Software of the PC instruction speculatively executed"
+   },
+   {.name = "BRANCH_SPEC_EXEC_IMM_BRANCH",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x78,
+    .desc = "Immediate branch speculatively executed"
+   },
+   {.name = "BRANCH_SPEC_EXEC_RET",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x79,
+    .desc = "Return branch speculatively executed"
+   },
+   {.name = "BRANCH_SPEC_EXEC_IND",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x7a,
+    .desc = "Indirect branch speculatively executed"
+   },
+   {.name = "BARRIER_SPEC_EXEC_ISB",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x7c,
+    .desc = "ISB barrier speculatively executed"
+   },
+   {.name = "BARRIER_SPEC_EXEC_DSB",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x7d,
+    .desc = "DSB barrier speculatively executed"
+   },
+   {.name = "BARRIER_SPEC_EXEC_DMB",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x7e,
+    .desc = "DMB barrier speculatively executed"
+   },
+   {.name = "EXCEPTION_UNDEF",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x81,
+    .desc = "Exception taken, other synchronous"
+   },
+   {.name = "EXCEPTION_SVC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x82,
+    .desc = "Exception taken, supervisor call"
+   },
+   {.name = "EXCEPTION_PABORT",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x83,
+    .desc = "Exception taken, instruction abort"
+   },
+   {.name = "EXCEPTION_DABORT",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x84,
+    .desc = "Exception taken, data abort or SError"
+   },
+   {.name = "EXCEPTION_IRQ",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x86,
+    .desc = "Exception taken, irq"
+   },
+   {.name = "EXCEPTION_FIQ",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x87,
+    .desc = "Exception taken, irq"
+   },
+   {.name = "EXCEPTION_SMC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x88,
+    .desc = "Exception taken, secure monitor call"
+   },
+   {.name = "EXCEPTION_HVC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x8a,
+    .desc = "Exception taken, hypervisor call"
+   },
+   {.name = "EXCEPTION_TRAP_PABORT",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x8b,
+    .desc = "Exception taken, instruction abort not taken locally"
+   },
+   {.name = "EXCEPTION_TRAP_DABORT",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x8c,
+    .desc = "Exception taken, data abort or SError not taken locally"
+   },
+   {.name = "EXCEPTION_TRAP_OTHER",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x8d,
+    .desc = "Exception taken, other traps not taken locally"
+   },
+   {.name = "EXCEPTION_TRAP_IRQ",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x8e,
+    .desc = "Exception taken, irq not taken locally"
+   },
+   {.name = "EXCEPTION_TRAP_FIQ",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x8f,
+    .desc = "Exception taken, fiq not taken locally"
+   },
+   {.name = "RC_LD_SPEC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x90,
+    .desc = "Release consistency instruction speculatively executed (load-acquire)",
+   },
+   {.name = "RC_ST_SPEC",
+    .modmsk = ARMV8_ATTRS,
+    .code = 0x91,
+    .desc = "Release consistency instruction speculatively executed (store-release)",
+   },
+   /* END Cortex A72 specific events */
+};
diff --git a/src/libpfm4/lib/pfmlib_arm_armv8.c b/src/libpfm4/lib/pfmlib_arm_armv8.c
index a252951cf..affc619be 100644
--- a/src/libpfm4/lib/pfmlib_arm_armv8.c
+++ b/src/libpfm4/lib/pfmlib_arm_armv8.c
@@ -30,12 +30,29 @@
 #include "pfmlib_priv.h"           /* library private */
 #include "pfmlib_arm_priv.h"

+#include "events/arm_cortex_a72_events.h"    /* A72 event tables */
 #include "events/arm_cortex_a57_events.h"    /* A57 event tables */
 #include "events/arm_cortex_a53_events.h"    /* A53 event tables */
 #include "events/arm_xgene_events.h"         /* Applied Micro X-Gene tables */
 #include "events/arm_cavium_tx2_events.h"      /* Marvell ThunderX2 tables */
 #include "events/arm_marvell_tx2_unc_events.h"     /* Marvell ThunderX2 PMU tables */

+static int
+pfm_arm_detect_cortex_a72(void *this)
+{
+   int ret;
+
+   ret = pfm_arm_detect(this);
+   if (ret != PFM_SUCCESS)
+       return PFM_ERR_NOTSUPP;
+
+   if ((pfm_arm_cfg.implementer == 0x41) && /* ARM */
+        (pfm_arm_cfg.part == 0xd08)) { /* Cortex A57 */
+           return PFM_SUCCESS;
+   }
+   return PFM_ERR_NOTSUPP;
+}
+
 static int
 pfm_arm_detect_cortex_a57(void *this)
 {
@@ -104,6 +121,31 @@ pfm_arm_detect_thunderx2(void *this)
    return PFM_ERR_NOTSUPP;
 }

+/* ARM Cortex A72 support */
+pfmlib_pmu_t arm_cortex_a72_support={
+   .desc           = "ARM Cortex A72",
+   .name           = "arm_ac72",
+   .pmu            = PFM_PMU_ARM_CORTEX_A72,
+   .pme_count      = LIBPFM_ARRAY_SIZE(arm_cortex_a72_pe),
+   .type           = PFM_PMU_TYPE_CORE,
+   .pe         = arm_cortex_a72_pe,
+
+   .pmu_detect     = pfm_arm_detect_cortex_a72,
+   .max_encoding       = 1,
+   .num_cntrs      = 6,
+
+   .get_event_encoding[PFM_OS_NONE] = pfm_arm_get_encoding,
+    PFMLIB_ENCODE_PERF(pfm_arm_get_perf_encoding),
+   .get_event_first    = pfm_arm_get_event_first,
+   .get_event_next     = pfm_arm_get_event_next,
+   .event_is_valid     = pfm_arm_event_is_valid,
+   .validate_table     = pfm_arm_validate_table,
+   .get_event_info     = pfm_arm_get_event_info,
+   .get_event_attr_info    = pfm_arm_get_event_attr_info,
+    PFMLIB_VALID_PERF_PATTRS(pfm_arm_perf_validate_pattrs),
+   .get_event_nattrs   = pfm_arm_get_event_nattrs,
+};
+
 /* ARM Cortex A57 support */
 pfmlib_pmu_t arm_cortex_a57_support={
    .desc           = "ARM Cortex A57",
diff --git a/src/libpfm4/lib/pfmlib_common.c b/src/libpfm4/lib/pfmlib_common.c
index 43a333432..6c71df4b5 100644
--- a/src/libpfm4/lib/pfmlib_common.c
+++ b/src/libpfm4/lib/pfmlib_common.c
@@ -482,6 +482,7 @@ static pfmlib_pmu_t *pfmlib_pmus[]=
    &arm_cortex_a15_support,
    &arm_1176_support,
    &arm_qcom_krait_support,
+   &arm_cortex_a72_support,
    &arm_cortex_a57_support,
    &arm_cortex_a53_support,
    &arm_xgene_support,
@@ -494,6 +495,7 @@ static pfmlib_pmu_t *pfmlib_pmus[]=
    &arm_thunderx2_ccpi1_support,
 #endif
 #ifdef CONFIG_PFMLIB_ARCH_ARM64
+   &arm_cortex_a72_support,
    &arm_cortex_a57_support,
    &arm_cortex_a53_support,
    &arm_xgene_support,
diff --git a/src/libpfm4/lib/pfmlib_priv.h b/src/libpfm4/lib/pfmlib_priv.h
index 796aa74dd..c813fd5e0 100644
--- a/src/libpfm4/lib/pfmlib_priv.h
+++ b/src/libpfm4/lib/pfmlib_priv.h
@@ -645,6 +645,7 @@ extern pfmlib_pmu_t arm_cortex_a9_support;
 extern pfmlib_pmu_t arm_cortex_a15_support;
 extern pfmlib_pmu_t arm_1176_support;
 extern pfmlib_pmu_t arm_qcom_krait_support;
+extern pfmlib_pmu_t arm_cortex_a72_support;
 extern pfmlib_pmu_t arm_cortex_a57_support;
 extern pfmlib_pmu_t arm_cortex_a53_support;
 extern pfmlib_pmu_t arm_xgene_support;
diff --git a/src/papi_events.csv b/src/papi_events.csv
index 8e96adfbd..a58c53a18 100644
--- a/src/papi_events.csv
+++ b/src/papi_events.csv
@@ -1772,6 +1772,7 @@ PRESET,PAPI_L1_ICM,NOT_DERIVED,IFETCH_MISS
 #
 CPU,arm_ac15
 CPU,arm_ac57
+CPU,arm_ac72
 #
 PRESET,PAPI_TOT_INS,NOT_DERIVED,INST_RETIRED
 PRESET,PAPI_TOT_IIS,NOT_DERIVED,INST_SPEC_EXEC
-- 
2.17.1

I have tested with the example code on my Raspberry Pi 4 board (4.19 kernel), so it should work.

BTW, make sure /proc/sys/kernel/perf_event_paranoid has value -1, and perf works fine on my board also.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.