Add a generic way to call per event allocate / release function.

Reviewed by:	mav
MFC after:	1 month
This commit is contained in:
Fabien Thomas 2013-03-05 10:18:48 +00:00
parent e6cd8542ed
commit d49302aead
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=247836
3 changed files with 24 additions and 9 deletions

View File

@ -45,8 +45,6 @@ __FBSDID("$FreeBSD$");
#define SOFT_CAPS (PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INTERRUPT | \ #define SOFT_CAPS (PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INTERRUPT | \
PMC_CAP_USER | PMC_CAP_SYSTEM) PMC_CAP_USER | PMC_CAP_SYSTEM)
PMC_SOFT_DECLARE( , , clock, prof);
struct soft_descr { struct soft_descr {
struct pmc_descr pm_descr; /* "base class" */ struct pmc_descr pm_descr; /* "base class" */
}; };
@ -126,9 +124,10 @@ soft_allocate_pmc(int cpu, int ri, struct pmc *pm,
if (ps == NULL) if (ps == NULL)
return (EINVAL); return (EINVAL);
pmc_soft_ev_release(ps); pmc_soft_ev_release(ps);
/* Module unload is protected by pmc SX lock. */
if (ps->ps_alloc != NULL)
ps->ps_alloc();
if (ev == pmc___clock_prof.ps_ev.pm_ev_code)
cpu_startprofclock();
return (0); return (0);
} }
@ -315,6 +314,8 @@ static int
soft_release_pmc(int cpu, int ri, struct pmc *pmc) soft_release_pmc(int cpu, int ri, struct pmc *pmc)
{ {
struct pmc_hw *phw; struct pmc_hw *phw;
enum pmc_event ev;
struct pmc_soft *ps;
(void) pmc; (void) pmc;
@ -328,8 +329,16 @@ soft_release_pmc(int cpu, int ri, struct pmc *pmc)
KASSERT(phw->phw_pmc == NULL, KASSERT(phw->phw_pmc == NULL,
("[soft,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc)); ("[soft,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
if (pmc->pm_event == pmc___clock_prof.ps_ev.pm_ev_code) ev = pmc->pm_event;
cpu_stopprofclock();
/* Check if event is registered. */
ps = pmc_soft_ev_acquire(ev);
KASSERT(ps != NULL,
("[soft,%d] unregistered event %d", __LINE__, ev));
pmc_soft_ev_release(ps);
/* Module unload is protected by pmc SX lock. */
if (ps->ps_release != NULL)
ps->ps_release();
return (0); return (0);
} }

View File

@ -78,7 +78,8 @@ __FBSDID("$FreeBSD$");
#include <sys/pmckern.h> #include <sys/pmckern.h>
PMC_SOFT_DEFINE( , , clock, hard); PMC_SOFT_DEFINE( , , clock, hard);
PMC_SOFT_DEFINE( , , clock, stat); PMC_SOFT_DEFINE( , , clock, stat);
PMC_SOFT_DEFINE( , , clock, prof); PMC_SOFT_DEFINE_EX( , , clock, prof, \
cpu_startprofclock, cpu_stopprofclock);
#endif #endif
#ifdef DEVICE_POLLING #ifdef DEVICE_POLLING

View File

@ -87,9 +87,9 @@ struct pmckern_soft {
* Soft PMC. * Soft PMC.
*/ */
#define PMC_SOFT_DEFINE(prov, mod, func, name) \ #define PMC_SOFT_DEFINE_EX(prov, mod, func, name, alloc, release) \
struct pmc_soft pmc_##prov##_##mod##_##func##_##name = \ struct pmc_soft pmc_##prov##_##mod##_##func##_##name = \
{ 0, { #prov "_" #mod "_" #func "." #name, 0 } }; \ { 0, alloc, release, { #prov "_" #mod "_" #func "." #name, 0 } }; \
SYSINIT(pmc_##prov##_##mod##_##func##_##name##_init, SI_SUB_KDTRACE, \ SYSINIT(pmc_##prov##_##mod##_##func##_##name##_init, SI_SUB_KDTRACE, \
SI_ORDER_SECOND + 1, pmc_soft_ev_register, \ SI_ORDER_SECOND + 1, pmc_soft_ev_register, \
&pmc_##prov##_##mod##_##func##_##name ); \ &pmc_##prov##_##mod##_##func##_##name ); \
@ -97,6 +97,9 @@ struct pmckern_soft {
SI_SUB_KDTRACE, SI_ORDER_SECOND + 1, pmc_soft_ev_deregister, \ SI_SUB_KDTRACE, SI_ORDER_SECOND + 1, pmc_soft_ev_deregister, \
&pmc_##prov##_##mod##_##func##_##name ) &pmc_##prov##_##mod##_##func##_##name )
#define PMC_SOFT_DEFINE(prov, mod, func, name) \
PMC_SOFT_DEFINE_EX(prov, mod, func, name, NULL, NULL)
#define PMC_SOFT_DECLARE(prov, mod, func, name) \ #define PMC_SOFT_DECLARE(prov, mod, func, name) \
extern struct pmc_soft pmc_##prov##_##mod##_##func##_##name extern struct pmc_soft pmc_##prov##_##mod##_##func##_##name
@ -147,6 +150,8 @@ do { \
struct pmc_soft { struct pmc_soft {
int ps_running; int ps_running;
void (*ps_alloc)(void);
void (*ps_release)(void);
struct pmc_dyn_event_descr ps_ev; struct pmc_dyn_event_descr ps_ev;
}; };