diff options
author | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2024-07-07 19:44:46 -0700 |
---|---|---|
committer | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2024-07-09 10:50:05 -0700 |
commit | 971ae1844e7c105cff3699ad69dfed31810ef8e4 (patch) | |
tree | a6c2e77232876ba0d7dc1f5b5b5bafadbc1eb87c /gprofng/common | |
parent | 604b972e61452801757f5c824e58a6c6c3a537d1 (diff) | |
download | binutils-971ae1844e7c105cff3699ad69dfed31810ef8e4.zip binutils-971ae1844e7c105cff3699ad69dfed31810ef8e4.tar.gz binutils-971ae1844e7c105cff3699ad69dfed31810ef8e4.tar.bz2 |
gprofng: add hardware counters for Intel Ice Lake processor
gprofng/ChangeLog
2024-07-07 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>.
* common/hwc_cpus.h: New constant for Intel Ice Lake processor.
* common/hwcdrv.c: Add a new argument to hwcfuncs_get_x86_eventsel.
Set config1 in perf_event_attr. Remove the use of memset.
* common/core_pcbe.c (core_pcbe_get_eventnum): Return 0.
* common/hwcentry.h: Add config1.
* src/collctrl.cc (Coll_Ctrl::build_data_desc):Set config1.
* common/hwcfuncs.c (process_data_descriptor): Set config1.
* common/hwctable.c: Add the hwc table for Intel Ice Lake processor.
* src/hwc_intel_icelake.h: New file.
Diffstat (limited to 'gprofng/common')
-rw-r--r-- | gprofng/common/core_pcbe.c | 3 | ||||
-rw-r--r-- | gprofng/common/hwc_cpus.h | 1 | ||||
-rw-r--r-- | gprofng/common/hwcdrv.c | 32 | ||||
-rw-r--r-- | gprofng/common/hwcentry.h | 1 | ||||
-rw-r--r-- | gprofng/common/hwcfuncs.c | 6 | ||||
-rw-r--r-- | gprofng/common/hwctable.c | 12 |
6 files changed, 37 insertions, 18 deletions
diff --git a/gprofng/common/core_pcbe.c b/gprofng/common/core_pcbe.c index 805bd14..45470d2 100644 --- a/gprofng/common/core_pcbe.c +++ b/gprofng/common/core_pcbe.c @@ -3017,8 +3017,7 @@ core_pcbe_get_eventnum (const char *eventname, uint_t pmc, eventsel_t *eventnum, return 0; } } - *eventnum = (eventsel_t) - 1; - return -1; + return 0; } static hdrv_pcbe_api_t hdrv_pcbe_core_api = { diff --git a/gprofng/common/hwc_cpus.h b/gprofng/common/hwc_cpus.h index 59052a0..3d84391 100644 --- a/gprofng/common/hwc_cpus.h +++ b/gprofng/common/hwc_cpus.h @@ -107,6 +107,7 @@ extern cpu_info_t *read_cpuinfo(); #define CPC_INTEL_HASWELL 2060 #define CPC_INTEL_BROADWELL 2070 #define CPC_INTEL_SKYLAKE 2080 +#define CPC_INTEL_ICELAKE 2081 #define CPC_INTEL_UNKNOWN 2499 #define CPC_AMD_K8C 2500 /* Opteron, Athlon... */ #define CPC_AMD_FAM_10H 2501 /* Barcelona, Shanghai... */ diff --git a/gprofng/common/hwcdrv.c b/gprofng/common/hwcdrv.c index 0b4cfc3..aaf3acd 100644 --- a/gprofng/common/hwcdrv.c +++ b/gprofng/common/hwcdrv.c @@ -215,29 +215,29 @@ set_x86_attr_bits (eventsel_t *result_mask, eventsel_t evnt_valid_umask, } static int -hwcfuncs_get_x86_eventsel (unsigned int regno, const char *int_name, +hwcfuncs_get_x86_eventsel (Hwcentry *h, eventsel_t *return_event, uint_t *return_pmc_sel) { hwcfuncs_attr_t attrs[HWCFUNCS_MAX_ATTRS + 1]; unsigned nattrs = 0; char *nameOnly = NULL; - eventsel_t evntsel = 0; // event number + eventsel_t evntsel = h->config; eventsel_t evnt_valid_umask = 0; uint_t pmc_sel = 0; int rc = -1; *return_event = 0; *return_pmc_sel = 0; - void *attr_mem = hwcfuncs_parse_attrs (int_name, attrs, HWCFUNCS_MAX_ATTRS, + void *attr_mem = hwcfuncs_parse_attrs (h->int_name, attrs, HWCFUNCS_MAX_ATTRS, &nattrs, NULL); if (!attr_mem) { logerr (GTXT ("out of memory, could not parse attributes\n")); return -1; } - hwcfuncs_parse_ctr (int_name, NULL, &nameOnly, NULL, NULL, NULL); + hwcfuncs_parse_ctr (h->int_name, NULL, &nameOnly, NULL, NULL, NULL); /* look up evntsel */ - if (myperfctr_get_x86_eventnum (nameOnly, regno, + if (myperfctr_get_x86_eventnum (nameOnly, h->reg_num, &evntsel, &evnt_valid_umask, &pmc_sel)) { logerr (GTXT ("counter `%s' is not valid\n"), nameOnly); @@ -335,6 +335,7 @@ typedef struct hrtime_t min_time; // minimum time we're targeting between events char *name; } perf_event_def_t; +static perf_event_def_t event_def_0; typedef struct { // runtime state of perf_event buffer @@ -601,11 +602,17 @@ static void init_perf_event (struct perf_event_attr *hw, uint64_t event, uint64_t period, Hwcentry *hwce) { - memset (hw, 0, sizeof (struct perf_event_attr)); - hw->size = sizeof (struct perf_event_attr); + static struct perf_event_attr perf_event_attr_0 = { + .size = sizeof (struct perf_event_attr), + .disabled = 1, /* off by default */ + .exclude_hv = 1, + .wakeup_events = 1 /* wakeup every n events */ + }; + *hw = perf_event_attr_0; if (hwce && hwce->use_perf_event_type) { hw->config = hwce->config; + hw->config1 = hwce->config1; hw->type = hwce->type; } else @@ -632,13 +639,10 @@ init_perf_event (struct perf_event_attr *hw, uint64_t event, uint64_t period, // PERF_FORMAT_ID | // PERF_FORMAT_GROUP | 0; - hw->disabled = 1; /* off by default */ // Note: the following override config.priv bits! hw->exclude_user = (event & (1 << 16)) == 0; /* don't count user */ hw->exclude_kernel = (event & (1 << 17)) == 0; /* ditto kernel */ - hw->exclude_hv = 1; /* ditto hypervisor */ - hw->wakeup_events = 1; /* wakeup every n events */ dump_perf_event_attr (hw); } @@ -773,8 +777,7 @@ hdrv_pcl_internal_open () } // determine if PCL is available - perf_event_def_t tmp_event_def; - memset (&tmp_event_def, 0, sizeof (tmp_event_def)); + perf_event_def_t tmp_event_def = event_def_0; struct perf_event_attr *pe_attr = &tmp_event_def.hw; init_perf_event (pe_attr, 0, 0, NULL); pe_attr->type = PERF_TYPE_HARDWARE; // specify abstracted HW event @@ -1186,11 +1189,10 @@ hwcdrv_create_counters (unsigned hwcdef_cnt, Hwcentry *hwcdef) for (unsigned idx = 0; idx < hwcdef_cnt; idx++) { perf_event_def_t *glb_event_def = &global_perf_event_def[idx]; - memset (glb_event_def, 0, sizeof (perf_event_def_t)); + *glb_event_def = event_def_0; unsigned int pmc_sel; eventsel_t evntsel; - if (hwcfuncs_get_x86_eventsel (hwcdef[idx].reg_num, - hwcdef[idx].int_name, &evntsel, &pmc_sel)) + if (hwcfuncs_get_x86_eventsel (hwcdef + idx, &evntsel, &pmc_sel)) { TprintfT (0, "hwcdrv: ERROR: hwcfuncs_get_x86_eventsel() failed\n"); return HWCFUNCS_ERROR_HWCARGS; diff --git a/gprofng/common/hwcentry.h b/gprofng/common/hwcentry.h index 946356e..b2ab8b9 100644 --- a/gprofng/common/hwcentry.h +++ b/gprofng/common/hwcentry.h @@ -118,6 +118,7 @@ extern "C" unsigned int use_perf_event_type : 16; /* Set 1 to use two fields below */ unsigned int type : 16; /* Type of perf_event_attr */ long long config; /* perf_event_type -specific configuration */ + long long config1; /* perf_event_type -specific configuration */ int sort_order; /* "tag" to associate experiment record with HWC def */ hrtime_t min_time; /* target minimum time between overflow events. 0 is off. See HWCTIME_* macros */ hrtime_t min_time_default; /* if min_time==HWCTIME_AUTO, use this value instead. 0 is off. */ diff --git a/gprofng/common/hwcfuncs.c b/gprofng/common/hwcfuncs.c index e6448a9..750db10 100644 --- a/gprofng/common/hwcfuncs.c +++ b/gprofng/common/hwcfuncs.c @@ -293,6 +293,12 @@ process_data_descriptor (const char *defstring) err = HWCFUNCS_ERROR_HWCARGS; break; } + hwcdef[idx].config1 = strtol (dsp, &dsp, 0); + if (*dsp++ != ':') + { + err = HWCFUNCS_ERROR_HWCARGS; + break; + } /* name */ name = dsp; diff --git a/gprofng/common/hwctable.c b/gprofng/common/hwctable.c index b3ccb36..0baf63b 100644 --- a/gprofng/common/hwctable.c +++ b/gprofng/common/hwctable.c @@ -1304,6 +1304,7 @@ static Hwcentry generic_list[] = { #include "hwc_amd_zen3.h" #include "hwc_amd_zen4.h" +#include "hwc_intel_icelake.h" /* structure defining the counters for a CPU type */ typedef struct @@ -1343,6 +1344,7 @@ static cpu_list_t cputabs[] = { "insts,,cycles,,l3m,,dtlbm", 0}}, {CPC_INTEL_SKYLAKE, intelSkylakeList, {"insts,,cycles,,+l2m_latency,,dtlbm_stall", "insts,,cycles,,l2m_stall,,dtlbm_stall", 0}}, + {CPC_INTEL_ICELAKE, intelIcelakeList, {"insts,,cycles,,dTLB-load-misses", 0}}, {CPC_INTEL_UNKNOWN, intelLinuxUnknown, {"cycles,,insts,,llm", "user_time,,system_time,,cycles,,insts,,llm", 0}}, {CPC_INTEL_ATOM, intelAtomList, {"insts", 0}}, @@ -1827,7 +1829,7 @@ setup_cpc_general (int skip_hwc_test) hwcdrv->hwcdrv_get_info (&cpcx_cpuver, &cpcx_cciname, &cpcx_npics, &cpcx_docref, &cpcx_support_bitmask); - /* Fix cpcx_cpuver for new Zen machines */ + /* Fix cpcx_cpuver for new Zen and Intel machines */ cpu_info_t *cpu_p = read_cpuinfo (); if (strcmp (cpu_p->cpu_vendorstr, "AuthenticAMD") == 0) { @@ -1846,6 +1848,14 @@ setup_cpc_general (int skip_hwc_test) break; } } + else if (strcmp (cpu_p->cpu_vendorstr, "GenuineIntel") == 0) + { + if (cpu_p->cpu_family == 6) + { + if (cpu_p->cpu_model == 106) + cpcx_cpuver = CPC_INTEL_ICELAKE; + } + } #ifdef DISALLOW_PENTIUM_PRO_MMX_7007575 if (cpcx_cpuver == CPC_PENTIUM_PRO_MMX) |