Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Oct 2011 08:29:47 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r226335 - in user/adrian/if_ath_tx/sys: conf dev/hwpmc
Message-ID:  <201110130829.p9D8Tlkr006690@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu Oct 13 08:29:47 2011
New Revision: 226335
URL: http://svn.freebsd.org/changeset/base/226335

Log:
  Flesh out some more hwpmc mips24k sampling stuff.
  
  * Change DEBUG -> HWPMC_DEBUG; make it easier to deal with.
  * Flesh out the beginning of the hwpmc sample handling code.
    This doesn't (yet) support handling user/kernel call trees,
    so trying to use this (with the subsequent commit) w/ call
    tree enabled will cause all kinds of crash behaviour.

Modified:
  user/adrian/if_ath_tx/sys/conf/options
  user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_logging.c
  user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mips24k.c
  user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mod.c

Modified: user/adrian/if_ath_tx/sys/conf/options
==============================================================================
--- user/adrian/if_ath_tx/sys/conf/options	Thu Oct 13 08:26:28 2011	(r226334)
+++ user/adrian/if_ath_tx/sys/conf/options	Thu Oct 13 08:29:47 2011	(r226335)
@@ -822,6 +822,7 @@ DCONS_FORCE_GDB		opt_dcons.h
 
 # HWPMC options
 HWPMC_HOOKS
+HWPMC_DEBUG		opt_global.h
 
 # XBOX options for FreeBSD/i386, but some files are MI
 XBOX			opt_xbox.h

Modified: user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_logging.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_logging.c	Thu Oct 13 08:26:28 2011	(r226334)
+++ user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_logging.c	Thu Oct 13 08:29:47 2011	(r226335)
@@ -210,7 +210,7 @@ pmclog_get_buffer(struct pmc_owner *po)
 
 	PMCDBG(LOG,GTB,1, "po=%p plb=%p", po, plb);
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 	if (plb)
 		KASSERT(plb->plb_ptr == plb->plb_base &&
 		    plb->plb_base < plb->plb_fence,

Modified: user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mips24k.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mips24k.c	Thu Oct 13 08:26:28 2011	(r226334)
+++ user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mips24k.c	Thu Oct 13 08:29:47 2011	(r226335)
@@ -254,6 +254,8 @@ mips24k_allocate_pmc(int cpu, int ri, st
 		config |= MIPS24K_PMC_USER_ENABLE;
 	if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0)
 		config |= MIPS24K_PMC_ENABLE;
+	if (caps & PMC_CAP_INTERRUPT)
+		config |= MIPS24K_PMC_INTERRUPT_ENABLE;
 
 	pm->pm_md.pm_mips24k.pm_mips24k_evsel = config;
 
@@ -384,6 +386,7 @@ mips24k_stop_pmc(int cpu, int ri)
 	return 0;
 }
 
