diff options
author | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2024-01-08 22:00:24 -0800 |
---|---|---|
committer | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2024-01-10 09:31:08 -0800 |
commit | 8fe04eeb2cbb8c4cf7b6e8d9183fe09a8b2e8d51 (patch) | |
tree | c3c29dfecf57ea78d8de663665a8c4ab53706b6a /gprofng/common/hwcdrv.c | |
parent | e1cab50d2dd3d416662b5399bd80e6311a6ade0e (diff) | |
download | gdb-8fe04eeb2cbb8c4cf7b6e8d9183fe09a8b2e8d51.zip gdb-8fe04eeb2cbb8c4cf7b6e8d9183fe09a8b2e8d51.tar.gz gdb-8fe04eeb2cbb8c4cf7b6e8d9183fe09a8b2e8d51.tar.bz2 |
gprofng: 31123 improvements to hardware event implementation
Our hardware counter profiling is based on perf_event_open().
Our HWC tables are absent for new machines.
I have added HWC tables for the following events: PERF_TYPE_HARDWARE,
PERF_TYPE_SOFTWARE, PERF_TYPE_HW_CACHE. Other events require additional fixes.
Did a little cleaning: marked the symbols as static, used Stringbuilder,
created a function to read /proc/cpuinfo.
gprofng/ChangeLog
2024-01-08 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
PR gprofng/31123
* common/core_pcbe.c: Mark the symbols as static. Add events_generic[].
* common/hwc_cpus.h: Declare a new function read_cpuinfo.
* common/hwcdrv.c: Add a new parameter in init_perf_event().
* common/hwcentry.h: Add use_perf_event_type in Hwcentry.
* common/hwcfuncs.c (process_data_descriptor): Read use_perf_event_type,
type, config.
* common/hwctable.c: Add a new HWC table generic_list[].
* common/opteron_pcbe.c (opt_pcbe_init): Accept AMD machines.
* src/collctrl.cc: Use StringBuilder in Coll_Ctrl::build_data_desc().
Add a new function read_cpuinfo.
Diffstat (limited to 'gprofng/common/hwcdrv.c')
-rw-r--r-- | gprofng/common/hwcdrv.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/gprofng/common/hwcdrv.c b/gprofng/common/hwcdrv.c index 29a0e17..2d549b0 100644 --- a/gprofng/common/hwcdrv.c +++ b/gprofng/common/hwcdrv.c @@ -675,26 +675,21 @@ dump_perf_event_attr (struct perf_event_attr *at) } static void -init_perf_event (struct perf_event_attr *hw, uint64_t event, uint64_t period) +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); // fwd/bwd compat - -#if defined(__i386__) || defined(__x86_64) - //note: Nehalem/Westmere OFFCORE_RESPONSE in upper 32 bits - hw->config = event; - hw->type = PERF_TYPE_RAW; // hw/sw/trace/raw... -#elif defined(__aarch64__) - hw->type = (event >> 24) & 7; - hw->config = event & 0xff; -#elif defined(sparc) - //SPARC needs to be shifted up 16 bits - hw->config = (event & 0xFFFF) << 16; // uint64_t event - uint64_t regs = (event >> 20) & 0xf; // see sparc_pcbe.c - hw->config |= regs << 4; // for M8, supported PICs need to be placed at bits [7:4] - hw->type = PERF_TYPE_RAW; // hw/sw/trace/raw... -#endif - + hw->size = sizeof (struct perf_event_attr); + if (hwce && hwce->use_perf_event_type) + { + hw->config = hwce->config; + hw->type = hwce->type; + } + else + { // backward compatibility. The old interface had no 'hwce' argument. + hw->config = event; + hw->type = PERF_TYPE_RAW; // hw/sw/trace/raw... + } hw->sample_period = period; hw->sample_type = PERF_SAMPLE_IP | // PERF_SAMPLE_TID | @@ -858,7 +853,7 @@ hdrv_pcl_internal_open () perf_event_def_t tmp_event_def; memset (&tmp_event_def, 0, sizeof (tmp_event_def)); struct perf_event_attr *pe_attr = &tmp_event_def.hw; - init_perf_event (pe_attr, 0, 0); + init_perf_event (pe_attr, 0, 0, NULL); pe_attr->type = PERF_TYPE_HARDWARE; // specify abstracted HW event pe_attr->config = PERF_COUNT_HW_INSTRUCTIONS; // specify abstracted insts int hwc_fd = perf_event_open (pe_attr, @@ -1283,7 +1278,7 @@ hwcdrv_create_counters (unsigned hwcdef_cnt, Hwcentry *hwcdef) glb_event_def->min_time = hwcdef[idx].min_time; glb_event_def->name = strdup (hwcdef[idx].name); // memory leak??? very minor init_perf_event (&glb_event_def->hw, glb_event_def->eventsel, - glb_event_def->counter_preload); + glb_event_def->counter_preload, hwcdef + idx); TprintfT (DBG_LT1, "hwcdrv: create_counters: pic=%u name='%s' interval=%lld" "(min_time=%lld): reg_num=0x%x eventsel=0x%llx ireset=%lld usr=%lld sys=%lld\n", idx, hwcdef[idx].int_name, (long long) glb_event_def->counter_preload, |