Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 May 2016 13:05:40 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300902 - head/sys/dev/hwpmc
Message-ID:  <201605281305.u4SD5ew7009322@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Sat May 28 13:05:39 2016
New Revision: 300902
URL: https://svnweb.freebsd.org/changeset/base/300902

Log:
  Don't panic in hwpmc when stopping sampling.
  
  When hwpmc stops sampling it will set the pm_state to something other
  than PMC_STATE_RUNNING. This means the following sequence can happen:
  
  CPU 0: Enter the interrupt handler
  CPU 0: Set the thread TDP_CALLCHAIN pflag
  CPU 1: Stop sampling
  CPU 0: Call pmc_process_samples, sampling is stopped so clears ps_nsamples
  CPU 0: Finishes interrupt processing with the TDP_CALLCHAIN flag set
  CPU 0: Call pmc_capture_user_callchain to capture the user call chain
  CPU 0: Find all the pmc sample are free so no call chains need to be captured
  CPU 0: KASSERT because of this
  
  This fixes the issue by checking if any of the samples have been stopped
  and including this in te KASSERT.
  
  PR:		204273
  Reviewed by:	bz, gnn
  Obtained from:	ABT Systems Ltd
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D6581

Modified:
  head/sys/dev/hwpmc/hwpmc_mod.c

Modified: head/sys/dev/hwpmc/hwpmc_mod.c
==============================================================================
--- head/sys/dev/hwpmc/hwpmc_mod.c	Sat May 28 08:32:15 2016	(r300901)
+++ head/sys/dev/hwpmc/hwpmc_mod.c	Sat May 28 13:05:39 2016	(r300902)
@@ -4199,6 +4199,7 @@ pmc_capture_user_callchain(int cpu, int 
 	struct pmc_samplebuffer *psb;
 #ifdef	INVARIANTS
 	int ncallchains;
+	int nfree;
 #endif
 
 	psb = pmc_pcpu[cpu]->pc_sb[ring];
@@ -4210,6 +4211,7 @@ pmc_capture_user_callchain(int cpu, int 
 
 #ifdef	INVARIANTS
 	ncallchains = 0;
+	nfree = 0;
 #endif
 
 	/*
@@ -4221,6 +4223,10 @@ pmc_capture_user_callchain(int cpu, int 
 	ps = psb->ps_read;
 	ps_end = psb->ps_write;
 	do {
+#ifdef	INVARIANTS
+		if (ps->ps_pmc->pm_state != PMC_STATE_RUNNING)
+			nfree++;
+#endif
 		if (ps->ps_nsamples != PMC_SAMPLE_INUSE)
 			goto next;
 		if (ps->ps_td != td)
@@ -4256,7 +4262,7 @@ next:
 			ps = psb->ps_samples;
 	} while (ps != ps_end);
 
-	KASSERT(ncallchains > 0,
+	KASSERT(ncallchains > 0 || nfree > 0,
 	    ("[pmc,%d] cpu %d didn't find a sample to collect", __LINE__,
 		cpu));
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605281305.u4SD5ew7009322>