+
 static int
 mips24k_release_pmc(int cpu, int ri, struct pmc *pmc)
 {
@@ -404,7 +407,71 @@ mips24k_release_pmc(int cpu, int ri, str
 static int
 mips24k_intr(int cpu, struct trapframe *tf)
 {
-	return 0;
+	int error;
+	int retval, ri;
+	struct pmc *pm;
+	struct mips24k_cpu *pc;
+	uint32_t r, r0, r2;
+
+	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
+	    ("[mips24k,%d] CPU %d out of range", __LINE__, cpu));
+
+	retval = 0;
+	pc = mips24k_pcpu[cpu];
+
+	/* Stop PMCs without clearing the counter */
+	r0 = mips_rd_perfcnt0();
+	mips_wr_perfcnt0(r0 & ~(0x1f));
+	r2 = mips_rd_perfcnt2();
+	mips_wr_perfcnt2(r2 & ~(0x1f));
+
+	//printf("%s: called, cpu=%d, tf=%p\n", __func__, cpu, tf);
+
+	for (ri = 0; ri < mips24k_npmcs; ri++) {
+		pm = mips24k_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
+		if (pm == NULL)
+			continue;
+		if (! PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+			continue;
+
+		r = mips24k_pmcn_read(ri);
+		//printf("%s: ri=%d; r=%x\n", __func__, ri, r);
+
+		/* If bit 31 is set, the counter has overflowed */
+		if ((r & 0x80000000) == 0)
+			continue;
+
+		retval = 1;
+		if (pm->pm_state != PMC_STATE_RUNNING)
+			continue;
+		error = pmc_process_interrupt(cpu, pm, tf,
+		    TRAPF_USERMODE(tf));
+		if (error) {
+			/* XXX this is hacky! Fix before merging to -HEAD! */
+			if (ri == 0)
+				r0 = 0;
+			else
+				r2 = 0;
+			mips24k_stop_pmc(cpu, ri);
+		}
+
+		/* Reload sampling count */
+		mips24k_write_pmc(cpu, ri, pm->pm_sc.pm_reloadcount);
+	}
+
+	/*
+	 * Re-enable the PMC counters.
+	 * XXX does this reset the event counter values?
+	 */
+#if 1
+	mips_wr_perfcnt0(r0);
+	mips_wr_perfcnt2(r2);
+#else
+	mips_wr_perfcnt0(0);
+	mips_wr_perfcnt2(0);
+#endif
+
+	return retval;
 }
 
 static int

Modified: user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mod.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mod.c	Thu Oct 13 08:26:28 2011	(r226334)
+++ user/adrian/if_ath_tx/sys/dev/hwpmc/hwpmc_mod.c	Thu Oct 13 08:29:47 2011	(r226335)
@@ -169,7 +169,7 @@ static struct pmc_classdep **pmc_rowinde
  * Prototypes
  */
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 static int	pmc_debugflags_sysctl_handler(SYSCTL_HANDLER_ARGS);
 static int	pmc_debugflags_parse(char *newstr, char *fence);
 #endif
@@ -230,7 +230,7 @@ TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "call
 SYSCTL_INT(_kern_hwpmc, OID_AUTO, callchaindepth, CTLFLAG_TUN|CTLFLAG_RD,
     &pmc_callchaindepth, 0, "depth of call chain records");
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 struct pmc_debugflags pmc_debugflags = PMC_DEBUG_DEFAULT_FLAGS;
 char	pmc_debugstr[PMC_DEBUG_STRSIZE];
 TUNABLE_STR(PMC_SYSCTL_NAME_PREFIX "debugflags", pmc_debugstr,
@@ -328,7 +328,7 @@ static moduledata_t pmc_mod = {
 DECLARE_MODULE(pmc, pmc_mod, SI_SUB_SMP, SI_ORDER_ANY);
 MODULE_VERSION(pmc, PMC_VERSION);
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 enum pmc_dbgparse_state {
 	PMCDS_WS,		/* in whitespace */
 	PMCDS_MAJOR,		/* seen a major keyword */
@@ -806,7 +806,7 @@ pmc_link_target_process(struct pmc *pm, 
 	PMCDBG(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p",
 	    pm, ri, pp);
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 	LIST_FOREACH(pt, &pm->pm_targets, pt_next)
 	    if (pt->pt_process == pp)
 		    KASSERT(0, ("[pmc,%d] pp %p already in pmc %p targets",
@@ -1821,7 +1821,7 @@ pmc_log_all_process_mappings(struct pmc_
  */
 
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 const char *pmc_hooknames[] = {
 	/* these strings correspond to PMC_FN_* in <sys/pmckern.h> */
 	"",
@@ -1979,7 +1979,6 @@ pmc_hook_handler(struct thread *td, int 
 	 * are being processed.
 	 */
 	case PMC_FN_DO_SAMPLES:
-
 		/*
 		 * Clear the cpu specific bit in the CPU mask before
 		 * do the rest of the processing.  If the NMI handler
@@ -2028,7 +2027,7 @@ pmc_hook_handler(struct thread *td, int 
 		break;
 
 	default:
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 		KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function));
 #endif
 		break;
@@ -2204,7 +2203,7 @@ pmc_destroy_pmc_descriptor(struct pmc *p
 {
 	(void) pm;
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 	KASSERT(pm->pm_state == PMC_STATE_DELETED ||
 	    pm->pm_state == PMC_STATE_FREE,
 	    ("[pmc,%d] destroying non-deleted PMC", __LINE__));
@@ -2221,7 +2220,7 @@ pmc_destroy_pmc_descriptor(struct pmc *p
 static void
 pmc_wait_for_pmc_idle(struct pmc *pm)
 {
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 	volatile int maxloop;
 
 	maxloop = 100 * pmc_cpu_max();
@@ -2232,7 +2231,7 @@ pmc_wait_for_pmc_idle(struct pmc *pm)
 	 * comes down to zero.
 	 */
 	while (atomic_load_acq_32(&pm->pm_runcount) > 0) {
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 		maxloop--;
 		KASSERT(maxloop > 0,
 		    ("[pmc,%d] (ri%d, rc%d) waiting too long for "
@@ -2798,7 +2797,7 @@ pmc_stop(struct pmc *pm)
 }
 
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 static const char *pmc_op_to_name[] = {
 #undef	__PMC_OP
 #define	__PMC_OP(N, D)	#N ,
@@ -3775,7 +3774,7 @@ pmc_syscall_handler(struct thread *td, v
 
 		pprw = (struct pmc_op_pmcrw *) arg;
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 		if (prw.pm_flags & PMC_F_NEWVALUE)
 			PMCDBG(PMC,OPS,2, "rw id=%d new %jx -> old %jx",
 			    ri, prw.pm_value, oldvalue);
@@ -4579,7 +4578,7 @@ pmc_initialize(void)
 	md = NULL;
 	error = 0;
 
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 	/* parse debug flags first */
 	if (TUNABLE_STR_FETCH(PMC_SYSCTL_NAME_PREFIX "debugflags",
 		pmc_debugstr, sizeof(pmc_debugstr)))
@@ -4775,7 +4774,7 @@ pmc_cleanup(void)
 	struct pmc_ownerhash *ph;
 	struct pmc_owner *po, *tmp;
 	struct pmc_binding pb;
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 	struct pmc_processhash *prh;
 #endif
 
@@ -4825,7 +4824,7 @@ pmc_cleanup(void)
 
 	mtx_destroy(&pmc_processhash_mtx);
 	if (pmc_processhash) {
-#ifdef	DEBUG
+#ifdef	HWPMC_DEBUG
 		struct pmc_process *pp;
 
 		PMCDBG(MOD,INI,3, "%s", "destroy process hash");



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