mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
Support overflow count in hwpmc on arm64
We increment the overflow count when receiving an overflow interrupt with special care to check if it happens while reading the event counter. Sponsored by: Innovate UK
This commit is contained in:
parent
b2a8d7a9b5
commit
12d053032b
|
@ -195,6 +195,8 @@ arm64_read_pmc(int cpu, int ri, pmc_value_t *v)
|
|||
{
|
||||
pmc_value_t tmp;
|
||||
struct pmc *pm;
|
||||
register_t s;
|
||||
int reg;
|
||||
|
||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
||||
("[arm64,%d] illegal CPU value %d", __LINE__, cpu));
|
||||
|
@ -203,7 +205,23 @@ arm64_read_pmc(int cpu, int ri, pmc_value_t *v)
|
|||
|
||||
pm = arm64_pcpu[cpu]->pc_arm64pmcs[ri].phw_pmc;
|
||||
|
||||
/*
|
||||
* Ensure we don't get interrupted while updating the overflow count.
|
||||
*/
|
||||
s = intr_disable();
|
||||
tmp = arm64_pmcn_read(ri);
|
||||
reg = (1 << ri);
|
||||
if ((READ_SPECIALREG(pmovsclr_el0) & reg) != 0) {
|
||||
/* Clear Overflow Flag */
|
||||
WRITE_SPECIALREG(pmovsclr_el0, reg);
|
||||
if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
||||
pm->pm_overflowcnt++;
|
||||
|
||||
/* Reread counter in case we raced. */
|
||||
tmp = arm64_pmcn_read(ri);
|
||||
}
|
||||
tmp += 0x100000000llu * pm->pm_overflowcnt;
|
||||
intr_restore(s);
|
||||
|
||||
PMCDBG2(MDP, REA, 2, "arm64-read id=%d -> %jd", ri, tmp);
|
||||
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
||||
|
@ -231,6 +249,7 @@ arm64_write_pmc(int cpu, int ri, pmc_value_t v)
|
|||
|
||||
PMCDBG3(MDP, WRI, 1, "arm64-write cpu=%d ri=%d v=%jx", cpu, ri, v);
|
||||
|
||||
pm->pm_overflowcnt = v >> 32;
|
||||
arm64_pmcn_write(ri, v);
|
||||
|
||||
return 0;
|
||||
|
@ -342,9 +361,6 @@ arm64_intr(struct trapframe *tf)
|
|||
pm = arm64_pcpu[cpu]->pc_arm64pmcs[ri].phw_pmc;
|
||||
if (pm == NULL)
|
||||
continue;
|
||||
if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
||||
continue;
|
||||
|
||||
/* Check if counter is overflowed */
|
||||
reg = (1 << ri);
|
||||
if ((READ_SPECIALREG(pmovsclr_el0) & reg) == 0)
|
||||
|
@ -355,6 +371,12 @@ arm64_intr(struct trapframe *tf)
|
|||
isb();
|
||||
|
||||
retval = 1; /* Found an interrupting PMC. */
|
||||
|
||||
if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
|
||||
pm->pm_overflowcnt += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pm->pm_state != PMC_STATE_RUNNING)
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue