Make sure that we clear the correct bits when we turn off
a PMC. It was possible that we could have turned a bit on but never cleared it. Extend the calls to rdmsr() to all necessary functions, not just those which previously caused a panic. Pointed out by: jhb@ MFC after: 1 week
This commit is contained in:
parent
6676877bd9
commit
ee6a02813b
@ -168,13 +168,13 @@ core_pcpu_fini(struct pmc_mdep *md, int cpu)
|
|||||||
core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri;
|
core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri;
|
||||||
|
|
||||||
for (n = 0; n < npmc; n++) {
|
for (n = 0; n < npmc; n++) {
|
||||||
msr = rdmsr(IAP_EVSEL0 + n);
|
msr = rdmsr(IAP_EVSEL0 + n) & ~IAP_EVSEL_MASK;
|
||||||
wrmsr(IAP_EVSEL0 + n, msr & ~IAP_EVSEL_MASK);
|
wrmsr(IAP_EVSEL0 + n, msr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (core_cputype != PMC_CPU_INTEL_CORE) {
|
if (core_cputype != PMC_CPU_INTEL_CORE) {
|
||||||
msr = rdmsr(IAF_CTRL);
|
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
|
||||||
wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK);
|
wrmsr(IAF_CTRL, msr);
|
||||||
npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num;
|
npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,13 +392,13 @@ iaf_start_pmc(int cpu, int ri)
|
|||||||
|
|
||||||
iafc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl;
|
iafc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl;
|
||||||
|
|
||||||
msr = rdmsr(IAF_CTRL);
|
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
|
||||||
wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
|
wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
iafc->pc_resync = 0;
|
iafc->pc_resync = 0;
|
||||||
iafc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET));
|
iafc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET));
|
||||||
msr = rdmsr(IA_GLOBAL_CTRL);
|
msr = rdmsr(IA_GLOBAL_CTRL) & ~IAF_GLOBAL_CTRL_MASK;
|
||||||
wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl &
|
wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl &
|
||||||
IAF_GLOBAL_CTRL_MASK));
|
IAF_GLOBAL_CTRL_MASK));
|
||||||
} while (iafc->pc_resync != 0);
|
} while (iafc->pc_resync != 0);
|
||||||
@ -434,13 +434,13 @@ iaf_stop_pmc(int cpu, int ri)
|
|||||||
iafc->pc_iafctrl &= ~fc;
|
iafc->pc_iafctrl &= ~fc;
|
||||||
|
|
||||||
PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl);
|
PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl);
|
||||||
msr = rdmsr(IAF_CTRL);
|
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
|
||||||
wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
|
wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
iafc->pc_resync = 0;
|
iafc->pc_resync = 0;
|
||||||
iafc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET));
|
iafc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET));
|
||||||
msr = rdmsr(IA_GLOBAL_CTRL);
|
msr = rdmsr(IA_GLOBAL_CTRL) & ~IAF_GLOBAL_CTRL_MASK;
|
||||||
wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl &
|
wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl &
|
||||||
IAF_GLOBAL_CTRL_MASK));
|
IAF_GLOBAL_CTRL_MASK));
|
||||||
} while (iafc->pc_resync != 0);
|
} while (iafc->pc_resync != 0);
|
||||||
@ -473,10 +473,14 @@ iaf_write_pmc(int cpu, int ri, pmc_value_t v)
|
|||||||
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
||||||
v = iaf_reload_count_to_perfctr_value(v);
|
v = iaf_reload_count_to_perfctr_value(v);
|
||||||
|
|
||||||
msr = rdmsr(IAF_CTRL);
|
/* Turn off fixed counters */
|
||||||
wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK);
|
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
|
||||||
|
wrmsr(IAF_CTRL, msr);
|
||||||
|
|
||||||
wrmsr(IAF_CTR0 + ri, v & ((1ULL << core_iaf_width) - 1));
|
wrmsr(IAF_CTR0 + ri, v & ((1ULL << core_iaf_width) - 1));
|
||||||
msr = rdmsr(IAF_CTRL);
|
|
||||||
|
/* Turn on fixed counters */
|
||||||
|
msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK;
|
||||||
wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK));
|
wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK));
|
||||||
|
|
||||||
PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx "
|
PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx "
|
||||||
@ -1910,15 +1914,17 @@ iap_stop_pmc(int cpu, int ri)
|
|||||||
|
|
||||||
PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri);
|
PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri);
|
||||||
|
|
||||||
msr = rdmsr(IAP_EVSEL0 + ri);
|
msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
|
||||||
wrmsr(IAP_EVSEL0 + ri, msr & IAP_EVSEL_MASK); /* stop hw */
|
wrmsr(IAP_EVSEL0 + ri, msr); /* stop hw */
|
||||||
|
|
||||||
if (core_cputype == PMC_CPU_INTEL_CORE)
|
if (core_cputype == PMC_CPU_INTEL_CORE)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
msr = 0;
|
||||||
do {
|
do {
|
||||||
cc->pc_resync = 0;
|
cc->pc_resync = 0;
|
||||||
cc->pc_globalctrl &= ~(1ULL << ri);
|
cc->pc_globalctrl &= ~(1ULL << ri);
|
||||||
|
msr = rdmsr(IA_GLOBAL_CTRL) & ~IA_GLOBAL_CTRL_MASK;
|
||||||
wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
|
wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
|
||||||
} while (cc->pc_resync != 0);
|
} while (cc->pc_resync != 0);
|
||||||
|
|
||||||
@ -2004,7 +2010,7 @@ core_intr(int cpu, struct trapframe *tf)
|
|||||||
struct pmc *pm;
|
struct pmc *pm;
|
||||||
struct core_cpu *cc;
|
struct core_cpu *cc;
|
||||||
int error, found_interrupt, ri;
|
int error, found_interrupt, ri;
|
||||||
uint64_t msr = 0;
|
uint64_t msr;
|
||||||
|
|
||||||
PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
|
PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
|
||||||
TRAPF_USERMODE(tf));
|
TRAPF_USERMODE(tf));
|
||||||
@ -2036,15 +2042,15 @@ core_intr(int cpu, struct trapframe *tf)
|
|||||||
* Stop the counter, reload it but only restart it if
|
* Stop the counter, reload it but only restart it if
|
||||||
* the PMC is not stalled.
|
* the PMC is not stalled.
|
||||||
*/
|
*/
|
||||||
msr = rdmsr(IAP_EVSEL0 + ri);
|
msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
|
||||||
wrmsr(IAP_EVSEL0 + ri, msr & ~IAP_EVSEL_MASK);
|
wrmsr(IAP_EVSEL0 + ri, msr);
|
||||||
wrmsr(IAP_PMC0 + ri, v);
|
wrmsr(IAP_PMC0 + ri, v);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wrmsr(IAP_EVSEL0 + ri,
|
wrmsr(IAP_EVSEL0 + ri, msr | (pm->pm_md.pm_iap.pm_iap_evsel |
|
||||||
pm->pm_md.pm_iap.pm_iap_evsel | IAP_EN);
|
IAP_EN));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_interrupt)
|
if (found_interrupt)
|
||||||
@ -2060,7 +2066,7 @@ static int
|
|||||||
core2_intr(int cpu, struct trapframe *tf)
|
core2_intr(int cpu, struct trapframe *tf)
|
||||||
{
|
{
|
||||||
int error, found_interrupt, n;
|
int error, found_interrupt, n;
|
||||||
uint64_t flag, intrstatus, intrenable;
|
uint64_t flag, intrstatus, intrenable, msr;
|
||||||
struct pmc *pm;
|
struct pmc *pm;
|
||||||
struct core_cpu *cc;
|
struct core_cpu *cc;
|
||||||
pmc_value_t v;
|
pmc_value_t v;
|
||||||
@ -2091,7 +2097,8 @@ core2_intr(int cpu, struct trapframe *tf)
|
|||||||
/*
|
/*
|
||||||
* Stop PMCs and clear overflow status bits.
|
* Stop PMCs and clear overflow status bits.
|
||||||
*/
|
*/
|
||||||
wrmsr(IA_GLOBAL_CTRL, 0);
|
msr = rdmsr(IA_GLOBAL_CTRL) & ~IA_GLOBAL_CTRL_MASK;
|
||||||
|
wrmsr(IA_GLOBAL_CTRL, msr);
|
||||||
wrmsr(IA_GLOBAL_OVF_CTRL, intrenable |
|
wrmsr(IA_GLOBAL_OVF_CTRL, intrenable |
|
||||||
IA_GLOBAL_STATUS_FLAG_OVFBUF |
|
IA_GLOBAL_STATUS_FLAG_OVFBUF |
|
||||||
IA_GLOBAL_STATUS_FLAG_CONDCHG);
|
IA_GLOBAL_STATUS_FLAG_CONDCHG);
|
||||||
@ -2162,7 +2169,7 @@ core2_intr(int cpu, struct trapframe *tf)
|
|||||||
|
|
||||||
cc->pc_globalctrl |= intrenable;
|
cc->pc_globalctrl |= intrenable;
|
||||||
|
|
||||||
wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
|
wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl & IA_GLOBAL_CTRL_MASK);
|
||||||
|
|
||||||
PMCDBG(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx "
|
PMCDBG(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx "
|
||||||
"ovf=%jx", cpu, (uintmax_t) rdmsr(IAF_CTRL),
|
"ovf=%jx", cpu, (uintmax_t) rdmsr(IAF_CTRL),
|
||||||
|
@ -144,6 +144,12 @@ struct pmc_md_iap_op_pmcallocate {
|
|||||||
/* The mask is only for the fixed porttion of the register. */
|
/* The mask is only for the fixed porttion of the register. */
|
||||||
#define IAF_GLOBAL_CTRL_MASK 0x0000000700000000
|
#define IAF_GLOBAL_CTRL_MASK 0x0000000700000000
|
||||||
|
|
||||||
|
/* The mask is only for the programmable porttion of the register. */
|
||||||
|
#define IAP_GLOBAL_CTRL_MASK 0x00000000ffffffff
|
||||||
|
|
||||||
|
/* The mask is for both the fixed and programmable porttions of the register. */
|
||||||
|
#define IA_GLOBAL_CTRL_MASK 0x00000007ffffffff
|
||||||
|
|
||||||
#define IA_GLOBAL_OVF_CTRL 0x390
|
#define IA_GLOBAL_OVF_CTRL 0x390
|
||||||
|
|
||||||
#define IA_GLOBAL_STATUS_FLAG_CONDCHG (1ULL << 63)
|
#define IA_GLOBAL_STATUS_FLAG_CONDCHG (1ULL << 63)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user