Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
libpfm
thunderx2-uncore-support.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File thunderx2-uncore-support.patch of Package libpfm
From: Shay Gal-On <sgalon@marvell.com> Date: Wed Oct 23 18:58:03 2019 -0700 Subject: ThunderX2 uncore support Git-commit: 0b050ca9ba2a2bf74f87fa3a8b4ed8aec9d1dfa8 References: jsc#SLE-10000 Signed-off-by: Tony Jones <tonyj@suse.de> X-Info: adjust for context, no 98218490 (CascadeLake X core PMU) ThunderX2 uncore support This patch adds ThundeX2 uncore PMUs support. The following uncore PMUs are added: - tx2_llc0, tx2_llc1 (last level cache) - tx2_dmc0, tx2_dmc1 (memory controller) Based on documentation available at: https://www.marvell.com/documents/hrur6mybdvk5uki1w0z7/ Signed-off-by: Shay Gal-On <sgalon@marvell.com> diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h index 09c673d..20d5feb 100644 --- a/include/perfmon/pfmlib.h +++ b/include/perfmon/pfmlib.h @@ -546,6 +546,11 @@ typedef enum { PFM_PMU_INTEL_KNM_UNC_UBOX, /* Intel Knights Mill Ubox uncore */ PFM_PMU_INTEL_KNM_UNC_M2PCIE, /* Intel Knights Mill M2PCIe uncore */ PFM_PMU_ARM_THUNDERX2, /* Cavium ThunderX2 */ + + PFM_PMU_ARM_THUNDERX2_DMC0, /* Cavium ThunderX2 DMC unit 0 uncore */ + PFM_PMU_ARM_THUNDERX2_DMC1, /* Cavium ThunderX2 DMC unit 1 uncore */ + PFM_PMU_ARM_THUNDERX2_LLC0, /* Cavium ThunderX2 LLC unit 0 uncore */ + PFM_PMU_ARM_THUNDERX2_LLC1, /* Cavium ThunderX2 LLC unit 1 uncore */ /* MUST ADD NEW PMU MODELS HERE */ PFM_PMU_MAX /* end marker */ diff --git a/lib/Makefile b/lib/Makefile index 2eb3ebb..f45515d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -188,7 +188,7 @@ SRCS += pfmlib_arm_perf_event.c endif INCARCH = $(INC_ARM64) -SRCS += pfmlib_arm.c pfmlib_arm_armv8.c +SRCS += pfmlib_arm.c pfmlib_arm_armv8.c pfmlib_tx2_unc_perf_event.c CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM64 endif diff --git a/lib/events/arm_cavium_tx2_events.h b/lib/events/arm_cavium_tx2_events.h index 198d33d..18d8931 100644 --- a/lib/events/arm_cavium_tx2_events.h +++ b/lib/events/arm_cavium_tx2_events.h @@ -835,3 +835,64 @@ static const arm_entry_t arm_thunderx2_pe[]={ .desc = "Scu hwpf next line requests generated" }, }; + +#define ARM_TX2_CORE_EVENT_COUNT (sizeof(arm_thunderx2_pe)/sizeof(arm_entry_t)) + +/* L3C event IDs */ +#define L3_EVENT_READ_REQ 0xD +#define L3_EVENT_WRITEBACK_REQ 0xE +#define L3_EVENT_EVICT_REQ 0x13 +#define L3_EVENT_READ_HIT 0x17 +#define L3_EVENT_MAX 0x18 + +/* DMC event IDs */ +#define DMC_EVENT_COUNT_CYCLES 0x1 +#define DMC_EVENT_WRITE_TXNS 0xB +#define DMC_EVENT_DATA_TRANSFERS 0xD +#define DMC_EVENT_READ_TXNS 0xF +#define DMC_EVENT_MAX 0x10 + +static const arm_entry_t arm_thunderx2_unc_dmc_pe[]={ + {.name = "UNC_DMC_READS", + .modmsk = ARMV8_ATTRS, + .code = DMC_EVENT_READ_TXNS, + .desc = "Memory read transactions" + }, + {.name = "UNC_DMC_WRITES", + .modmsk = ARMV8_ATTRS, + .code = DMC_EVENT_WRITE_TXNS, + .desc = "Memory write transactions" + }, +}; + +#define ARM_TX2_CORE_DMC_COUNT (sizeof(arm_thunderx2_unc_dmc_pe)/sizeof(arm_entry_t)) + +static const arm_entry_t arm_thunderx2_unc_llc_pe[]={ + {.name = "UNC_LLC_READ", + .modmsk = ARMV8_ATTRS, + .code = L3_EVENT_READ_REQ, + .desc = "Read requests to LLC" + }, + {.name = "UNC_LLC_EVICT", + .modmsk = ARMV8_ATTRS, + .code = L3_EVENT_EVICT_REQ, + .desc = "Evict requests to LLC" + }, + {.name = "UNC_LLC_READ_HIT", + .modmsk = ARMV8_ATTRS, + .code = L3_EVENT_READ_HIT, + .desc = "Read requests to LLC which hit" + }, + {.name = "UNC_LLC_WB", + .modmsk = ARMV8_ATTRS, + .code = L3_EVENT_WRITEBACK_REQ, + .desc = "Writeback requests to LLC" + } +}; + +#define ARM_TX2_CORE_LLC_COUNT (sizeof(arm_thunderx2_unc_llc_pe)/sizeof(arm_entry_t)) +//Uncore accessor functions +int +pfm_tx2_unc_get_event_encoding(void *this, pfmlib_event_desc_t *e); +int +pfm_tx2_unc_get_perf_encoding(void *this, pfmlib_event_desc_t *e); diff --git a/lib/pfmlib_arm_armv8.c b/lib/pfmlib_arm_armv8.c index 0a3313f..35ff70f 100644 --- a/lib/pfmlib_arm_armv8.c +++ b/lib/pfmlib_arm_armv8.c @@ -203,3 +203,58 @@ pfmlib_pmu_t arm_thunderx2_support={ .get_event_nattrs = pfm_arm_get_event_nattrs, }; +// For uncore, each socket has a separate perf name, otherwise they are the same, use macro + +#define DEFINE_TX2_DMC(n) \ +pfmlib_pmu_t arm_thunderx2_dmc##n##_support={ \ + .desc = "Cavium ThunderX2 Node"#n" DMC", \ + .name = "tx2_dmc"#n, \ + .perf_name = "uncore_dmc_"#n, \ + .pmu = PFM_PMU_ARM_THUNDERX2_DMC##n, \ + .pme_count = LIBPFM_ARRAY_SIZE(arm_thunderx2_unc_dmc_pe), \ + .type = PFM_PMU_TYPE_UNCORE, \ + .pe = arm_thunderx2_unc_dmc_pe, \ + .pmu_detect = pfm_arm_detect_thunderx2, \ + .max_encoding = 1, \ + .num_cntrs = 4, \ + .get_event_encoding[PFM_OS_NONE] = pfm_tx2_unc_get_event_encoding, \ + PFMLIB_ENCODE_PERF(pfm_tx2_unc_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, \ +}; + +DEFINE_TX2_DMC(0); +DEFINE_TX2_DMC(1); + +#define DEFINE_TX2_LLC(n) \ +pfmlib_pmu_t arm_thunderx2_llc##n##_support={ \ + .desc = "Cavium ThunderX2 node "#n" LLC", \ + .name = "tx2_llc"#n, \ + .perf_name = "uncore_l3c_"#n, \ + .pmu = PFM_PMU_ARM_THUNDERX2_LLC##n, \ + .pme_count = LIBPFM_ARRAY_SIZE(arm_thunderx2_unc_llc_pe), \ + .type = PFM_PMU_TYPE_UNCORE, \ + .pe = arm_thunderx2_unc_llc_pe, \ + .pmu_detect = pfm_arm_detect_thunderx2, \ + .max_encoding = 1, \ + .num_cntrs = 4, \ + .get_event_encoding[PFM_OS_NONE] = pfm_tx2_unc_get_event_encoding, \ + PFMLIB_ENCODE_PERF(pfm_tx2_unc_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, \ +}; + +DEFINE_TX2_LLC(0); +DEFINE_TX2_LLC(1); diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c index 2b6cbb4..8314d4b 100644 --- a/lib/pfmlib_common.c +++ b/lib/pfmlib_common.c @@ -490,6 +490,10 @@ static pfmlib_pmu_t *pfmlib_pmus[]= &arm_cortex_a53_support, &arm_xgene_support, &arm_thunderx2_support, + &arm_thunderx2_dmc0_support, + &arm_thunderx2_dmc1_support, + &arm_thunderx2_llc0_support, + &arm_thunderx2_llc1_support, #endif #ifdef CONFIG_PFMLIB_ARCH_S390X diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h index b0070a6..cb83f43 100644 --- a/lib/pfmlib_priv.h +++ b/lib/pfmlib_priv.h @@ -644,7 +644,13 @@ extern pfmlib_pmu_t arm_qcom_krait_support; extern pfmlib_pmu_t arm_cortex_a57_support; extern pfmlib_pmu_t arm_cortex_a53_support; extern pfmlib_pmu_t arm_xgene_support; + extern pfmlib_pmu_t arm_thunderx2_support; +extern pfmlib_pmu_t arm_thunderx2_dmc0_support; +extern pfmlib_pmu_t arm_thunderx2_dmc1_support; +extern pfmlib_pmu_t arm_thunderx2_llc0_support; +extern pfmlib_pmu_t arm_thunderx2_llc1_support; + extern pfmlib_pmu_t mips_74k_support; extern pfmlib_pmu_t s390x_cpum_cf_support; extern pfmlib_pmu_t s390x_cpum_sf_support; diff --git a/lib/pfmlib_tx2_unc_perf_event.c b/lib/pfmlib_tx2_unc_perf_event.c new file mode 100644 index 0000000..1a04e1d --- /dev/null +++ b/lib/pfmlib_tx2_unc_perf_event.c @@ -0,0 +1,139 @@ +#include <sys/types.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <limits.h> + +/* private headers */ +#include "pfmlib_priv.h" +#include "pfmlib_perf_event_priv.h" +#include "pfmlib_arm_priv.h" + +typedef union { + uint64_t val; + struct { + unsigned long unc_event:8; /* event code */ + unsigned long unc_umask:8; /* unit mask */ + unsigned long unc_res1:1; /* reserved */ + unsigned long unc_rst:1; /* reset */ + unsigned long unc_edge:1; /* edge detect */ + unsigned long unc_res2:3; /* reserved */ + unsigned long unc_en:1; /* enable */ + unsigned long unc_inv:1; /* invert counter mask */ + unsigned long unc_thres:8; /* counter mask */ + unsigned long unc_res3:32; /* reserved */ + } com; /* covers common fields for DMC/L3C */ +} tx2_unc_data_t; + +static void +display_reg(void *this, pfmlib_event_desc_t *e, tx2_unc_data_t reg); +static void +display_com(void *this, pfmlib_event_desc_t *e, void *val); +static int +find_pmu_type_by_name(const char *name); + +int +pfm_tx2_unc_get_event_encoding(void *this, pfmlib_event_desc_t *e) +{ + //from pe field in for the uncore, get the array with all the event defs + const arm_entry_t *event_list = this_pe(this); + tx2_unc_data_t reg; + //get code for the event from the table + reg.val = event_list[e->event].code; + //pass the data back to the caller + e->codes[0] = reg.val; + e->count = 1; + evt_strcat(e->fstr, "%s", event_list[e->event].name); + display_reg(this, e, reg); + return PFM_SUCCESS; +} + +int +pfm_tx2_unc_get_perf_encoding(void *this, pfmlib_event_desc_t *e) +{ + pfmlib_pmu_t *pmu = this; + struct perf_event_attr *attr = e->os_data; + tx2_unc_data_t reg; + int ret; + + if (!pmu->get_event_encoding[PFM_OS_NONE]) + return PFM_ERR_NOTSUPP; + + ret = pmu->get_event_encoding[PFM_OS_NONE](this, e); + if (ret != PFM_SUCCESS) + return ret; + //get pmu type to probe + ret = find_pmu_type_by_name(pmu->perf_name); + if (ret < 0) + return ret; + + attr->type = ret; + //get code to provide to the uncore pmu probe + reg.val = e->codes[0]; + attr->config = reg.val; + + // if needed, can use attr->config1 or attr->config2 for extra info from event structure defines e->codes[i] + + // uncore measures at all priv levels + attr->exclude_hv = 0; + attr->exclude_kernel = 0; + attr->exclude_user = 0; + + return PFM_SUCCESS; +} + + +static void +display_reg(void *this, pfmlib_event_desc_t *e, tx2_unc_data_t reg) +{ + pfmlib_pmu_t *pmu = this; + if (pmu->display_reg) + pmu->display_reg(this, e, ®); + else + display_com(this, e, ®); +} + +static void +display_com(void *this, pfmlib_event_desc_t *e, void *val) +{ + const arm_entry_t *pe = this_pe(this); + tx2_unc_data_t *reg = val; + + __pfm_vbprintf("[UNC=0x%"PRIx64" event=0x%x umask=0x%x en=%d " + "inv=%d edge=%d thres=%d] %s\n", + reg->val, + reg->com.unc_event, + reg->com.unc_umask, + reg->com.unc_en, + reg->com.unc_inv, + reg->com.unc_edge, + reg->com.unc_thres, + pe[e->event].name); +} + +static int +find_pmu_type_by_name(const char *name) +{ + char filename[PATH_MAX]; + FILE *fp; + int ret, type; + + if (!name) + return PFM_ERR_NOTSUPP; + + sprintf(filename, "/sys/bus/event_source/devices/%s/type", name); + + fp = fopen(filename, "r"); + if (!fp) + return PFM_ERR_NOTSUPP; + + ret = fscanf(fp, "%d", &type); + if (ret != 1) + type = PFM_ERR_NOTSUPP; + + fclose(fp); + + return type; +} + diff --git a/tests/validate_arm64.c b/tests/validate_arm64.c index f7f021a..35eb6ef 100644 --- a/tests/validate_arm64.c +++ b/tests/validate_arm64.c @@ -177,6 +177,12 @@ static const test_event_t arm64_test_events[]={ .codes[0] = 0x8000008, .fstr = "arm_thunderx2::INST_RETIRED:k=1:u=1:hv=0", }, + { SRC_LINE, + .name = "tx2_dmc1::UNC_DMC_READS", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0xf, + }, }; #define NUM_TEST_EVENTS (int)(sizeof(arm64_test_events)/sizeof(test_event_t))
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor