Add aditional counter descriptions to AMD 0x17

Submitted by:	Somalapuram Amaranath
MFC after:	3 days
Differential Revision:	https://reviews.freebsd.org/D17401
This commit is contained in:
Matt Macy 2018-11-04 06:24:27 +00:00
parent 561991144e
commit dacc43df34
6 changed files with 8310 additions and 25 deletions

View File

@ -146,6 +146,8 @@ pmu_alias_get(const char *name)
struct pmu_event_desc {
uint64_t ped_period;
uint64_t ped_offcore_rsp;
uint64_t ped_l3_thread;
uint64_t ped_l3_slice;
uint32_t ped_event;
uint32_t ped_frontend;
uint32_t ped_ldlat;
@ -270,6 +272,10 @@ pmu_parse_event(struct pmu_event_desc *ped, const char *eventin)
ped->ped_ch_mask = strtol(value, NULL, 16);
else if (strcmp(key, "config1") == 0)
ped->ped_config1 = strtol(value, NULL, 16);
else if (strcmp(key, "l3_thread_mask") == 0)
ped->ped_l3_thread = strtol(value, NULL, 16);
else if (strcmp(key, "l3_slice_mask") == 0)
ped->ped_l3_slice = strtol(value, NULL, 16);
else {
debug = getenv("PMUDEBUG");
if (debug != NULL && strcmp(debug, "true") == 0 && value != NULL)
@ -407,33 +413,50 @@ pmc_pmu_print_counter_full(const char *ev)
}
static int
pmc_pmu_amd_pmcallocate(const char *event_name __unused, struct pmc_op_pmcallocate *pm,
pmc_pmu_amd_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm,
struct pmu_event_desc *ped)
{
struct pmc_md_amd_op_pmcallocate *amd;
const struct pmu_event *pe;
int idx = -1;
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;
pe = pmu_event_get(NULL, event_name, &idx);
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;
if (strcmp("l3cache", pe->topic) == 0){
amd->pm_amd_config |= AMD_PMC_TO_EVENTMASK(ped->ped_event);
amd->pm_amd_sub_class = PMC_AMD_SUB_CLASS_L3_CACHE;
amd->pm_amd_config |= AMD_PMC_TO_L3SLICE(ped->ped_l3_slice);
amd->pm_amd_config |= AMD_PMC_TO_L3CORE(ped->ped_l3_thread);
}
else if (strcmp("data fabric", pe->topic) == 0){
amd->pm_amd_config |= AMD_PMC_TO_EVENTMASK_DF(ped->ped_event);
amd->pm_amd_sub_class = PMC_AMD_SUB_CLASS_DATA_FABRIC;
}
else{
amd->pm_amd_config |= AMD_PMC_TO_EVENTMASK(ped->ped_event);
amd->pm_amd_sub_class = PMC_AMD_SUB_CLASS_CORE;
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);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -184,6 +184,8 @@ static struct field {
{ "SampleAfterValue", "period=" },
{ "FCMask", "fc_mask=" },
{ "PortMask", "ch_mask=" },
{ "L3ThreadMask", "l3_thread_mask=" },
{ "L3SliceMask", "l3_slice_mask=" },
{ NULL, NULL }
};

View File

@ -105,7 +105,139 @@ static struct amd_descr amd_pmcdesc[AMD_NPMCS] =
},
.pm_evsel = AMD_PMC_EVSEL_3,
.pm_perfctr = AMD_PMC_PERFCTR_3
}
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_4,
.pm_perfctr = AMD_PMC_PERFCTR_4
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_5,
.pm_perfctr = AMD_PMC_PERFCTR_5
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_L3_0,
.pm_perfctr = AMD_PMC_PERFCTR_EP_L3_0
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_L3_1,
.pm_perfctr = AMD_PMC_PERFCTR_EP_L3_1
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_L3_2,
.pm_perfctr = AMD_PMC_PERFCTR_EP_L3_2
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_L3_3,
.pm_perfctr = AMD_PMC_PERFCTR_EP_L3_3
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_L3_4,
.pm_perfctr = AMD_PMC_PERFCTR_EP_L3_4
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_L3_5,
.pm_perfctr = AMD_PMC_PERFCTR_EP_L3_5
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_DF_0,
.pm_perfctr = AMD_PMC_PERFCTR_EP_DF_0
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_DF_1,
.pm_perfctr = AMD_PMC_PERFCTR_EP_DF_1
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_DF_2,
.pm_perfctr = AMD_PMC_PERFCTR_EP_DF_2
},
{
.pm_descr =
{
.pd_name = "",
.pd_class = -1,
.pd_caps = AMD_PMC_CAPS,
.pd_width = 48
},
.pm_evsel = AMD_PMC_EVSEL_EP_DF_3,
.pm_perfctr = AMD_PMC_PERFCTR_EP_DF_3
}
};
struct amd_event_code_map {
@ -435,7 +567,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm,
const struct pmc_op_pmcallocate *a)
{
int i;
uint32_t allowed_unitmask, caps, config, unitmask;
uint64_t allowed_unitmask, caps, config, unitmask;
enum pmc_event pe;
const struct pmc_descr *pd;
@ -456,6 +588,13 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm,
PMCDBG2(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps);
if((ri >= 0 && ri < 6) && !(a->pm_md.pm_amd.pm_amd_sub_class == PMC_AMD_SUB_CLASS_CORE))
return EINVAL;
if((ri >= 6 && ri < 12) && !(a->pm_md.pm_amd.pm_amd_sub_class == PMC_AMD_SUB_CLASS_L3_CACHE))
return EINVAL;
if((ri >= 12 && ri < 16) && !(a->pm_md.pm_amd.pm_amd_sub_class == PMC_AMD_SUB_CLASS_DATA_FABRIC))
return EINVAL;
if ((pd->pd_caps & caps) != caps)
return EPERM;
if (strlen(pmc_cpuid) != 0) {
@ -556,7 +695,7 @@ amd_release_pmc(int cpu, int ri, struct pmc *pmc)
static int
amd_start_pmc(int cpu, int ri)
{
uint32_t config;
uint64_t config;
struct pmc *pm;
struct pmc_hw *phw;
const struct amd_descr *pd;
@ -636,7 +775,7 @@ static int
amd_intr(struct trapframe *tf)
{
int i, error, retval, cpu;
uint32_t config, evsel, perfctr;
uint64_t config, evsel, perfctr;
struct pmc *pm;
struct amd_cpu *pac;
pmc_value_t v;
@ -688,8 +827,8 @@ amd_intr(struct trapframe *tf)
KASSERT((config & ~AMD_PMC_ENABLE) ==
(pm->pm_md.pm_amd.pm_amd_evsel & ~AMD_PMC_ENABLE),
("[amd,%d] config mismatch reg=0x%x pm=0x%x", __LINE__,
config, pm->pm_md.pm_amd.pm_amd_evsel));
("[amd,%d] config mismatch reg=0x%jx pm=0x%jx", __LINE__,
(uintmax_t)config, (uintmax_t)pm->pm_md.pm_amd.pm_amd_evsel));
wrmsr(evsel, config & ~AMD_PMC_ENABLE);
wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v));

View File

@ -44,9 +44,39 @@
#define AMD_PMC_PERFCTR_1 0xC0010005
#define AMD_PMC_PERFCTR_2 0xC0010006
#define AMD_PMC_PERFCTR_3 0xC0010007
/* CORE */
#define AMD_PMC_EVSEL_4 0xC0010208
#define AMD_PMC_EVSEL_5 0xC001020A
#define AMD_PMC_PERFCTR_4 0xC0010209
#define AMD_PMC_PERFCTR_5 0xC001020B
/* L3 */
#define AMD_PMC_EVSEL_EP_L3_0 0xC0010230
#define AMD_PMC_EVSEL_EP_L3_1 0xC0010232
#define AMD_PMC_EVSEL_EP_L3_2 0xC0010234
#define AMD_PMC_EVSEL_EP_L3_3 0xC0010236
#define AMD_PMC_EVSEL_EP_L3_4 0xC0010238
#define AMD_PMC_EVSEL_EP_L3_5 0xC001023A
#define AMD_PMC_PERFCTR_EP_L3_0 0xC0010231
#define AMD_PMC_PERFCTR_EP_L3_1 0xC0010233
#define AMD_PMC_PERFCTR_EP_L3_2 0xC0010235
#define AMD_PMC_PERFCTR_EP_L3_3 0xC0010237
#define AMD_PMC_PERFCTR_EP_L3_4 0xC0010239
#define AMD_PMC_PERFCTR_EP_L3_5 0xC001023B
/* DF */
#define AMD_PMC_EVSEL_EP_DF_0 0xC0010240
#define AMD_PMC_EVSEL_EP_DF_1 0xC0010242
#define AMD_PMC_EVSEL_EP_DF_2 0xC0010244
#define AMD_PMC_EVSEL_EP_DF_3 0xC0010246
#define AMD_PMC_PERFCTR_EP_DF_0 0xC0010241
#define AMD_PMC_PERFCTR_EP_DF_1 0xC0010243
#define AMD_PMC_PERFCTR_EP_DF_2 0xC0010245
#define AMD_PMC_PERFCTR_EP_DF_3 0xC0010247
#define AMD_NPMCS 16
#define AMD_NPMCS 4
#define AMD_PMC_COUNTERMASK 0xFF000000
#define AMD_PMC_TO_COUNTER(x) (((x) << 24) & AMD_PMC_COUNTERMASK)
@ -57,6 +87,10 @@
#define AMD_PMC_EDGE (1 << 18)
#define AMD_PMC_OS (1 << 17)
#define AMD_PMC_USR (1 << 16)
#define AMD_PMC_L3SLICEMASK (0x000F000000000000)
#define AMD_PMC_L3COREMASK (0xFF00000000000000)
#define AMD_PMC_TO_L3SLICE(x) (((x) << 48) & AMD_PMC_L3SLICEMASK)
#define AMD_PMC_TO_L3CORE(x) (((x) << 56) & AMD_PMC_L3COREMASK)
#define AMD_PMC_UNITMASK_M 0x10
#define AMD_PMC_UNITMASK_O 0x08
@ -70,6 +104,7 @@
#define AMD_PMC_TO_UNITMASK(x) (((x) << 8) & AMD_PMC_UNITMASK)
#define AMD_PMC_TO_EVENTMASK(x) (((x) & 0xFF) | (((uint64_t)(x) & 0xF00) << 24))
#define AMD_PMC_TO_EVENTMASK_DF(x) (((x) & 0xFF) | (((uint64_t)(x) & 0x0F00) << 24)) | (((uint64_t)(x) & 0x3000) << 47)
#define AMD_VALID_BITS (AMD_PMC_COUNTERMASK | AMD_PMC_INVERT | \
AMD_PMC_ENABLE | AMD_PMC_INT | AMD_PMC_PC | AMD_PMC_EDGE | \
AMD_PMC_OS | AMD_PMC_USR | AMD_PMC_UNITMASK | AMD_PMC_EVENTMASK)
@ -84,15 +119,22 @@
#define AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(V) (-(V))
#define AMD_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (-(P))
enum sub_class{
PMC_AMD_SUB_CLASS_CORE,
PMC_AMD_SUB_CLASS_L3_CACHE,
PMC_AMD_SUB_CLASS_DATA_FABRIC
};
struct pmc_md_amd_op_pmcallocate {
uint32_t pm_amd_config;
uint64_t pm_amd_config;
uint32_t pm_amd_sub_class;
};
#ifdef _KERNEL
/* MD extension for 'struct pmc' */
struct pmc_md_amd_pmc {
uint32_t pm_amd_evsel;
uint64_t pm_amd_evsel;
};
#endif /* _KERNEL */