Add support for good old 8192Hz profiling clock to software PMC.

Reviewed by:	fabient
This commit is contained in:
mav 2013-02-26 18:13:42 +00:00
parent 49f99b7251
commit fdde785247
4 changed files with 29 additions and 13 deletions

View File

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 28, 2012
.Dd February 26, 2013
.Dt PMC.SOFT 3
.Os
.Sh NAME
@ -61,6 +61,8 @@ The event specifiers supported by software are:
Hard clock ticks.
.It Li CLOCK.STAT
Stat clock ticks.
.It Li CLOCK.PROF
Profiling clock ticks.
.It Li LOCK.FAILED
Lock acquisition failed.
.It Li PAGE_FAULT.ALL

View File

@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#define SOFT_CAPS (PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INTERRUPT | \
PMC_CAP_USER | PMC_CAP_SYSTEM)
PMC_SOFT_DECLARE( , , clock, prof);
struct soft_descr {
struct pmc_descr pm_descr; /* "base class" */
};
@ -125,6 +127,8 @@ soft_allocate_pmc(int cpu, int ri, struct pmc *pm,
return (EINVAL);
pmc_soft_ev_release(ps);
if (ev == pmc___clock_prof.ps_ev.pm_ev_code)
cpu_startprofclock();
return (0);
}
@ -324,9 +328,8 @@ soft_release_pmc(int cpu, int ri, struct pmc *pmc)
KASSERT(phw->phw_pmc == NULL,
("[soft,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
/*
* Nothing to do.
*/
if (pmc->pm_event == pmc___clock_prof.ps_ev.pm_ev_code)
cpu_stopprofclock();
return (0);
}

View File

@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pmckern.h>
PMC_SOFT_DEFINE( , , clock, hard);
PMC_SOFT_DEFINE( , , clock, stat);
PMC_SOFT_DEFINE( , , clock, prof);
#endif
#ifdef DEVICE_POLLING
@ -817,6 +818,10 @@ profclock_cnt(int cnt, int usermode, uintfptr_t pc)
}
}
#endif
#ifdef HWPMC_HOOKS
if (td->td_intr_frame != NULL)
PMC_SOFT_CALL_TF( , , clock, prof, td->td_intr_frame);
#endif
}
/*

View File

@ -732,12 +732,15 @@ cpu_startprofclock(void)
{
ET_LOCK();
if (periodic) {
configtimer(0);
profiling = 1;
configtimer(1);
if (profiling == 0) {
if (periodic) {
configtimer(0);
profiling = 1;
configtimer(1);
} else
profiling = 1;
} else
profiling = 1;
profiling++;
ET_UNLOCK();
}
@ -749,12 +752,15 @@ cpu_stopprofclock(void)
{
ET_LOCK();
if (periodic) {
configtimer(0);
if (profiling == 1) {
if (periodic) {
configtimer(0);
profiling = 0;
configtimer(1);
} else
profiling = 0;
configtimer(1);
} else
profiling = 0;
profiling--;
ET_UNLOCK();
}