diff options
| author | Matt Macy <mmacy@FreeBSD.org> | 2018-08-14 05:18:43 +0000 |
|---|---|---|
| committer | Matt Macy <mmacy@FreeBSD.org> | 2018-08-14 05:18:43 +0000 |
| commit | 81eb4dcf9e0d00972eceeaf61215db5995287498 (patch) | |
| tree | eefb3dffa51f73cff3f604dfa2b4c21125da79ae /lib/libpmc | |
| parent | bb3ba83eeefba8d3e19fd54a450bea57ccd2b8c8 (diff) | |
Notes
Diffstat (limited to 'lib/libpmc')
| -rw-r--r-- | lib/libpmc/libpmc_pmu_util.c | 172 | ||||
| -rw-r--r-- | lib/libpmc/pmu-events/arch/x86/amdfam17h/core.json | 3 | ||||
| -rw-r--r-- | lib/libpmc/pmu-events/arch/x86/amdfam17h/memory.json | 1 | ||||
| -rw-r--r-- | lib/libpmc/pmu-events/arch/x86/mapfile.csv | 6 |
4 files changed, 149 insertions, 33 deletions
diff --git a/lib/libpmc/libpmc_pmu_util.c b/lib/libpmc/libpmc_pmu_util.c index 8900c430009f..7aaf6f2a5b18 100644 --- a/lib/libpmc/libpmc_pmu_util.c +++ b/lib/libpmc/libpmc_pmu_util.c @@ -46,7 +46,14 @@ struct pmu_alias { const char *pa_alias; const char *pa_name; }; -static struct pmu_alias pmu_alias_table[] = { + +typedef enum { + PMU_INVALID, + PMU_INTEL, + PMU_AMD, +} pmu_mfr_t; + +static struct pmu_alias pmu_intel_alias_table[] = { {"UNHALTED_CORE_CYCLES", "CPU_CLK_UNHALTED.THREAD_P_ANY"}, {"UNHALTED-CORE-CYCLES", "CPU_CLK_UNHALTED.THREAD_P_ANY"}, {"LLC_MISSES", "LONGEST_LAT_CACHE.MISS"}, @@ -70,6 +77,40 @@ static struct pmu_alias pmu_alias_table[] = { {NULL, NULL}, }; +static struct pmu_alias pmu_amd_alias_table[] = { + {"UNHALTED_CORE_CYCLES", "ls_not_halted_cyc"}, + {"UNHALTED-CORE-CYCLES", "ls_not_halted_cyc"}, + {NULL, NULL}, +}; + + +static pmu_mfr_t +pmu_events_mfr(void) +{ + char *buf; + size_t s; + pmu_mfr_t mfr; + + if (sysctlbyname("kern.hwpmc.cpuid", (void *)NULL, &s, + (void *)NULL, 0) == -1) + return (PMU_INVALID); + if ((buf = malloc(s + 1)) == NULL) + return (PMU_INVALID); + if (sysctlbyname("kern.hwpmc.cpuid", buf, &s, + (void *)NULL, 0) == -1) { + free(buf); + return (PMU_INVALID); + } + if (strcasestr(buf, "AuthenticAMD") != NULL) + mfr = PMU_AMD; + else if (strcasestr(buf, "GenuineIntel") != NULL) + mfr = PMU_INTEL; + else + mfr = PMU_INVALID; + free(buf); + return (mfr); +} + /* * The Intel fixed mode counters are: * "inst_retired.any", @@ -82,11 +123,23 @@ static struct pmu_alias pmu_alias_table[] = { static const char * pmu_alias_get(const char *name) { + pmu_mfr_t mfr; struct pmu_alias *pa; + struct pmu_alias *pmu_alias_table; + + if ((mfr = pmu_events_mfr()) == PMU_INVALID) + return (name); + if (mfr == PMU_AMD) + pmu_alias_table = pmu_amd_alias_table; + else if (mfr == PMU_INTEL) + pmu_alias_table = pmu_intel_alias_table; + else + return (name); for (pa = pmu_alias_table; pa->pa_alias != NULL; pa++) if (strcasecmp(name, pa->pa_alias) == 0) return (pa->pa_name); + return (name); } @@ -352,59 +405,114 @@ pmc_pmu_print_counter_full(const char *ev) } } -int -pmc_pmu_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm) +static int +pmc_pmu_amd_pmcallocate(const char *event_name __unused, struct pmc_op_pmcallocate *pm, + struct pmu_event_desc *ped) { - const struct pmu_event *pe; - struct pmu_event_desc ped; - struct pmc_md_iap_op_pmcallocate *iap; - int idx, isfixed; + struct pmc_md_amd_op_pmcallocate *amd; - iap = &pm->pm_md.pm_iap; - isfixed = 0; - bzero(iap, sizeof(*iap)); - event_name = pmu_alias_get(event_name); - pm->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); - if ((pe = pmu_event_get(NULL, event_name, &idx)) == NULL) - return (ENOENT); - if (pe->alias && (pe = pmu_event_get(NULL, pe->alias, &idx)) == NULL) - return (ENOENT); - if (pe->event == NULL) - return (ENOENT); - if (pmu_parse_event(&ped, pe->event)) - return (ENOENT); + amd = &pm->pm_md.pm_amd; + amd->pm_amd_config = AMD_PMC_TO_EVENTMASK(ped->ped_event); + if (ped->ped_umask > 0) { + pm->pm_caps |= PMC_CAP_QUALIFIER; + amd->pm_amd_config |= AMD_PMC_TO_UNITMASK(ped->ped_umask); + } + pm->pm_class = PMC_CLASS_K8; + if ((pm->pm_caps & (PMC_CAP_USER|PMC_CAP_SYSTEM)) == 0 || + (pm->pm_caps & (PMC_CAP_USER|PMC_CAP_SYSTEM)) == + (PMC_CAP_USER|PMC_CAP_SYSTEM)) + amd->pm_amd_config |= (AMD_PMC_USR | AMD_PMC_OS); + else if (pm->pm_caps & PMC_CAP_USER) + amd->pm_amd_config |= AMD_PMC_USR; + else if (pm->pm_caps & PMC_CAP_SYSTEM) + amd->pm_amd_config |= AMD_PMC_OS; + if (ped->ped_edge) + amd->pm_amd_config |= AMD_PMC_EDGE; + if (ped->ped_inv) + amd->pm_amd_config |= AMD_PMC_EDGE; + if (pm->pm_caps & PMC_CAP_INTERRUPT) + amd->pm_amd_config |= AMD_PMC_INT; + return (0); +} +static int +pmc_pmu_intel_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm, + struct pmu_event_desc *ped) +{ + struct pmc_md_iap_op_pmcallocate *iap; + int isfixed; + + isfixed = 0; + iap = &pm->pm_md.pm_iap; if (strcasestr(event_name, "UNC_") == event_name || strcasestr(event_name, "uncore") != NULL) { pm->pm_class = PMC_CLASS_UCP; pm->pm_caps |= PMC_CAP_QUALIFIER; - } else if ((ped.ped_umask == -1) || - (ped.ped_event == 0x0 && ped.ped_umask == 0x3)) { + } else if ((ped->ped_umask == -1) || + (ped->ped_event == 0x0 && ped->ped_umask == 0x3)) { pm->pm_class = PMC_CLASS_IAF; } else { pm->pm_class = PMC_CLASS_IAP; pm->pm_caps |= PMC_CAP_QUALIFIER; } - pm->pm_ev = idx; - iap->pm_iap_config |= IAP_EVSEL(ped.ped_event); - if (ped.ped_umask > 0) - iap->pm_iap_config |= IAP_UMASK(ped.ped_umask); - iap->pm_iap_config |= IAP_CMASK(ped.ped_cmask); - iap->pm_iap_rsp = ped.ped_offcore_rsp; + iap->pm_iap_config |= IAP_EVSEL(ped->ped_event); + if (ped->ped_umask > 0) + iap->pm_iap_config |= IAP_UMASK(ped->ped_umask); + iap->pm_iap_config |= IAP_CMASK(ped->ped_cmask); + iap->pm_iap_rsp = ped->ped_offcore_rsp; - iap->pm_iap_config |= (IAP_USR | IAP_OS); - if (ped.ped_edge) + if ((pm->pm_caps & (PMC_CAP_USER|PMC_CAP_SYSTEM)) == 0 || + (pm->pm_caps & (PMC_CAP_USER|PMC_CAP_SYSTEM)) == + (PMC_CAP_USER|PMC_CAP_SYSTEM)) + iap->pm_iap_config |= (IAP_USR | IAP_OS); + else if (pm->pm_caps & PMC_CAP_USER) + iap->pm_iap_config |= IAP_USR; + else if (pm->pm_caps & PMC_CAP_SYSTEM) + iap->pm_iap_config |= IAP_OS; + if (ped->ped_edge) iap->pm_iap_config |= IAP_EDGE; - if (ped.ped_any) + if (ped->ped_any) iap->pm_iap_config |= IAP_ANY; - if (ped.ped_inv) + if (ped->ped_inv) iap->pm_iap_config |= IAP_EDGE; if (pm->pm_caps & PMC_CAP_INTERRUPT) iap->pm_iap_config |= IAP_INT; return (0); } +int +pmc_pmu_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm) +{ + const struct pmu_event *pe; + struct pmu_event_desc ped; + pmu_mfr_t mfr; + int idx = -1; + + if ((mfr = pmu_events_mfr()) == PMU_INVALID) + return (ENOENT); + + bzero(&pm->pm_md, sizeof(pm->pm_md)); + pm->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); + event_name = pmu_alias_get(event_name); + if ((pe = pmu_event_get(NULL, event_name, &idx)) == NULL) + return (ENOENT); + if (pe->alias && (pe = pmu_event_get(NULL, pe->alias, &idx)) == NULL) + return (ENOENT); + assert(idx >= 0); + pm->pm_ev = idx; + + if (pe->event == NULL) + return (ENOENT); + if (pmu_parse_event(&ped, pe->event)) + return (ENOENT); + + if (mfr == PMU_INTEL) + return (pmc_pmu_intel_pmcallocate(event_name, pm, &ped)); + else + return (pmc_pmu_amd_pmcallocate(event_name, pm, &ped)); +} + /* * Ultimately rely on AMD calling theirs the same */ diff --git a/lib/libpmc/pmu-events/arch/x86/amdfam17h/core.json b/lib/libpmc/pmu-events/arch/x86/amdfam17h/core.json index 76517c4f057a..4098ad8cab4b 100644 --- a/lib/libpmc/pmu-events/arch/x86/amdfam17h/core.json +++ b/lib/libpmc/pmu-events/arch/x86/amdfam17h/core.json @@ -3,16 +3,19 @@ "EventName": "ex_ret_instr", "EventCode": "0xc0", "BriefDescription": "Retired Instructions." + "SampleAfterValue": "2000003", }, { "EventName": "ex_ret_cops", "EventCode": "0xc1", "BriefDescription": "The number of uOps retired. This includes all processor activity (instructions, exceptions, interrupts, microcode assists, etc.). The number of events logged per cycle can vary from 0 to 4." + "SampleAfterValue": "2000003", }, { "EventName": "ex_ret_brn", "EventCode": "0xc2", "BriefDescription": "The number of branch instructions retired. This includes all types of architectural control flow changes, including exceptions and interrupts." + "SampleAfterValue": "2000003", }, { "EventName": "ex_ret_brn_misp", diff --git a/lib/libpmc/pmu-events/arch/x86/amdfam17h/memory.json b/lib/libpmc/pmu-events/arch/x86/amdfam17h/memory.json index 094cfda11f5c..8380ba53522b 100644 --- a/lib/libpmc/pmu-events/arch/x86/amdfam17h/memory.json +++ b/lib/libpmc/pmu-events/arch/x86/amdfam17h/memory.json @@ -221,5 +221,6 @@ "EventName": "ls_not_halted_cyc", "EventCode": "0x76", "BriefDescription": "Cycles not in Halt." + "SampleAfterValue": "2000003", } ] diff --git a/lib/libpmc/pmu-events/arch/x86/mapfile.csv b/lib/libpmc/pmu-events/arch/x86/mapfile.csv index 2aeb67b146eb..4657c54cccec 100644 --- a/lib/libpmc/pmu-events/arch/x86/mapfile.csv +++ b/lib/libpmc/pmu-events/arch/x86/mapfile.csv @@ -36,4 +36,8 @@ GenuineIntel-6-2C,v2,westmereep-dp,core GenuineIntel-6-25,v2,westmereep-sp,core GenuineIntel-6-2F,v2,westmereex,core GenuineIntel-6-55,v1,skylakex,core -AuthenticAMD-23-1,v1,amdfam17h,core +AuthenticAMD-23-01,v1,amdfam17h,core +AuthenticAMD-23-02,v1,amdfam17h,core +AuthenticAMD-23-03,v1,amdfam17h,core +AuthenticAMD-23-04,v1,amdfam17h,core +AuthenticAMD-23-05,v1,amdfam17h,core |
