svn commit: r226335 - in user/adrian/if_ath_tx/sys: conf dev/hwpmc
Adrian Chadd
adrian at FreeBSD.org
Thu Oct 13 08:29:47 UTC 2011
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");
More information about the svn-src-user
mailing list