hwpmc / amd panic when stopping pmcstat

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Tue, 8 Nov 2016 09:41:06 +0200
panic: [pmc,1473] pp_pmcval outside of expected range cpu=2 ri=17
pp_pmcval=fffffffffa529f5b pm_reloadcount=10000

(kgdb) p pp->pp_pmcs[17].pp_pmc->pm_state
$2 = PMC_STATE_DELETED

Those are interesting bits.  The counter is logically stopped and the value read
from the hardware is small (become huge after "munging").  My theory is that, at
least for AMD processors, a counter keeps running after overflowing.
At the same time, amd_intr() takes an early way out if pm_state !=
PMC_STATE_RUNNING.  So, the counter is allowed to overflow if it's logically
stopped.  But that makes the assertion in pmc_process_csw_out() invalid.

It seems that the following patch fixes the problem.
But I wonder if there is a better, perhaps hardware specific, fix.

Also, maybe the condition should be pm_state == PMC_STATE_RUNNING instead of
pm_state != PMC_STATE_DELETED.

diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 55dc499b1c40e..36bcccb8c27ac 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
_at__at_ -1431,8 +1431,8 _at__at_ pmc_process_csw_out(struct thread *td)
 		 * save the reading.
 		 */

-		if (pp != NULL && pp->pp_pmcs[ri].pp_pmc != NULL) {
-
+		if (pm->pm_state != PMC_STATE_DELETED && pp != NULL &&
+		    pp->pp_pmcs[ri].pp_pmc != NULL) {
 			KASSERT(pm == pp->pp_pmcs[ri].pp_pmc,
 			    ("[pmc,%d] pm %p != pp_pmcs[%d] %p", __LINE__,
 				pm, ri, pp->pp_pmcs[ri].pp_pmc));

-- 
Andriy Gapon
Received on Tue Nov 08 2016 - 06:42:19 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:08 UTC