commit 77ee6b54f4080ca27b7efcb4c91679d0f1e090b5 Author: Anthony Castaldo Date: Fri Jan 24 10:25:36 2020 -0500 New libpfm4 contains "aliased" pmus for backward compatibility, amd64_fam17h == amd64_fam17h_zen1; this causes us to put BOTH pmus into the PMUs supported string and double the events in native_avail. This update recognizes when aliases exist (the names must be hard-coded) and uses only one of the most recent name. diff --git a/src/components/perf_event/pe_libpfm4_events.c b/src/components/perf_event/pe_libpfm4_events.c index 3b5f8d13f..3262608cd 100644 --- a/src/components/perf_event/pe_libpfm4_events.c +++ b/src/components/perf_event/pe_libpfm4_events.c @@ -31,6 +31,9 @@ // used to step through the attributes when enumerating events static int attr_idx; +/* alias flags to handle amd_fam17h, amd_fam17h_zen1 both present PMUs*/ +static int amd64_fam17h_zen1_present = 0; + /** @class find_existing_event * @brief looks up an event, returns it if it exists * @@ -482,7 +485,13 @@ static struct native_event_t *allocate_native_event( * * @returns returns a libpfm event number * @retval PAPI_ENOEVENT Could not find an event - * + * Operational note: _pe_libpfm4_init() must be called first to set + * flags for synonymous PMUs. At this writing only + * amd64_fam17h_zen1_present is defined. + * Operational note: We indirectly return the pmu_idx within the + * event data; the calling code uses that to set + * pmu_idx for subsequent calls. All we do is find + * the next valid pmu, if any. */ static int @@ -511,6 +520,12 @@ get_first_event_next_pmu(int pmu_idx, int pmu_type) break; } + if ((ret==PFM_SUCCESS) && amd64_fam17h_zen1_present && strcmp(pinfo.name, "amd64_fam17h") == 0) { + /* Skip as if invalid; we want the PMU amd64_fam17h_zen1 instead. */ + pmu_idx++; + continue; + } + if ((ret==PFM_SUCCESS) && pmu_is_present_and_right_type(&pinfo,pmu_type)) { pidx=pinfo.first_event; @@ -1159,6 +1174,35 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx, event_table->default_pmu.size = sizeof(pfm_pmu_info_t); retval=pfm_get_pmu_info(0, &(event_table->default_pmu)); + SUBDBG("Prescan for aliases.") + /* We have to see if we have aliases in there as separate PMUs, */ + /* we don't want both PMUs with all the events duplicated. */ + /* For aliases, either is valid alone, but if both are present */ + /* specify a preference in the code. */ + /* Alias: amd64_fam17h_zen1 over amd64_fam17h. */ + /* Alias flags are static ints global to this file. */ + i=0; + while(1) { + memset(&pinfo,0,sizeof(pfm_pmu_info_t)); + pinfo.size = sizeof(pfm_pmu_info_t); + retval=pfm_get_pmu_info(i, &pinfo); + + /* We're done if we hit an invalid PMU entry */ + /* We can't check against PFM_PMU_MAX as that might not */ + /* match if libpfm4 is dynamically linked */ + + if (retval==PFM_ERR_INVAL) { + break; + } + + if ( (retval==PFM_SUCCESS) && (pinfo.name != NULL) && + (pmu_is_present_and_right_type(&pinfo,pmu_type)) && + (strcmp(pinfo.name,"amd64_fam17h_zen1") == 0) ) { + amd64_fam17h_zen1_present = 1; + } + i++; + } + SUBDBG("Detected pmus:\n"); i=0; while(1) { @@ -1177,6 +1221,12 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx, if ((retval==PFM_SUCCESS) && (pinfo.name != NULL) && (pmu_is_present_and_right_type(&pinfo,pmu_type))) { + /* skip if it is amd64_fam17h and zen1 is also present. */ + if (strcmp(pinfo.name,"amd64_fam17h") == 0 && amd64_fam17h_zen1_present) { + i++; + continue; + } + SUBDBG("\t%d %s %s %d\n",i, pinfo.name,pinfo.desc,pinfo.type); @@ -1193,11 +1243,9 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx, /* Hack to have "default core" PMU */ if ( (pinfo.type==PFM_PMU_TYPE_CORE) && strcmp(pinfo.name,"ix86arch")) { - - SUBDBG("\t %s is default\n",pinfo.name); - memcpy(&(event_table->default_pmu), - &pinfo,sizeof(pfm_pmu_info_t)); - found_default++; + memcpy(&(event_table->default_pmu), + &pinfo,sizeof(pfm_pmu_info_t)); + found_default++; } } commit 79fe2a025afb8acb317032030c8847c9cbfd0162 Author: Masahiko, Yamada Date: Tue Jan 5 13:45:34 2021 +0900 Get model_string for ARM processor from pfm_get_pmu_info() function On ARM processors, the model_string does not appear in /proc/cpuinfo. Instead of looking at the /proc/cpuinfo information, you can look at the lscpu command information at the following URL:. https://github.com/google/cpu_features/issues/26 http://suihkulokki.blogspot.com/2018/02/making-sense-of-proccpuinfo-on-arm.html The libpfm4 library identifies the ARM processor type from the "CPU implement" and "CPU part" in the /proc/cpuinfo information. The papi library can use the pfm_get_pmu_info() function from the libpfm4 library to obtain a string identifying the ARM processor type. diff --git a/src/components/perf_event/pe_libpfm4_events.c b/src/components/perf_event/pe_libpfm4_events.c index a84819cc0..744851ff0 100644 --- a/src/components/perf_event/pe_libpfm4_events.c +++ b/src/components/perf_event/pe_libpfm4_events.c @@ -1149,6 +1149,7 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx, pfm_err_t retval = PFM_SUCCESS; pfm_pmu_info_t pinfo; + unsigned int strSize; /* allocate the native event structure */ event_table->num_native_events=0; @@ -1247,6 +1248,13 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx, &pinfo,sizeof(pfm_pmu_info_t)); found_default++; } + if ( (pinfo.type==PFM_PMU_TYPE_CORE) && + ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_ARM)) { + if (strlen(_papi_hwi_system_info.hw_info.model_string) == 0) { + strSize = sizeof(_papi_hwi_system_info.hw_info.model_string); + strncpy( _papi_hwi_system_info.hw_info.model_string, pinfo.desc, strSize - 1); + } + } } if (pmu_type==PMU_TYPE_UNCORE) {