aboutsummaryrefslogtreecommitdiff
path: root/gprofng/common/hwcdrv.c
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2024-01-08 22:00:24 -0800
committerVladimir Mezentsev <vladimir.mezentsev@oracle.com>2024-01-10 09:31:08 -0800
commit8fe04eeb2cbb8c4cf7b6e8d9183fe09a8b2e8d51 (patch)
treec3c29dfecf57ea78d8de663665a8c4ab53706b6a /gprofng/common/hwcdrv.c
parente1cab50d2dd3d416662b5399bd80e6311a6ade0e (diff)
downloadgdb-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.c35
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,