hwpmc: fix a race between amd_stop_pmc and amd_intr
It is possible that wrmsr in amd_stop_pmc() causes an overflow in a counter that it disables. In that case a non-maskable interrupt is generated. The interrupt handler code was written in such a way that it would re-enable the counter. That would lead to an unexpected interrupt later on. This problem was easy to reproduce with $ pmcstat -T -P instructions -t $pid if the target process is sufficiently busy and there are context switches from time to time. There would be a lot of interrupts to "race" with amd_stop_pmc() called during the context switches. The problem affected only AMD processors. While there, trace whether amd_intr() claimed an interrupt. Reviewed by: jhb MFC after: 2 weeks
This commit is contained in:
parent
c82bd4484c
commit
3c1f73b18d
@ -689,12 +689,13 @@ amd_intr(int cpu, struct trapframe *tf)
|
||||
error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
|
||||
TRAPF_USERMODE(tf));
|
||||
if (error == 0)
|
||||
wrmsr(evsel, config | AMD_PMC_ENABLE);
|
||||
wrmsr(evsel, config);
|
||||
}
|
||||
|
||||
atomic_add_int(retval ? &pmc_stats.pm_intr_processed :
|
||||
&pmc_stats.pm_intr_ignored, 1);
|
||||
|
||||
PMCDBG1(MDP,INT,2, "retval=%d", retval);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user