|
Hi Fabien,
I've heard some rumours that this broke hwpmc support for mips24k. Monthadar, can you please provide some background info for this? Thanks, adrian On 28 March 2012 13:58, Fabien Thomas <[hidden email]> wrote: > Author: fabient > Date: Wed Mar 28 20:58:30 2012 > New Revision: 233628 > URL: http://svn.freebsd.org/changeset/base/233628 > > Log: > Add software PMC support. > > New kernel events can be added at various location for sampling or counting. > This will for example allow easy system profiling whatever the processor is > with known tools like pmcstat(8). > > Simultaneous usage of software PMC and hardware PMC is possible, for example > looking at the lock acquire failure, page fault while sampling on > instructions. > > Sponsored by: NETASQ > MFC after: 1 month > > Added: > head/lib/libpmc/pmc.soft.3 (contents, props changed) > head/sys/dev/hwpmc/hwpmc_soft.c (contents, props changed) > head/sys/dev/hwpmc/hwpmc_soft.h (contents, props changed) > Modified: > head/lib/libpmc/Makefile > head/lib/libpmc/libpmc.c > head/lib/libpmc/pmc.3 > head/lib/libpmc/pmc.atom.3 > head/lib/libpmc/pmc.core.3 > head/lib/libpmc/pmc.core2.3 > head/lib/libpmc/pmc.corei7.3 > head/lib/libpmc/pmc.corei7uc.3 > head/lib/libpmc/pmc.iaf.3 > head/lib/libpmc/pmc.k7.3 > head/lib/libpmc/pmc.k8.3 > head/lib/libpmc/pmc.mips24k.3 > head/lib/libpmc/pmc.octeon.3 > head/lib/libpmc/pmc.p4.3 > head/lib/libpmc/pmc.p5.3 > head/lib/libpmc/pmc.p6.3 > head/lib/libpmc/pmc.sandybridge.3 > head/lib/libpmc/pmc.sandybridgeuc.3 > head/lib/libpmc/pmc.tsc.3 > head/lib/libpmc/pmc.ucf.3 > head/lib/libpmc/pmc.westmere.3 > head/lib/libpmc/pmc.westmereuc.3 > head/lib/libpmc/pmc.xscale.3 > head/lib/libpmc/pmclog.c > head/lib/libpmc/pmclog.h > head/sys/amd64/amd64/trap.c > head/sys/amd64/include/pmc_mdep.h > head/sys/arm/include/pmc_mdep.h > head/sys/conf/files > head/sys/dev/hwpmc/hwpmc_amd.c > head/sys/dev/hwpmc/hwpmc_core.c > head/sys/dev/hwpmc/hwpmc_intel.c > head/sys/dev/hwpmc/hwpmc_logging.c > head/sys/dev/hwpmc/hwpmc_mips.c > head/sys/dev/hwpmc/hwpmc_mod.c > head/sys/dev/hwpmc/hwpmc_piv.c > head/sys/dev/hwpmc/hwpmc_powerpc.c > head/sys/dev/hwpmc/hwpmc_ppro.c > head/sys/dev/hwpmc/hwpmc_tsc.c > head/sys/dev/hwpmc/hwpmc_x86.c > head/sys/dev/hwpmc/hwpmc_xscale.c > head/sys/dev/hwpmc/pmc_events.h > head/sys/i386/i386/trap.c > head/sys/i386/include/pmc_mdep.h > head/sys/kern/kern_clock.c > head/sys/kern/kern_lock.c > head/sys/kern/kern_mutex.c > head/sys/kern/kern_pmc.c > head/sys/kern/kern_rwlock.c > head/sys/kern/kern_sx.c > head/sys/kern/subr_trap.c > head/sys/mips/include/pmc_mdep.h > head/sys/modules/hwpmc/Makefile > head/sys/powerpc/include/pmc_mdep.h > head/sys/sys/pmc.h > head/sys/sys/pmckern.h > head/sys/sys/pmclog.h > head/usr.sbin/pmcstat/pmcstat_log.c > > Modified: head/lib/libpmc/Makefile > ============================================================================== > --- head/lib/libpmc/Makefile Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/Makefile Wed Mar 28 20:58:30 2012 (r233628) > @@ -20,6 +20,7 @@ MAN+= pmc_read.3 > MAN+= pmc_set.3 > MAN+= pmc_start.3 > MAN+= pmclog.3 > +MAN+= pmc.soft.3 > > # PMC-dependent manual pages > .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" > > Modified: head/lib/libpmc/libpmc.c > ============================================================================== > --- head/lib/libpmc/libpmc.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/libpmc.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_eve > static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec, > struct pmc_op_pmcallocate *_pmc_config); > #endif > - > #if defined(__mips__) > static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec, > struct pmc_op_pmcallocate *_pmc_config); > #endif /* __mips__ */ > +static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec, > + struct pmc_op_pmcallocate *_pmc_config); > > #if defined(__powerpc__) > static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec, > @@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON); > PMC_CLASSDEP_TABLE(ucf, UCF); > PMC_CLASSDEP_TABLE(ppc7450, PPC7450); > > +static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; > + > #undef __PMC_EV_ALIAS > #define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE }, > > @@ -215,21 +218,22 @@ static const struct pmc_event_descr west > PMC_CLASS_##C, __VA_ARGS__ \ > } > > -PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); > -PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); > -PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); > -PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC); > -PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE); > -PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K); > -PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON); > -PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450); > +PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); > +PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); > +PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); > +PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC); > +PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); > +PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); > +PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); > +PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); > +PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); > > static const struct pmc_event_descr tsc_event_table[] = > { > @@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc) > #if defined(__XSCALE__) > PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale); > #endif > - > #if defined(__mips__) > PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); > PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); > #endif /* __mips__ */ > - > #if defined(__powerpc__) > PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450); > #endif > > +static struct pmc_class_descr soft_class_table_descr = > +{ > + .pm_evc_name = "SOFT-", > + .pm_evc_name_size = sizeof("SOFT-") - 1, > + .pm_evc_class = PMC_CLASS_SOFT, > + .pm_evc_event_table = NULL, > + .pm_evc_event_table_size = 0, > + .pm_evc_allocate_pmc = soft_allocate_pmc > +}; > + > #undef PMC_CLASS_TABLE_DESC > > static const struct pmc_class_descr **pmc_class_table; > @@ -343,9 +355,12 @@ static const char * pmc_state_names[] = > __PMC_STATES() > }; > > -static int pmc_syscall = -1; /* filled in by pmc_init() */ > - > -static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */ > +/* > + * Filled in by pmc_init(). > + */ > +static int pmc_syscall = -1; > +static struct pmc_cpuinfo cpu_info; > +static struct pmc_op_getdyneventinfo soft_event_info; > > /* Event masks for events */ > struct pmc_masks { > @@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char > } > #endif > > +static struct pmc_event_alias generic_aliases[] = { > + EV_ALIAS("instructions", "SOFT-CLOCK.HARD"), > + EV_ALIAS(NULL, NULL) > +}; > + > +static int > +soft_allocate_pmc(enum pmc_event pe, char *ctrspec, > + struct pmc_op_pmcallocate *pmc_config) > +{ > + (void)ctrspec; > + (void)pmc_config; > + > + if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST) > + return (-1); > + > + pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); > + return (0); > +} > + > #if defined(__XSCALE__) > > static struct pmc_event_alias xscale_aliases[] = { > @@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class > ev = ppc7450_event_table; > count = PMC_EVENT_TABLE_SIZE(ppc7450); > break; > + case PMC_CLASS_SOFT: > + ev = soft_event_table; > + count = soft_event_info.pm_nevent; > + break; > default: > errno = EINVAL; > return (-1); > @@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class > > for (;count--; ev++, names++) > *names = ev->pm_ev_name; > + > return (0); > } > > @@ -2780,11 +2819,34 @@ pmc_init(void) > pmc_class_table[n] = NULL; > > /* > + * Get soft events list. > + */ > + soft_event_info.pm_class = PMC_CLASS_SOFT; > + if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0) > + return (pmc_syscall = -1); > + > + /* Map soft events to static list. */ > + for (n = 0; n < soft_event_info.pm_nevent; n++) { > + soft_event_table[n].pm_ev_name = > + soft_event_info.pm_events[n].pm_ev_name; > + soft_event_table[n].pm_ev_code = > + soft_event_info.pm_events[n].pm_ev_code; > + } > + soft_class_table_descr.pm_evc_event_table_size = \ > + soft_event_info.pm_nevent; > + soft_class_table_descr.pm_evc_event_table = \ > + soft_event_table; > + > + /* > * Fill in the class table. > */ > n = 0; > + > + /* Fill soft events information. */ > + pmc_class_table[n++] = &soft_class_table_descr; > #if defined(__amd64__) || defined(__i386__) > - pmc_class_table[n++] = &tsc_class_table_descr; > + if (cpu_info.pm_cputype != PMC_CPU_GENERIC) > + pmc_class_table[n++] = &tsc_class_table_descr; > > /* > * Check if this CPU has fixed function counters. > @@ -2867,6 +2929,9 @@ pmc_init(void) > pmc_class_table[n] = &p4_class_table_descr; > break; > #endif > + case PMC_CPU_GENERIC: > + PMC_MDEP_INIT(generic); > + break; > #if defined(__XSCALE__) > case PMC_CPU_INTEL_XSCALE: > PMC_MDEP_INIT(xscale); > @@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, en > evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale); > } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) { > ev = mips24k_event_table; > - evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k > -); > + evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k); > } else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) { > ev = octeon_event_table; > evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon); > } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) { > ev = ppc7450_event_table; > - evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450 > -); > + evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450); > } else if (pe == PMC_EV_TSC_TSC) { > ev = tsc_event_table; > evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); > + } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) { > + ev = soft_event_table; > + evfence = soft_event_table + soft_event_info.pm_nevent; > } > > for (; ev != evfence; ev++) > > Modified: head/lib/libpmc/pmc.3 > ============================================================================== > --- head/lib/libpmc/pmc.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -223,6 +223,8 @@ and > CPUs. > .It Li PMC_CLASS_TSC > The timestamp counter on i386 and amd64 architecture CPUs. > +.It Li PMC_CLASS_SOFT > +Software events. > .El > .Ss PMC Capabilities > Capabilities of performance monitoring hardware are denoted using > @@ -525,6 +527,7 @@ API is > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 , > > Modified: head/lib/libpmc/pmc.atom.3 > ============================================================================== > --- head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1176,6 +1176,7 @@ and the underlying hardware events used > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.core.3 > ============================================================================== > --- head/lib/libpmc/pmc.core.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.core.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -792,6 +792,7 @@ may not count some transitions. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > > Modified: head/lib/libpmc/pmc.core2.3 > ============================================================================== > --- head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1107,6 +1107,7 @@ and the underlying hardware events used. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.corei7.3 > ============================================================================== > --- head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1559,6 +1559,7 @@ Counts number of segment register loads. > .Xr pmc.corei7uc 3 , > .Xr pmc.westmere 3 , > .Xr pmc.westmereuc 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.corei7uc.3 > ============================================================================== > --- head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -863,6 +863,7 @@ refreshed or needs to go into a power do > .Xr pmc.corei7 3 , > .Xr pmc.westmere 3 , > .Xr pmc.westmereuc 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.iaf.3 > ============================================================================== > --- head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -132,6 +132,7 @@ CPU, use the event specifier > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.k7.3 > ============================================================================== > --- head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -249,6 +249,7 @@ and the underlying hardware events used. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > > Modified: head/lib/libpmc/pmc.k8.3 > ============================================================================== > --- head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -783,6 +783,7 @@ and the underlying hardware events used. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > > Modified: head/lib/libpmc/pmc.mips24k.3 > ============================================================================== > --- head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -392,6 +392,7 @@ and the underlying hardware events used. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.octeon.3 > ============================================================================== > --- head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -232,6 +232,7 @@ and the underlying hardware events used. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.p4.3 > ============================================================================== > --- head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1208,6 +1208,7 @@ and the underlying hardware events used. > .Xr pmc.k8 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > > Modified: head/lib/libpmc/pmc.p5.3 > ============================================================================== > --- head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -444,6 +444,7 @@ and the underlying hardware events used. > .Xr pmc.k8 3 , > .Xr pmc.p4 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > > Modified: head/lib/libpmc/pmc.p6.3 > ============================================================================== > --- head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1010,6 +1010,7 @@ and the underlying hardware events used. > .Xr pmc.k8 3 , > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > > Modified: head/lib/libpmc/pmc.sandybridge.3 > ============================================================================== > --- head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -907,6 +907,7 @@ Split locks in SQ. > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > .Xr pmc.sandybridgeuc 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc.ucf 3 , > .Xr pmc.westmere 3 , > > Modified: head/lib/libpmc/pmc.sandybridgeuc.3 > ============================================================================== > --- head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -208,6 +208,7 @@ Counts the number of core-outgoing entri > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > .Xr pmc.sandybridge 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc.ucf 3 , > .Xr pmc.westmere 3 , > > Added: head/lib/libpmc/pmc.soft.3 > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/lib/libpmc/pmc.soft.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -0,0 +1,104 @@ > +.\" Copyright (c) 2012 Fabien Thomas. All rights reserved. > +.\" > +.\" Redistribution and use in source and binary forms, with or without > +.\" modification, are permitted provided that the following conditions > +.\" are met: > +.\" 1. Redistributions of source code must retain the above copyright > +.\" notice, this list of conditions and the following disclaimer. > +.\" 2. Redistributions in binary form must reproduce the above copyright > +.\" notice, this list of conditions and the following disclaimer in the > +.\" documentation and/or other materials provided with the distribution. > +.\" > +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > +.\" SUCH DAMAGE. > +.\" > +.\" $FreeBSD$ > +.\" > +.Dd March 28, 2012 > +.Os > +.Dt PMC.SOFT 3 > +.Sh NAME > +.Nm pmc.soft > +.Nd measurements using software based events > +.Sh LIBRARY > +.Lb libpmc > +.Sh SYNOPSIS > +.In pmc.h > +.Sh DESCRIPTION > +Software events are used to collect various source of software events. > +.Ss PMC Features > +16 sampling counters using software events based on various sources. > +These PMCs support the following capabilities: > +.Bl -column "PMC_CAP_INTERRUPT" "Support" > +.It Em Capability Ta Em Support > +.It PMC_CAP_CASCADE Ta \&No > +.It PMC_CAP_EDGE Ta \&No > +.It PMC_CAP_INTERRUPT Ta Yes > +.It PMC_CAP_INVERT Ta \&No > +.It PMC_CAP_READ Ta Yes > +.It PMC_CAP_PRECISE Ta \&No > +.It PMC_CAP_SYSTEM Ta Yes > +.It PMC_CAP_TAGGING Ta \&No > +.It PMC_CAP_THRESHOLD Ta \&No > +.It PMC_CAP_USER Ta Yes > +.It PMC_CAP_WRITE Ta Yes > +.El > +.Ss Event Qualifiers > +There is no supported event qualifier. > +.Pp > +The event specifiers supported by software are: > +.Bl -tag -width indent > +.It Li CLOCK.HARD > +Hard clock ticks. > +.It Li CLOCK.STAT > +Stat clock ticks. > +.It Li LOCK.FAILED > +Lock acquisition failed. > +.It Li PAGE_FAULT.ALL > +All page fault type. > +.It Li PAGE_FAULT.READ > +Read page fault. > +.It Li PAGE_FAULT.WRITE > +Write page fault. > +.El > +.Sh SEE ALSO > +.Xr pmc 3 , > +.Xr pmc.atom 3 , > +.Xr pmc.core 3 , > +.Xr pmc.iaf 3 , > +.Xr pmc.ucf 3 , > +.Xr pmc.k7 3 , > +.Xr pmc.k8 3 , > +.Xr pmc.p4 3 , > +.Xr pmc.p5 3 , > +.Xr pmc.p6 3 , > +.Xr pmc.corei7 3 , > +.Xr pmc.corei7uc 3 , > +.Xr pmc.westmereuc 3 , > +.Xr pmc.tsc 3 , > +.Xr pmc_cpuinfo 3 , > +.Xr pmclog 3 , > +.Xr hwpmc 4 > +.Sh HISTORY > +The > +.Nm pmc > +library first appeared in > +.Fx 6.0 . > +.Sh AUTHORS > +The > +.Lb libpmc > +library was written by > +.An "Joseph Koshy" > +.Aq [hidden email] . > +Software PMC was written by > +.An "Fabien Thomas" > +.Aq [hidden email] . > > Modified: head/lib/libpmc/pmc.tsc.3 > ============================================================================== > --- head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -68,6 +68,7 @@ maps to the TSC. > .Xr pmc.p4 3 , > .Xr pmc.p5 3 , > .Xr pmc.p6 3 , > +.Xr pmc.soft 3 , > .Xr pmclog 3 , > .Xr hwpmc 4 > .Sh HISTORY > > Modified: head/lib/libpmc/pmc.ucf.3 > ============================================================================== > --- head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -96,6 +96,7 @@ offset C0H under device number 0 and Fun > .Xr pmc.corei7uc 3 , > .Xr pmc.westmere 3 , > .Xr pmc.westmereuc 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.westmere.3 > ============================================================================== > --- head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shif > .Xr pmc.corei7 3 , > .Xr pmc.corei7uc 3 , > .Xr pmc.westmereuc 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.westmereuc.3 > ============================================================================== > --- head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -1066,6 +1066,7 @@ disabled. > .Xr pmc.corei7 3 , > .Xr pmc.corei7uc 3 , > .Xr pmc.westmere 3 , > +.Xr pmc.soft 3 , > .Xr pmc.tsc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > > Modified: head/lib/libpmc/pmc.xscale.3 > ============================================================================== > --- head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:58:30 2012 (r233628) > @@ -134,6 +134,7 @@ and the underlying hardware events used. > .Xr pmc 3 , > .Xr pmc_cpuinfo 3 , > .Xr pmclog 3 , > +.Xr pmc.soft 3 , > .Xr hwpmc 4 > .Sh HISTORY > The > > Modified: head/lib/libpmc/pmclog.c > ============================================================================== > --- head/lib/libpmc/pmclog.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmclog.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **da > == NULL) > goto error; > break; > + case PMCLOG_TYPE_PMCALLOCATEDYN: > + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid); > + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event); > + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags); > + PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX); > + break; > case PMCLOG_TYPE_PMCATTACH: > PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach); > PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid); > > Modified: head/lib/libpmc/pmclog.h > ============================================================================== > --- head/lib/libpmc/pmclog.h Wed Mar 28 20:49:11 2012 (r233627) > +++ head/lib/libpmc/pmclog.h Wed Mar 28 20:58:30 2012 (r233628) > @@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate { > pmc_id_t pl_pmcid; > }; > > +struct pmclog_ev_pmcallocatedyn { > + uint32_t pl_event; > + char pl_evname[PMC_NAME_MAX]; > + uint32_t pl_flags; > + pmc_id_t pl_pmcid; > +}; > + > struct pmclog_ev_pmcattach { > pmc_id_t pl_pmcid; > pid_t pl_pid; > @@ -146,6 +153,7 @@ struct pmclog_ev { > struct pmclog_ev_map_out pl_mo; > struct pmclog_ev_pcsample pl_s; > struct pmclog_ev_pmcallocate pl_a; > + struct pmclog_ev_pmcallocatedyn pl_ad; > struct pmclog_ev_pmcattach pl_t; > struct pmclog_ev_pmcdetach pl_d; > struct pmclog_ev_proccsw pl_c; > > Modified: head/sys/amd64/amd64/trap.c > ============================================================================== > --- head/sys/amd64/amd64/trap.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/amd64/amd64/trap.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$"); > #include <sys/vmmeter.h> > #ifdef HWPMC_HOOKS > #include <sys/pmckern.h> > +PMC_SOFT_DEFINE( , , page_fault, all); > +PMC_SOFT_DEFINE( , , page_fault, read); > +PMC_SOFT_DEFINE( , , page_fault, write); > #endif > > #include <vm/vm.h> > @@ -743,8 +746,20 @@ trap_pfault(frame, usermode) > */ > rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); > } > - if (rv == KERN_SUCCESS) > + if (rv == KERN_SUCCESS) { > +#ifdef HWPMC_HOOKS > + if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) { > + PMC_SOFT_CALL_TF( , , page_fault, all, frame); > + if (ftype == VM_PROT_READ) > + PMC_SOFT_CALL_TF( , , page_fault, read, > + frame); > + else > + PMC_SOFT_CALL_TF( , , page_fault, write, > + frame); > + } > +#endif > return (0); > + } > nogo: > if (!usermode) { > if (td->td_intr_nesting_level == 0 && > > Modified: head/sys/amd64/include/pmc_mdep.h > ============================================================================== > --- head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) > @@ -50,13 +50,13 @@ struct pmc_mdep; > * measurement architecture have PMCs of the following classes: TSC, > * IAF, IAP, UCF and UCP. > */ > -#define PMC_MDEP_CLASS_INDEX_TSC 0 > -#define PMC_MDEP_CLASS_INDEX_K8 1 > -#define PMC_MDEP_CLASS_INDEX_P4 1 > -#define PMC_MDEP_CLASS_INDEX_IAP 1 > -#define PMC_MDEP_CLASS_INDEX_IAF 2 > -#define PMC_MDEP_CLASS_INDEX_UCP 3 > -#define PMC_MDEP_CLASS_INDEX_UCF 4 > +#define PMC_MDEP_CLASS_INDEX_TSC 1 > +#define PMC_MDEP_CLASS_INDEX_K8 2 > +#define PMC_MDEP_CLASS_INDEX_P4 2 > +#define PMC_MDEP_CLASS_INDEX_IAP 2 > +#define PMC_MDEP_CLASS_INDEX_IAF 3 > +#define PMC_MDEP_CLASS_INDEX_UCP 4 > +#define PMC_MDEP_CLASS_INDEX_UCF 5 > > /* > * On the amd64 platform we support the following PMCs. > @@ -119,6 +119,15 @@ union pmc_md_pmc { > > #define PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS) > > +/* Build a fake kernel trapframe from current instruction pointer. */ > +#define PMC_FAKE_TRAPFRAME(TF) \ > + do { \ > + (TF)->tf_cs = 0; (TF)->tf_rflags = 0; \ > + __asm __volatile("movq %%rbp,%0" : "=r" ((TF)->tf_rbp)); \ > + __asm __volatile("movq %%rsp,%0" : "=r" ((TF)->tf_rsp)); \ > + __asm __volatile("call 1f \n\t1: pop %0" : "=r"((TF)->tf_rip)); \ > + } while (0) > + > /* > * Prototypes > */ > > Modified: head/sys/arm/include/pmc_mdep.h > ============================================================================== > --- head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) > @@ -29,7 +29,7 @@ > #ifndef _MACHINE_PMC_MDEP_H_ > #define _MACHINE_PMC_MDEP_H_ > > -#define PMC_MDEP_CLASS_INDEX_XSCALE 0 > +#define PMC_MDEP_CLASS_INDEX_XSCALE 1 > /* > * On the ARM platform we support the following PMCs. > * > > Modified: head/sys/conf/files > ============================================================================== > --- head/sys/conf/files Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/conf/files Wed Mar 28 20:58:30 2012 (r233628) > @@ -1260,6 +1260,7 @@ dev/hme/if_hme_sbus.c optional hme sbus > dev/hptiop/hptiop.c optional hptiop scbus > dev/hwpmc/hwpmc_logging.c optional hwpmc > dev/hwpmc/hwpmc_mod.c optional hwpmc > +dev/hwpmc/hwpmc_soft.c optional hwpmc > dev/ichsmb/ichsmb.c optional ichsmb > dev/ichsmb/ichsmb_pci.c optional ichsmb pci > dev/ida/ida.c optional ida > > Modified: head/sys/dev/hwpmc/hwpmc_amd.c > ============================================================================== > --- head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -687,7 +687,8 @@ amd_intr(int cpu, struct trapframe *tf) > wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v)); > > /* Restart the counter if logging succeeded. */ > - error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf)); > + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, > + TRAPF_USERMODE(tf)); > if (error == 0) > wrmsr(evsel, config | AMD_PMC_ENABLE); > } > @@ -874,7 +875,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int c > struct pmc_mdep * > pmc_amd_initialize(void) > { > - int classindex, error, i, nclasses, ncpus; > + int classindex, error, i, ncpus; > struct pmc_classdep *pcd; > enum pmc_cputype cputype; > struct pmc_mdep *pmc_mdep; > @@ -926,12 +927,9 @@ pmc_amd_initialize(void) > * These processors have two classes of PMCs: the TSC and > * programmable PMCs. > */ > - nclasses = 2; > - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * sizeof (struct pmc_classdep), > - M_PMC, M_WAITOK|M_ZERO); > + pmc_mdep = pmc_mdep_alloc(2); > > pmc_mdep->pmd_cputype = cputype; > - pmc_mdep->pmd_nclass = nclasses; > > ncpus = pmc_cpu_max(); > > > Modified: head/sys/dev/hwpmc/hwpmc_core.c > ============================================================================== > --- head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -2239,7 +2239,7 @@ core_intr(int cpu, struct trapframe *tf) > if (pm->pm_state != PMC_STATE_RUNNING) > continue; > > - error = pmc_process_interrupt(cpu, pm, tf, > + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, > TRAPF_USERMODE(tf)); > > v = pm->pm_sc.pm_reloadcount; > @@ -2326,7 +2326,7 @@ core2_intr(int cpu, struct trapframe *tf > !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) > continue; > > - error = pmc_process_interrupt(cpu, pm, tf, > + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, > TRAPF_USERMODE(tf)); > if (error) > intrenable &= ~flag; > @@ -2354,7 +2354,7 @@ core2_intr(int cpu, struct trapframe *tf > !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) > continue; > > - error = pmc_process_interrupt(cpu, pm, tf, > + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, > TRAPF_USERMODE(tf)); > if (error) > intrenable &= ~flag; > > Modified: head/sys/dev/hwpmc/hwpmc_intel.c > ============================================================================== > --- head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -162,12 +162,10 @@ pmc_intel_initialize(void) > return (NULL); > } > > - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * > - sizeof(struct pmc_classdep), M_PMC, M_WAITOK|M_ZERO); > + /* Allocate base class and initialize machine dependent struct */ > + pmc_mdep = pmc_mdep_alloc(nclasses); > > pmc_mdep->pmd_cputype = cputype; > - pmc_mdep->pmd_nclass = nclasses; > - > pmc_mdep->pmd_switch_in = intel_switch_in; > pmc_mdep->pmd_switch_out = intel_switch_out; > > > Modified: head/sys/dev/hwpmc/hwpmc_logging.c > ============================================================================== > --- head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -129,6 +129,7 @@ static struct mtx pmc_kthread_mtx; /* sl > > /* Emit a string. Caution: does NOT update _le, so needs to be last */ > #define PMCLOG_EMITSTRING(S,L) do { bcopy((S), _le, (L)); } while (0) > +#define PMCLOG_EMITNULLSTRING(L) do { bzero(_le, (L)); } while (0) > > #define PMCLOG_DESPATCH(PO) \ > pmclog_release((PO)); \ > @@ -835,16 +836,33 @@ void > pmclog_process_pmcallocate(struct pmc *pm) > { > struct pmc_owner *po; > + struct pmc_soft *ps; > > po = pm->pm_owner; > > PMCDBG(LOG,ALL,1, "pm=%p", pm); > > - PMCLOG_RESERVE(po, PMCALLOCATE, sizeof(struct pmclog_pmcallocate)); > - PMCLOG_EMIT32(pm->pm_id); > - PMCLOG_EMIT32(pm->pm_event); > - PMCLOG_EMIT32(pm->pm_flags); > - PMCLOG_DESPATCH(po); > + if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) { > + PMCLOG_RESERVE(po, PMCALLOCATEDYN, > + sizeof(struct pmclog_pmcallocatedyn)); > + PMCLOG_EMIT32(pm->pm_id); > + PMCLOG_EMIT32(pm->pm_event); > + PMCLOG_EMIT32(pm->pm_flags); > + ps = pmc_soft_ev_acquire(pm->pm_event); > + if (ps != NULL) > + PMCLOG_EMITSTRING(ps->ps_ev.pm_ev_name,PMC_NAME_MAX); > + else > + PMCLOG_EMITNULLSTRING(PMC_NAME_MAX); > + pmc_soft_ev_release(ps); > + PMCLOG_DESPATCH(po); > + } else { > + PMCLOG_RESERVE(po, PMCALLOCATE, > + sizeof(struct pmclog_pmcallocate)); > + PMCLOG_EMIT32(pm->pm_id); > + PMCLOG_EMIT32(pm->pm_event); > + PMCLOG_EMIT32(pm->pm_flags); > + PMCLOG_DESPATCH(po); > + } > } > > void > > Modified: head/sys/dev/hwpmc/hwpmc_mips.c > ============================================================================== > --- head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -287,7 +287,7 @@ mips_pmc_intr(int cpu, struct trapframe > retval = 1; > if (pm->pm_state != PMC_STATE_RUNNING) > continue; > - error = pmc_process_interrupt(cpu, pm, tf, > + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, > TRAPF_USERMODE(tf)); > if (error) { > /* Clear/disable the relevant counter */ > > Modified: head/sys/dev/hwpmc/hwpmc_mod.c > ============================================================================== > --- head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:49:11 2012 (r233627) > +++ head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:58:30 2012 (r233628) > @@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$"); > #include <vm/vm_map.h> > #include <vm/vm_object.h> > > +#include "hwpmc_soft.h" > + > /* > * Types > */ > @@ -182,7 +184,7 @@ static int pmc_attach_one_process(struct > static int pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, > int cpu); > static int pmc_can_attach(struct pmc *pm, struct proc *p); > -static void pmc_capture_user_callchain(int cpu, struct trapframe *tf); > +static void pmc_capture_user_callchain(int cpu, int soft, struct trapframe *tf); > static void pmc_cleanup(void); > static int pmc_detach_process(struct proc *p, struct pmc *pm); > static int pmc_detach_one_process(struct proc *p, struct pmc *pm, > @@ -206,7 +208,7 @@ static void pmc_process_csw_out(struct t > static void pmc_process_exit(void *arg, struct proc *p); > static void pmc_process_fork(void *arg, struct proc *p1, > struct proc *p2, int n); > -static void pmc_process_samples(int cpu); > +static void pmc_process_samples(int cpu, int soft); > static void pmc_release_pmc_descriptor(struct pmc *pmc); > static void pmc_remove_owner(struct pmc_owner *po); > static void pmc_remove_process_descriptor(struct pmc_process *pp); > @@ -218,12 +220,16 @@ static int pmc_stop(struct pmc *pm); > static int pmc_syscall_handler(struct thread *td, void *syscall_args); > static void pmc_unlink_target_process(struct pmc *pmc, > struct pmc_process *pp); > +static int generic_switch_in(struct pmc_cpu *pc, struct pmc_process *pp); > +static int generic_switch_out(struct pmc_cpu *pc, struct pmc_process *pp); > +static struct pmc_mdep *pmc_generic_cpu_initialize(void); > +static void pmc_generic_cpu_finalize(struct pmc_mdep *md); > > /* > * Kernel tunables and sysctl(8) interface. > */ > > -SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters"); > +SYSCTL_DECL(_kern_hwpmc); > > static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; > TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "callchaindepth", &pmc_callchaindepth); > @@ -1833,7 +1839,9 @@ const char *pmc_hooknames[] = { > "KLDUNLOAD", > "MMAP", > "MUNMAP", > - "CALLCHAIN" > + "CALLCHAIN-NMI", > + "CALLCHAIN-SOFT", > + "SOFTSAMPLING" > }; > #endif > > @@ -1992,7 +2000,8 @@ pmc_hook_handler(struct thread *td, int > * lose the interrupt sample. > */ > CPU_CLR_ATOMIC(PCPU_GET(cpuid), &pmc_cpumask); > - pmc_process_samples(PCPU_GET(cpuid)); > + pmc_process_samples(PCPU_GET(cpuid), PMC_HR); > + pmc_process_samples(PCPU_GET(cpuid), PMC_SR); > break; > > > @@ -2022,11 +2031,30 @@ pmc_hook_handler(struct thread *td, int > */ > KASSERT(td == curthread, ("[pmc,%d] td != curthread", > __LINE__)); > - pmc_capture_user_callchain(PCPU_GET(cpuid), > + > + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_HR, > (struct trapframe *) arg); > td->td_pflags &= ~TDP_CALLCHAIN; > break; > > + case PMC_FN_USER_CALLCHAIN_SOFT: > + /* > + * Record a call chain. > + */ > + KASSERT(td == curthread, ("[pmc,%d] td != curthread", > + __LINE__)); > + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_SR, > + (struct trapframe *) arg); > + td->td_pflags &= ~TDP_CALLCHAIN; > + break; > + > + case PMC_FN_SOFT_SAMPLING: > + /* > + * Call soft PMC sampling intr. > + */ > + pmc_soft_intr((struct pmckern_soft *) arg); > + break; > + > default: > #ifdef DEBUG > KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function)); > @@ -2221,18 +2249,17 @@ pmc_destroy_pmc_descriptor(struct pmc *p > static void > pmc_wait_for_pmc_idle(struct pmc *pm) > { > -#ifdef DEBUG > +#ifdef DEBUG > volatile int maxloop; > > maxloop = 100 * pmc_cpu_max(); > #endif > - > /* > * Loop (with a forced context switch) till the PMC's runcount > * comes down to zero. > */ > while (atomic_load_acq_32(&pm->pm_runcount) > 0) { > -#ifdef DEBUG > +#ifdef DEBUG > maxloop--; > KASSERT(maxloop > 0, > ("[pmc,%d] (ri%d, rc%d) waiting too long for " > @@ -2972,6 +2999,53 @@ pmc_syscall_handler(struct thread *td, v > } > break; > > + /* > + * Retrieve soft events list. > + */ > + case PMC_OP_GETDYNEVENTINFO: > + { > + enum pmc_class cl; > + enum pmc_event ev; > + struct pmc_op_getdyneventinfo *gei; > + struct pmc_dyn_event_descr dev; > + struct pmc_soft *ps; > + uint32_t nevent; > + > + sx_assert(&pmc_sx, SX_LOCKED); > + > + gei = (struct pmc_op_getdyneventinfo *) arg; > + > + if ((error = copyin(&gei->pm_class, &cl, sizeof(cl))) != 0) > + break; > + > + /* Only SOFT class is dynamic. */ > + if (cl != PMC_CLASS_SOFT) { > + error = EINVAL; > + break; > + } > + > + nevent = 0; > + for (ev = PMC_EV_SOFT_FIRST; ev <= PMC_EV_SOFT_LAST; ev++) { > + ps = pmc_soft_ev_acquire(ev); > + if (ps == NULL) > + continue; > + bcopy(&ps->ps_ev, &dev, sizeof(dev)); > + pmc_soft_ev_release(ps); > + > + error = copyout(&dev, > + &gei->pm_events[nevent], > + sizeof(struct pmc_dyn_event_descr)); > + if (error != 0) > + break; > + nevent++; > + } > + if (error != 0) > + break; > + > + error = copyout(&nevent, &gei->pm_nevent, > > *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** [hidden email] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-mips To unsubscribe, send any mail to "[hidden email]" |
|
On Mon, Apr 23, 2012 at 8:44 AM, Adrian Chadd <[hidden email]> wrote:
> Hi Fabien, > > I've heard some rumours that this broke hwpmc support for mips24k. > > Monthadar, can you please provide some background info for this? > This is the log output Using default protocol (TFTP) Entry point: 0x80050100, address range: 0x80050000-0x804f1dcc RedBoot> exec Now booting linux kernel: Base address 0x80050000 Entry 0x80050100 memsize=0x08000000 modetty0=0,n,8,1,hw board=RouterStation PRO ethaddr=00.15.6d.c8.c9.2e CPU platform: Atheros AR7161 rev 2 CPU Frequency=720 MHz CPU DDR Frequency=360 MHz CPU AHB Frequency=180 MHz platform frequency: 720000000 arguments: a0 = 00000002 a1 = 80050028 a2 = 80050000 a3 = 00000001 Cmd line: �������m���������������_}������߾q��������������������������������߿���������_�w���������?-����{������~�� Environment: memsize = 0x08000000 modetty0 = 0,n,8,1,hw ethaddr = 00.15.6d.c8.c9.2e board = RouterStation PRO Cache info: picache_stride = 4096 picache_loopcount = 16 pdcache_stride = 4096 pdcache_loopcount = 8 cpu0: MIPS Technologies processor v116.147 MMU: Standard TLB, 16 entries L1 i-cache: 4 ways of 512 sets, 32 bytes per line L1 d-cache: 4 ways of 256 sets, 32 bytes per line Config1=0x9ee3519e<PerfCount,WatchRegs,MIPS16,EJTAG> Config3=0x20 KDB: debugger backends: ddb KDB: current backend: ddb Copyright (c) 1992-2012 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD is a registered trademark of The FreeBSD Foundation. FreeBSD 10.0-CURRENT #12: Fri Apr 20 18:03:16 CEST 2012 root@freebsd-re-9:/usr/obj/mips.mips/usr/src/sys/RSPRO_USB_PROD mips WARNING: WITNESS option enabled, expect reduced performance. MEMGUARD DEBUGGING ALLOCATOR INITIALIZED: MEMGUARD map base: 0xc0800000 MEMGUARD map limit: 0xc1c00000 MEMGUARD map size: 20480 KBytes real memory = 134217728 (131072K bytes) avail memory = 123117568 (117MB) random device not loaded; using insecure entropy nexus0: <MIPS32 root nexus> clock0: <Generic MIPS32 ticker> on nexus0 Timecounter "MIPS32" frequency 360000000 Hz quality 800 Event timer "MIPS32" frequency 360000000 Hz quality 800 apb0 at irq 4 on nexus0 uart0: <16550 or compatible> on apb0 uart0: console (115200,n,8,1) gpio0: <Atheros AR71XX GPIO driver> on apb0 gpio0: [GIANT-LOCKED] gpio0: gpio pinmask=0x0 gpioc0: <GPIO controller> on gpio0 gpiobus0: <GPIO bus> on gpio0 ehci0: <AR71XX Integrated USB 2.0 controller> at mem 0x1b000000-0x1bffffff irq 1 on nexus0 usbus0: set host controller mode usbus0: EHCI version 1.0 usbus0: set host controller mode usbus0 on ehci0 pcib0 at irq 0 on nexus0 pci0: <PCI bus> on pcib0 pci0: <old, non-VGA display device> at device 0.0 (no driver attached) ath0: <Atheros 5413> irq 0 at device 17.0 on pci0 ath0: AR5413 mac 10.5 RF5413 phy 6.1 ath0: 2GHz radio: 0x0000; 5GHz radio: 0x0063 arge0: <Atheros AR71xx built-in ethernet interface> at mem 0x19000000-0x19000fff irq 2 on nexus0 arge0: No PHY specified, using mask 16 miibus0: <MII bus> on arge0 ukphy0: <Generic IEEE 802.3u media interface> PHY 4 on miibus0 ukphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT-FDX, 1000baseT-FDX-master, auto arge0: Ethernet address: 00:15:6d:c8:c9:2e arge1: <Atheros AR71xx built-in ethernet interface> at mem 0x1a000000-0x1a000fff irq 3 on nexus0 arge1: No PHY specified, using mask 15 arge1: Ethernet address: 00:15:6d:c8:c9:2f spi0: <AR71XX SPI> at mem 0x1f000000-0x1f00000f on nexus0 spibus0: <spibus bus> on spi0 mx25l0: <M25Pxx Flash Family> at cs 0 on spibus0 mx25l0: mx25ll128, sector 65536 bytes, 256 sectors ar71xx_wdog0: <Atheros AR71XX watchdog timer> on nexus0 Timecounters tick every 1.000 msec usbus0: 480Mbps High Speed USB v2.0 ugen0.1: <Atheros> at usbus0 uhub0: <Atheros EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0 panic: [pmc,4816] npmc miscomputed: ri=0, md->npmc=2 KDB: enter: panic [ thread pid 0 tid 100000 ] Stopped at kdb_enter+0x4c: lui at,0x8050 db> tr Tracing pid 0 tid 100000 td 0x804f76d0 db_trace_thread+30 (?,?,?,?) ra 8068b94800000018 sp 0 sz 0 80075adc+114 (0,?,ffffffff,?) ra 8068b96000000020 sp 100000000 sz 1 80074e24+388 (?,?,?,?) ra 8068b980000000a8 sp 0 sz 0 db_command_loop+70 (?,?,?,?) ra 8068ba2800000018 sp 0 sz 0 80077900+f4 (?,?,?,?) ra 8068ba40000001a8 sp 0 sz 0 kdb_trap+110 (?,?,?,?) ra 8068bbe800000030 sp 0 sz 0 trap+c7c (?,?,?,?) ra 8068bc18000000b8 sp 0 sz 0 MipsKernGenException+134 (0,4,8043b1d4,119) ra 8068bcd0000000c8 sp 100000001 sz 1 kdb_enter+4c (?,?,?,?) ra 8068bd9800000018 sp 0 sz 0 panic+11c (?,12d0,0,2) ra 8068bdb000000028 sp 1 sz 1 800e8ca8+274 (?,?,?,?) ra 8068bdd800000038 sp 0 sz 0 syscall_module_handler+b8 (?,?,?,?) ra 8068be1000000028 sp 0 sz 0 module_register_init+9c (?,?,?,?) ra 8068be3800000028 sp 0 sz 0 mi_startup+138 (?,?,?,?) ra 8068be6000000020 sp 0 sz 0 _start+90 (?,?,?,?) ra 8068be8000000000 sp 0 sz 0 pid 0 db> > Thanks, > > > > adrian > > On 28 March 2012 13:58, Fabien Thomas <[hidden email]> wrote: >> Author: fabient >> Date: Wed Mar 28 20:58:30 2012 >> New Revision: 233628 >> URL: http://svn.freebsd.org/changeset/base/233628 >> >> Log: >> Add software PMC support. >> >> New kernel events can be added at various location for sampling or counting. >> This will for example allow easy system profiling whatever the processor is >> with known tools like pmcstat(8). >> >> Simultaneous usage of software PMC and hardware PMC is possible, for example >> looking at the lock acquire failure, page fault while sampling on >> instructions. >> >> Sponsored by: NETASQ >> MFC after: 1 month >> >> Added: >> head/lib/libpmc/pmc.soft.3 (contents, props changed) >> head/sys/dev/hwpmc/hwpmc_soft.c (contents, props changed) >> head/sys/dev/hwpmc/hwpmc_soft.h (contents, props changed) >> Modified: >> head/lib/libpmc/Makefile >> head/lib/libpmc/libpmc.c >> head/lib/libpmc/pmc.3 >> head/lib/libpmc/pmc.atom.3 >> head/lib/libpmc/pmc.core.3 >> head/lib/libpmc/pmc.core2.3 >> head/lib/libpmc/pmc.corei7.3 >> head/lib/libpmc/pmc.corei7uc.3 >> head/lib/libpmc/pmc.iaf.3 >> head/lib/libpmc/pmc.k7.3 >> head/lib/libpmc/pmc.k8.3 >> head/lib/libpmc/pmc.mips24k.3 >> head/lib/libpmc/pmc.octeon.3 >> head/lib/libpmc/pmc.p4.3 >> head/lib/libpmc/pmc.p5.3 >> head/lib/libpmc/pmc.p6.3 >> head/lib/libpmc/pmc.sandybridge.3 >> head/lib/libpmc/pmc.sandybridgeuc.3 >> head/lib/libpmc/pmc.tsc.3 >> head/lib/libpmc/pmc.ucf.3 >> head/lib/libpmc/pmc.westmere.3 >> head/lib/libpmc/pmc.westmereuc.3 >> head/lib/libpmc/pmc.xscale.3 >> head/lib/libpmc/pmclog.c >> head/lib/libpmc/pmclog.h >> head/sys/amd64/amd64/trap.c >> head/sys/amd64/include/pmc_mdep.h >> head/sys/arm/include/pmc_mdep.h >> head/sys/conf/files >> head/sys/dev/hwpmc/hwpmc_amd.c >> head/sys/dev/hwpmc/hwpmc_core.c >> head/sys/dev/hwpmc/hwpmc_intel.c >> head/sys/dev/hwpmc/hwpmc_logging.c >> head/sys/dev/hwpmc/hwpmc_mips.c >> head/sys/dev/hwpmc/hwpmc_mod.c >> head/sys/dev/hwpmc/hwpmc_piv.c >> head/sys/dev/hwpmc/hwpmc_powerpc.c >> head/sys/dev/hwpmc/hwpmc_ppro.c >> head/sys/dev/hwpmc/hwpmc_tsc.c >> head/sys/dev/hwpmc/hwpmc_x86.c >> head/sys/dev/hwpmc/hwpmc_xscale.c >> head/sys/dev/hwpmc/pmc_events.h >> head/sys/i386/i386/trap.c >> head/sys/i386/include/pmc_mdep.h >> head/sys/kern/kern_clock.c >> head/sys/kern/kern_lock.c >> head/sys/kern/kern_mutex.c >> head/sys/kern/kern_pmc.c >> head/sys/kern/kern_rwlock.c >> head/sys/kern/kern_sx.c >> head/sys/kern/subr_trap.c >> head/sys/mips/include/pmc_mdep.h >> head/sys/modules/hwpmc/Makefile >> head/sys/powerpc/include/pmc_mdep.h >> head/sys/sys/pmc.h >> head/sys/sys/pmckern.h >> head/sys/sys/pmclog.h >> head/usr.sbin/pmcstat/pmcstat_log.c >> >> Modified: head/lib/libpmc/Makefile >> ============================================================================== >> --- head/lib/libpmc/Makefile Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/Makefile Wed Mar 28 20:58:30 2012 (r233628) >> @@ -20,6 +20,7 @@ MAN+= pmc_read.3 >> MAN+= pmc_set.3 >> MAN+= pmc_start.3 >> MAN+= pmclog.3 >> +MAN+= pmc.soft.3 >> >> # PMC-dependent manual pages >> .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" >> >> Modified: head/lib/libpmc/libpmc.c >> ============================================================================== >> --- head/lib/libpmc/libpmc.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/libpmc.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_eve >> static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >> struct pmc_op_pmcallocate *_pmc_config); >> #endif >> - >> #if defined(__mips__) >> static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec, >> struct pmc_op_pmcallocate *_pmc_config); >> #endif /* __mips__ */ >> +static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >> + struct pmc_op_pmcallocate *_pmc_config); >> >> #if defined(__powerpc__) >> static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec, >> @@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON); >> PMC_CLASSDEP_TABLE(ucf, UCF); >> PMC_CLASSDEP_TABLE(ppc7450, PPC7450); >> >> +static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; >> + >> #undef __PMC_EV_ALIAS >> #define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE }, >> >> @@ -215,21 +218,22 @@ static const struct pmc_event_descr west >> PMC_CLASS_##C, __VA_ARGS__ \ >> } >> >> -PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >> -PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >> -PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >> -PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC); >> -PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE); >> -PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K); >> -PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON); >> -PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450); >> +PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >> +PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >> +PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >> +PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC); >> +PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); >> +PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); >> +PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); >> +PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); >> +PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); >> >> static const struct pmc_event_descr tsc_event_table[] = >> { >> @@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc) >> #if defined(__XSCALE__) >> PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale); >> #endif >> - >> #if defined(__mips__) >> PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); >> PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); >> #endif /* __mips__ */ >> - >> #if defined(__powerpc__) >> PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450); >> #endif >> >> +static struct pmc_class_descr soft_class_table_descr = >> +{ >> + .pm_evc_name = "SOFT-", >> + .pm_evc_name_size = sizeof("SOFT-") - 1, >> + .pm_evc_class = PMC_CLASS_SOFT, >> + .pm_evc_event_table = NULL, >> + .pm_evc_event_table_size = 0, >> + .pm_evc_allocate_pmc = soft_allocate_pmc >> +}; >> + >> #undef PMC_CLASS_TABLE_DESC >> >> static const struct pmc_class_descr **pmc_class_table; >> @@ -343,9 +355,12 @@ static const char * pmc_state_names[] = >> __PMC_STATES() >> }; >> >> -static int pmc_syscall = -1; /* filled in by pmc_init() */ >> - >> -static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */ >> +/* >> + * Filled in by pmc_init(). >> + */ >> +static int pmc_syscall = -1; >> +static struct pmc_cpuinfo cpu_info; >> +static struct pmc_op_getdyneventinfo soft_event_info; >> >> /* Event masks for events */ >> struct pmc_masks { >> @@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char >> } >> #endif >> >> +static struct pmc_event_alias generic_aliases[] = { >> + EV_ALIAS("instructions", "SOFT-CLOCK.HARD"), >> + EV_ALIAS(NULL, NULL) >> +}; >> + >> +static int >> +soft_allocate_pmc(enum pmc_event pe, char *ctrspec, >> + struct pmc_op_pmcallocate *pmc_config) >> +{ >> + (void)ctrspec; >> + (void)pmc_config; >> + >> + if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST) >> + return (-1); >> + >> + pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); >> + return (0); >> +} >> + >> #if defined(__XSCALE__) >> >> static struct pmc_event_alias xscale_aliases[] = { >> @@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class >> ev = ppc7450_event_table; >> count = PMC_EVENT_TABLE_SIZE(ppc7450); >> break; >> + case PMC_CLASS_SOFT: >> + ev = soft_event_table; >> + count = soft_event_info.pm_nevent; >> + break; >> default: >> errno = EINVAL; >> return (-1); >> @@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class >> >> for (;count--; ev++, names++) >> *names = ev->pm_ev_name; >> + >> return (0); >> } >> >> @@ -2780,11 +2819,34 @@ pmc_init(void) >> pmc_class_table[n] = NULL; >> >> /* >> + * Get soft events list. >> + */ >> + soft_event_info.pm_class = PMC_CLASS_SOFT; >> + if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0) >> + return (pmc_syscall = -1); >> + >> + /* Map soft events to static list. */ >> + for (n = 0; n < soft_event_info.pm_nevent; n++) { >> + soft_event_table[n].pm_ev_name = >> + soft_event_info.pm_events[n].pm_ev_name; >> + soft_event_table[n].pm_ev_code = >> + soft_event_info.pm_events[n].pm_ev_code; >> + } >> + soft_class_table_descr.pm_evc_event_table_size = \ >> + soft_event_info.pm_nevent; >> + soft_class_table_descr.pm_evc_event_table = \ >> + soft_event_table; >> + >> + /* >> * Fill in the class table. >> */ >> n = 0; >> + >> + /* Fill soft events information. */ >> + pmc_class_table[n++] = &soft_class_table_descr; >> #if defined(__amd64__) || defined(__i386__) >> - pmc_class_table[n++] = &tsc_class_table_descr; >> + if (cpu_info.pm_cputype != PMC_CPU_GENERIC) >> + pmc_class_table[n++] = &tsc_class_table_descr; >> >> /* >> * Check if this CPU has fixed function counters. >> @@ -2867,6 +2929,9 @@ pmc_init(void) >> pmc_class_table[n] = &p4_class_table_descr; >> break; >> #endif >> + case PMC_CPU_GENERIC: >> + PMC_MDEP_INIT(generic); >> + break; >> #if defined(__XSCALE__) >> case PMC_CPU_INTEL_XSCALE: >> PMC_MDEP_INIT(xscale); >> @@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, en >> evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale); >> } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) { >> ev = mips24k_event_table; >> - evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k >> -); >> + evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k); >> } else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) { >> ev = octeon_event_table; >> evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon); >> } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) { >> ev = ppc7450_event_table; >> - evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450 >> -); >> + evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450); >> } else if (pe == PMC_EV_TSC_TSC) { >> ev = tsc_event_table; >> evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); >> + } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) { >> + ev = soft_event_table; >> + evfence = soft_event_table + soft_event_info.pm_nevent; >> } >> >> for (; ev != evfence; ev++) >> >> Modified: head/lib/libpmc/pmc.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -223,6 +223,8 @@ and >> CPUs. >> .It Li PMC_CLASS_TSC >> The timestamp counter on i386 and amd64 architecture CPUs. >> +.It Li PMC_CLASS_SOFT >> +Software events. >> .El >> .Ss PMC Capabilities >> Capabilities of performance monitoring hardware are denoted using >> @@ -525,6 +527,7 @@ API is >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 , >> >> Modified: head/lib/libpmc/pmc.atom.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1176,6 +1176,7 @@ and the underlying hardware events used >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.core.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.core.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.core.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -792,6 +792,7 @@ may not count some transitions. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> >> Modified: head/lib/libpmc/pmc.core2.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1107,6 +1107,7 @@ and the underlying hardware events used. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.corei7.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1559,6 +1559,7 @@ Counts number of segment register loads. >> .Xr pmc.corei7uc 3 , >> .Xr pmc.westmere 3 , >> .Xr pmc.westmereuc 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.corei7uc.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -863,6 +863,7 @@ refreshed or needs to go into a power do >> .Xr pmc.corei7 3 , >> .Xr pmc.westmere 3 , >> .Xr pmc.westmereuc 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.iaf.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -132,6 +132,7 @@ CPU, use the event specifier >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.k7.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -249,6 +249,7 @@ and the underlying hardware events used. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> >> Modified: head/lib/libpmc/pmc.k8.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -783,6 +783,7 @@ and the underlying hardware events used. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> >> Modified: head/lib/libpmc/pmc.mips24k.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -392,6 +392,7 @@ and the underlying hardware events used. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.octeon.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -232,6 +232,7 @@ and the underlying hardware events used. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.p4.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1208,6 +1208,7 @@ and the underlying hardware events used. >> .Xr pmc.k8 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> >> Modified: head/lib/libpmc/pmc.p5.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -444,6 +444,7 @@ and the underlying hardware events used. >> .Xr pmc.k8 3 , >> .Xr pmc.p4 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> >> Modified: head/lib/libpmc/pmc.p6.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1010,6 +1010,7 @@ and the underlying hardware events used. >> .Xr pmc.k8 3 , >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> >> Modified: head/lib/libpmc/pmc.sandybridge.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -907,6 +907,7 @@ Split locks in SQ. >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> .Xr pmc.sandybridgeuc 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc.ucf 3 , >> .Xr pmc.westmere 3 , >> >> Modified: head/lib/libpmc/pmc.sandybridgeuc.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -208,6 +208,7 @@ Counts the number of core-outgoing entri >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> .Xr pmc.sandybridge 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc.ucf 3 , >> .Xr pmc.westmere 3 , >> >> Added: head/lib/libpmc/pmc.soft.3 >> ============================================================================== >> --- /dev/null 00:00:00 1970 (empty, because file is newly added) >> +++ head/lib/libpmc/pmc.soft.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -0,0 +1,104 @@ >> +.\" Copyright (c) 2012 Fabien Thomas. All rights reserved. >> +.\" >> +.\" Redistribution and use in source and binary forms, with or without >> +.\" modification, are permitted provided that the following conditions >> +.\" are met: >> +.\" 1. Redistributions of source code must retain the above copyright >> +.\" notice, this list of conditions and the following disclaimer. >> +.\" 2. Redistributions in binary form must reproduce the above copyright >> +.\" notice, this list of conditions and the following disclaimer in the >> +.\" documentation and/or other materials provided with the distribution. >> +.\" >> +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >> +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >> +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >> +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >> +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >> +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >> +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >> +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >> +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >> +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >> +.\" SUCH DAMAGE. >> +.\" >> +.\" $FreeBSD$ >> +.\" >> +.Dd March 28, 2012 >> +.Os >> +.Dt PMC.SOFT 3 >> +.Sh NAME >> +.Nm pmc.soft >> +.Nd measurements using software based events >> +.Sh LIBRARY >> +.Lb libpmc >> +.Sh SYNOPSIS >> +.In pmc.h >> +.Sh DESCRIPTION >> +Software events are used to collect various source of software events. >> +.Ss PMC Features >> +16 sampling counters using software events based on various sources. >> +These PMCs support the following capabilities: >> +.Bl -column "PMC_CAP_INTERRUPT" "Support" >> +.It Em Capability Ta Em Support >> +.It PMC_CAP_CASCADE Ta \&No >> +.It PMC_CAP_EDGE Ta \&No >> +.It PMC_CAP_INTERRUPT Ta Yes >> +.It PMC_CAP_INVERT Ta \&No >> +.It PMC_CAP_READ Ta Yes >> +.It PMC_CAP_PRECISE Ta \&No >> +.It PMC_CAP_SYSTEM Ta Yes >> +.It PMC_CAP_TAGGING Ta \&No >> +.It PMC_CAP_THRESHOLD Ta \&No >> +.It PMC_CAP_USER Ta Yes >> +.It PMC_CAP_WRITE Ta Yes >> +.El >> +.Ss Event Qualifiers >> +There is no supported event qualifier. >> +.Pp >> +The event specifiers supported by software are: >> +.Bl -tag -width indent >> +.It Li CLOCK.HARD >> +Hard clock ticks. >> +.It Li CLOCK.STAT >> +Stat clock ticks. >> +.It Li LOCK.FAILED >> +Lock acquisition failed. >> +.It Li PAGE_FAULT.ALL >> +All page fault type. >> +.It Li PAGE_FAULT.READ >> +Read page fault. >> +.It Li PAGE_FAULT.WRITE >> +Write page fault. >> +.El >> +.Sh SEE ALSO >> +.Xr pmc 3 , >> +.Xr pmc.atom 3 , >> +.Xr pmc.core 3 , >> +.Xr pmc.iaf 3 , >> +.Xr pmc.ucf 3 , >> +.Xr pmc.k7 3 , >> +.Xr pmc.k8 3 , >> +.Xr pmc.p4 3 , >> +.Xr pmc.p5 3 , >> +.Xr pmc.p6 3 , >> +.Xr pmc.corei7 3 , >> +.Xr pmc.corei7uc 3 , >> +.Xr pmc.westmereuc 3 , >> +.Xr pmc.tsc 3 , >> +.Xr pmc_cpuinfo 3 , >> +.Xr pmclog 3 , >> +.Xr hwpmc 4 >> +.Sh HISTORY >> +The >> +.Nm pmc >> +library first appeared in >> +.Fx 6.0 . >> +.Sh AUTHORS >> +The >> +.Lb libpmc >> +library was written by >> +.An "Joseph Koshy" >> +.Aq [hidden email] . >> +Software PMC was written by >> +.An "Fabien Thomas" >> +.Aq [hidden email] . >> >> Modified: head/lib/libpmc/pmc.tsc.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -68,6 +68,7 @@ maps to the TSC. >> .Xr pmc.p4 3 , >> .Xr pmc.p5 3 , >> .Xr pmc.p6 3 , >> +.Xr pmc.soft 3 , >> .Xr pmclog 3 , >> .Xr hwpmc 4 >> .Sh HISTORY >> >> Modified: head/lib/libpmc/pmc.ucf.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -96,6 +96,7 @@ offset C0H under device number 0 and Fun >> .Xr pmc.corei7uc 3 , >> .Xr pmc.westmere 3 , >> .Xr pmc.westmereuc 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.westmere.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shif >> .Xr pmc.corei7 3 , >> .Xr pmc.corei7uc 3 , >> .Xr pmc.westmereuc 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.westmereuc.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1066,6 +1066,7 @@ disabled. >> .Xr pmc.corei7 3 , >> .Xr pmc.corei7uc 3 , >> .Xr pmc.westmere 3 , >> +.Xr pmc.soft 3 , >> .Xr pmc.tsc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> >> Modified: head/lib/libpmc/pmc.xscale.3 >> ============================================================================== >> --- head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:58:30 2012 (r233628) >> @@ -134,6 +134,7 @@ and the underlying hardware events used. >> .Xr pmc 3 , >> .Xr pmc_cpuinfo 3 , >> .Xr pmclog 3 , >> +.Xr pmc.soft 3 , >> .Xr hwpmc 4 >> .Sh HISTORY >> The >> >> Modified: head/lib/libpmc/pmclog.c >> ============================================================================== >> --- head/lib/libpmc/pmclog.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmclog.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **da >> == NULL) >> goto error; >> break; >> + case PMCLOG_TYPE_PMCALLOCATEDYN: >> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid); >> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event); >> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags); >> + PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX); >> + break; >> case PMCLOG_TYPE_PMCATTACH: >> PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach); >> PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid); >> >> Modified: head/lib/libpmc/pmclog.h >> ============================================================================== >> --- head/lib/libpmc/pmclog.h Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/lib/libpmc/pmclog.h Wed Mar 28 20:58:30 2012 (r233628) >> @@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate { >> pmc_id_t pl_pmcid; >> }; >> >> +struct pmclog_ev_pmcallocatedyn { >> + uint32_t pl_event; >> + char pl_evname[PMC_NAME_MAX]; >> + uint32_t pl_flags; >> + pmc_id_t pl_pmcid; >> +}; >> + >> struct pmclog_ev_pmcattach { >> pmc_id_t pl_pmcid; >> pid_t pl_pid; >> @@ -146,6 +153,7 @@ struct pmclog_ev { >> struct pmclog_ev_map_out pl_mo; >> struct pmclog_ev_pcsample pl_s; >> struct pmclog_ev_pmcallocate pl_a; >> + struct pmclog_ev_pmcallocatedyn pl_ad; >> struct pmclog_ev_pmcattach pl_t; >> struct pmclog_ev_pmcdetach pl_d; >> struct pmclog_ev_proccsw pl_c; >> >> Modified: head/sys/amd64/amd64/trap.c >> ============================================================================== >> --- head/sys/amd64/amd64/trap.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/amd64/amd64/trap.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$"); >> #include <sys/vmmeter.h> >> #ifdef HWPMC_HOOKS >> #include <sys/pmckern.h> >> +PMC_SOFT_DEFINE( , , page_fault, all); >> +PMC_SOFT_DEFINE( , , page_fault, read); >> +PMC_SOFT_DEFINE( , , page_fault, write); >> #endif >> >> #include <vm/vm.h> >> @@ -743,8 +746,20 @@ trap_pfault(frame, usermode) >> */ >> rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); >> } >> - if (rv == KERN_SUCCESS) >> + if (rv == KERN_SUCCESS) { >> +#ifdef HWPMC_HOOKS >> + if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) { >> + PMC_SOFT_CALL_TF( , , page_fault, all, frame); >> + if (ftype == VM_PROT_READ) >> + PMC_SOFT_CALL_TF( , , page_fault, read, >> + frame); >> + else >> + PMC_SOFT_CALL_TF( , , page_fault, write, >> + frame); >> + } >> +#endif >> return (0); >> + } >> nogo: >> if (!usermode) { >> if (td->td_intr_nesting_level == 0 && >> >> Modified: head/sys/amd64/include/pmc_mdep.h >> ============================================================================== >> --- head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >> @@ -50,13 +50,13 @@ struct pmc_mdep; >> * measurement architecture have PMCs of the following classes: TSC, >> * IAF, IAP, UCF and UCP. >> */ >> -#define PMC_MDEP_CLASS_INDEX_TSC 0 >> -#define PMC_MDEP_CLASS_INDEX_K8 1 >> -#define PMC_MDEP_CLASS_INDEX_P4 1 >> -#define PMC_MDEP_CLASS_INDEX_IAP 1 >> -#define PMC_MDEP_CLASS_INDEX_IAF 2 >> -#define PMC_MDEP_CLASS_INDEX_UCP 3 >> -#define PMC_MDEP_CLASS_INDEX_UCF 4 >> +#define PMC_MDEP_CLASS_INDEX_TSC 1 >> +#define PMC_MDEP_CLASS_INDEX_K8 2 >> +#define PMC_MDEP_CLASS_INDEX_P4 2 >> +#define PMC_MDEP_CLASS_INDEX_IAP 2 >> +#define PMC_MDEP_CLASS_INDEX_IAF 3 >> +#define PMC_MDEP_CLASS_INDEX_UCP 4 >> +#define PMC_MDEP_CLASS_INDEX_UCF 5 >> >> /* >> * On the amd64 platform we support the following PMCs. >> @@ -119,6 +119,15 @@ union pmc_md_pmc { >> >> #define PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS) >> >> +/* Build a fake kernel trapframe from current instruction pointer. */ >> +#define PMC_FAKE_TRAPFRAME(TF) \ >> + do { \ >> + (TF)->tf_cs = 0; (TF)->tf_rflags = 0; \ >> + __asm __volatile("movq %%rbp,%0" : "=r" ((TF)->tf_rbp)); \ >> + __asm __volatile("movq %%rsp,%0" : "=r" ((TF)->tf_rsp)); \ >> + __asm __volatile("call 1f \n\t1: pop %0" : "=r"((TF)->tf_rip)); \ >> + } while (0) >> + >> /* >> * Prototypes >> */ >> >> Modified: head/sys/arm/include/pmc_mdep.h >> ============================================================================== >> --- head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >> @@ -29,7 +29,7 @@ >> #ifndef _MACHINE_PMC_MDEP_H_ >> #define _MACHINE_PMC_MDEP_H_ >> >> -#define PMC_MDEP_CLASS_INDEX_XSCALE 0 >> +#define PMC_MDEP_CLASS_INDEX_XSCALE 1 >> /* >> * On the ARM platform we support the following PMCs. >> * >> >> Modified: head/sys/conf/files >> ============================================================================== >> --- head/sys/conf/files Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/conf/files Wed Mar 28 20:58:30 2012 (r233628) >> @@ -1260,6 +1260,7 @@ dev/hme/if_hme_sbus.c optional hme sbus >> dev/hptiop/hptiop.c optional hptiop scbus >> dev/hwpmc/hwpmc_logging.c optional hwpmc >> dev/hwpmc/hwpmc_mod.c optional hwpmc >> +dev/hwpmc/hwpmc_soft.c optional hwpmc >> dev/ichsmb/ichsmb.c optional ichsmb >> dev/ichsmb/ichsmb_pci.c optional ichsmb pci >> dev/ida/ida.c optional ida >> >> Modified: head/sys/dev/hwpmc/hwpmc_amd.c >> ============================================================================== >> --- head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -687,7 +687,8 @@ amd_intr(int cpu, struct trapframe *tf) >> wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v)); >> >> /* Restart the counter if logging succeeded. */ >> - error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf)); >> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >> + TRAPF_USERMODE(tf)); >> if (error == 0) >> wrmsr(evsel, config | AMD_PMC_ENABLE); >> } >> @@ -874,7 +875,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int c >> struct pmc_mdep * >> pmc_amd_initialize(void) >> { >> - int classindex, error, i, nclasses, ncpus; >> + int classindex, error, i, ncpus; >> struct pmc_classdep *pcd; >> enum pmc_cputype cputype; >> struct pmc_mdep *pmc_mdep; >> @@ -926,12 +927,9 @@ pmc_amd_initialize(void) >> * These processors have two classes of PMCs: the TSC and >> * programmable PMCs. >> */ >> - nclasses = 2; >> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * sizeof (struct pmc_classdep), >> - M_PMC, M_WAITOK|M_ZERO); >> + pmc_mdep = pmc_mdep_alloc(2); >> >> pmc_mdep->pmd_cputype = cputype; >> - pmc_mdep->pmd_nclass = nclasses; >> >> ncpus = pmc_cpu_max(); >> >> >> Modified: head/sys/dev/hwpmc/hwpmc_core.c >> ============================================================================== >> --- head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -2239,7 +2239,7 @@ core_intr(int cpu, struct trapframe *tf) >> if (pm->pm_state != PMC_STATE_RUNNING) >> continue; >> >> - error = pmc_process_interrupt(cpu, pm, tf, >> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >> TRAPF_USERMODE(tf)); >> >> v = pm->pm_sc.pm_reloadcount; >> @@ -2326,7 +2326,7 @@ core2_intr(int cpu, struct trapframe *tf >> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >> continue; >> >> - error = pmc_process_interrupt(cpu, pm, tf, >> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >> TRAPF_USERMODE(tf)); >> if (error) >> intrenable &= ~flag; >> @@ -2354,7 +2354,7 @@ core2_intr(int cpu, struct trapframe *tf >> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >> continue; >> >> - error = pmc_process_interrupt(cpu, pm, tf, >> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >> TRAPF_USERMODE(tf)); >> if (error) >> intrenable &= ~flag; >> >> Modified: head/sys/dev/hwpmc/hwpmc_intel.c >> ============================================================================== >> --- head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -162,12 +162,10 @@ pmc_intel_initialize(void) >> return (NULL); >> } >> >> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * >> - sizeof(struct pmc_classdep), M_PMC, M_WAITOK|M_ZERO); >> + /* Allocate base class and initialize machine dependent struct */ >> + pmc_mdep = pmc_mdep_alloc(nclasses); >> >> pmc_mdep->pmd_cputype = cputype; >> - pmc_mdep->pmd_nclass = nclasses; >> - >> pmc_mdep->pmd_switch_in = intel_switch_in; >> pmc_mdep->pmd_switch_out = intel_switch_out; >> >> >> Modified: head/sys/dev/hwpmc/hwpmc_logging.c >> ============================================================================== >> --- head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -129,6 +129,7 @@ static struct mtx pmc_kthread_mtx; /* sl >> >> /* Emit a string. Caution: does NOT update _le, so needs to be last */ >> #define PMCLOG_EMITSTRING(S,L) do { bcopy((S), _le, (L)); } while (0) >> +#define PMCLOG_EMITNULLSTRING(L) do { bzero(_le, (L)); } while (0) >> >> #define PMCLOG_DESPATCH(PO) \ >> pmclog_release((PO)); \ >> @@ -835,16 +836,33 @@ void >> pmclog_process_pmcallocate(struct pmc *pm) >> { >> struct pmc_owner *po; >> + struct pmc_soft *ps; >> >> po = pm->pm_owner; >> >> PMCDBG(LOG,ALL,1, "pm=%p", pm); >> >> - PMCLOG_RESERVE(po, PMCALLOCATE, sizeof(struct pmclog_pmcallocate)); >> - PMCLOG_EMIT32(pm->pm_id); >> - PMCLOG_EMIT32(pm->pm_event); >> - PMCLOG_EMIT32(pm->pm_flags); >> - PMCLOG_DESPATCH(po); >> + if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) { >> + PMCLOG_RESERVE(po, PMCALLOCATEDYN, >> + sizeof(struct pmclog_pmcallocatedyn)); >> + PMCLOG_EMIT32(pm->pm_id); >> + PMCLOG_EMIT32(pm->pm_event); >> + PMCLOG_EMIT32(pm->pm_flags); >> + ps = pmc_soft_ev_acquire(pm->pm_event); >> + if (ps != NULL) >> + PMCLOG_EMITSTRING(ps->ps_ev.pm_ev_name,PMC_NAME_MAX); >> + else >> + PMCLOG_EMITNULLSTRING(PMC_NAME_MAX); >> + pmc_soft_ev_release(ps); >> + PMCLOG_DESPATCH(po); >> + } else { >> + PMCLOG_RESERVE(po, PMCALLOCATE, >> + sizeof(struct pmclog_pmcallocate)); >> + PMCLOG_EMIT32(pm->pm_id); >> + PMCLOG_EMIT32(pm->pm_event); >> + PMCLOG_EMIT32(pm->pm_flags); >> + PMCLOG_DESPATCH(po); >> + } >> } >> >> void >> >> Modified: head/sys/dev/hwpmc/hwpmc_mips.c >> ============================================================================== >> --- head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -287,7 +287,7 @@ mips_pmc_intr(int cpu, struct trapframe >> retval = 1; >> if (pm->pm_state != PMC_STATE_RUNNING) >> continue; >> - error = pmc_process_interrupt(cpu, pm, tf, >> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >> TRAPF_USERMODE(tf)); >> if (error) { >> /* Clear/disable the relevant counter */ >> >> Modified: head/sys/dev/hwpmc/hwpmc_mod.c >> ============================================================================== >> --- head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:49:11 2012 (r233627) >> +++ head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:58:30 2012 (r233628) >> @@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$"); >> #include <vm/vm_map.h> >> #include <vm/vm_object.h> >> >> +#include "hwpmc_soft.h" >> + >> /* >> * Types >> */ >> @@ -182,7 +184,7 @@ static int pmc_attach_one_process(struct >> static int pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, >> int cpu); >> static int pmc_can_attach(struct pmc *pm, struct proc *p); >> -static void pmc_capture_user_callchain(int cpu, struct trapframe *tf); >> +static void pmc_capture_user_callchain(int cpu, int soft, struct trapframe *tf); >> static void pmc_cleanup(void); >> static int pmc_detach_process(struct proc *p, struct pmc *pm); >> static int pmc_detach_one_process(struct proc *p, struct pmc *pm, >> @@ -206,7 +208,7 @@ static void pmc_process_csw_out(struct t >> static void pmc_process_exit(void *arg, struct proc *p); >> static void pmc_process_fork(void *arg, struct proc *p1, >> struct proc *p2, int n); >> -static void pmc_process_samples(int cpu); >> +static void pmc_process_samples(int cpu, int soft); >> static void pmc_release_pmc_descriptor(struct pmc *pmc); >> static void pmc_remove_owner(struct pmc_owner *po); >> static void pmc_remove_process_descriptor(struct pmc_process *pp); >> @@ -218,12 +220,16 @@ static int pmc_stop(struct pmc *pm); >> static int pmc_syscall_handler(struct thread *td, void *syscall_args); >> static void pmc_unlink_target_process(struct pmc *pmc, >> struct pmc_process *pp); >> +static int generic_switch_in(struct pmc_cpu *pc, struct pmc_process *pp); >> +static int generic_switch_out(struct pmc_cpu *pc, struct pmc_process *pp); >> +static struct pmc_mdep *pmc_generic_cpu_initialize(void); >> +static void pmc_generic_cpu_finalize(struct pmc_mdep *md); >> >> /* >> * Kernel tunables and sysctl(8) interface. >> */ >> >> -SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters"); >> +SYSCTL_DECL(_kern_hwpmc); >> >> static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; >> TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "callchaindepth", &pmc_callchaindepth); >> @@ -1833,7 +1839,9 @@ const char *pmc_hooknames[] = { >> "KLDUNLOAD", >> "MMAP", >> "MUNMAP", >> - "CALLCHAIN" >> + "CALLCHAIN-NMI", >> + "CALLCHAIN-SOFT", >> + "SOFTSAMPLING" >> }; >> #endif >> >> @@ -1992,7 +2000,8 @@ pmc_hook_handler(struct thread *td, int >> * lose the interrupt sample. >> */ >> CPU_CLR_ATOMIC(PCPU_GET(cpuid), &pmc_cpumask); >> - pmc_process_samples(PCPU_GET(cpuid)); >> + pmc_process_samples(PCPU_GET(cpuid), PMC_HR); >> + pmc_process_samples(PCPU_GET(cpuid), PMC_SR); >> break; >> >> >> @@ -2022,11 +2031,30 @@ pmc_hook_handler(struct thread *td, int >> */ >> KASSERT(td == curthread, ("[pmc,%d] td != curthread", >> __LINE__)); >> - pmc_capture_user_callchain(PCPU_GET(cpuid), >> + >> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_HR, >> (struct trapframe *) arg); >> td->td_pflags &= ~TDP_CALLCHAIN; >> break; >> >> + case PMC_FN_USER_CALLCHAIN_SOFT: >> + /* >> + * Record a call chain. >> + */ >> + KASSERT(td == curthread, ("[pmc,%d] td != curthread", >> + __LINE__)); >> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_SR, >> + (struct trapframe *) arg); >> + td->td_pflags &= ~TDP_CALLCHAIN; >> + break; >> + >> + case PMC_FN_SOFT_SAMPLING: >> + /* >> + * Call soft PMC sampling intr. >> + */ >> + pmc_soft_intr((struct pmckern_soft *) arg); >> + break; >> + >> default: >> #ifdef DEBUG >> KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function)); >> @@ -2221,18 +2249,17 @@ pmc_destroy_pmc_descriptor(struct pmc *p >> static void >> pmc_wait_for_pmc_idle(struct pmc *pm) >> { >> -#ifdef DEBUG >> +#ifdef DEBUG >> volatile int maxloop; >> >> maxloop = 100 * pmc_cpu_max(); >> #endif >> - >> /* >> * Loop (with a forced context switch) till the PMC's runcount >> * comes down to zero. >> */ >> while (atomic_load_acq_32(&pm->pm_runcount) > 0) { >> -#ifdef DEBUG >> +#ifdef DEBUG >> maxloop--; >> KASSERT(maxloop > 0, >> ("[pmc,%d] (ri%d, rc%d) waiting too long for " >> @@ -2972,6 +2999,53 @@ pmc_syscall_handler(struct thread *td, v >> } >> break; >> >> + /* >> + * Retrieve soft events list. >> + */ >> + case PMC_OP_GETDYNEVENTINFO: >> + { >> + enum pmc_class cl; >> + enum pmc_event ev; >> + struct pmc_op_getdyneventinfo *gei; >> + struct pmc_dyn_event_descr dev; >> + struct pmc_soft *ps; >> + uint32_t nevent; >> + >> + sx_assert(&pmc_sx, SX_LOCKED); >> + >> + gei = (struct pmc_op_getdyneventinfo *) arg; >> + >> + if ((error = copyin(&gei->pm_class, &cl, sizeof(cl))) != 0) >> + break; >> + >> + /* Only SOFT class is dynamic. */ >> + if (cl != PMC_CLASS_SOFT) { >> + error = EINVAL; >> + break; >> + } >> + >> + nevent = 0; >> + for (ev = PMC_EV_SOFT_FIRST; ev <= PMC_EV_SOFT_LAST; ev++) { >> + ps = pmc_soft_ev_acquire(ev); >> + if (ps == NULL) >> + continue; >> + bcopy(&ps->ps_ev, &dev, sizeof(dev)); >> + pmc_soft_ev_release(ps); >> + >> + error = copyout(&dev, >> + &gei->pm_events[nevent], >> + sizeof(struct pmc_dyn_event_descr)); >> + if (error != 0) >> + break; >> + nevent++; >> + } >> + if (error != 0) >> + break; >> + >> + error = copyout(&nevent, &gei->pm_nevent, >> >> *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** -- Monthadar Al Jaberi _______________________________________________ [hidden email] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-mips To unsubscribe, send any mail to "[hidden email]" |
|
Hi,
The rumors seems true :) Can you try the patch attached (I cannot test as i've no MIPS hardware) ? Thanks, Fabien > On Mon, Apr 23, 2012 at 8:44 AM, Adrian Chadd <[hidden email]> wrote: >> Hi Fabien, >> >> I've heard some rumours that this broke hwpmc support for mips24k. >> >> Monthadar, can you please provide some background info for this? >> > > This is the log output > > Using default protocol (TFTP) > Entry point: 0x80050100, address range: 0x80050000-0x804f1dcc > RedBoot> exec > Now booting linux kernel: > Base address 0x80050000 Entry 0x80050100 > memsize=0x08000000 > modetty0=0,n,8,1,hw > board=RouterStation PRO > ethaddr=00.15.6d.c8.c9.2e > CPU platform: Atheros AR7161 rev 2 > CPU Frequency=720 MHz > CPU DDR Frequency=360 MHz > CPU AHB Frequency=180 MHz > platform frequency: 720000000 > arguments: > a0 = 00000002 > a1 = 80050028 > a2 = 80050000 > a3 = 00000001 > Cmd line: �������m���������������_}������߾q��������������������������������߿���������_�w���������?-����{������~�� > Environment: > memsize = 0x08000000 > modetty0 = 0,n,8,1,hw > ethaddr = 00.15.6d.c8.c9.2e > board = RouterStation PRO > Cache info: > picache_stride = 4096 > picache_loopcount = 16 > pdcache_stride = 4096 > pdcache_loopcount = 8 > cpu0: MIPS Technologies processor v116.147 > MMU: Standard TLB, 16 entries > L1 i-cache: 4 ways of 512 sets, 32 bytes per line > L1 d-cache: 4 ways of 256 sets, 32 bytes per line > Config1=0x9ee3519e<PerfCount,WatchRegs,MIPS16,EJTAG> > Config3=0x20 > KDB: debugger backends: ddb > KDB: current backend: ddb > Copyright (c) 1992-2012 The FreeBSD Project. > Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 > The Regents of the University of California. All rights reserved. > FreeBSD is a registered trademark of The FreeBSD Foundation. > FreeBSD 10.0-CURRENT #12: Fri Apr 20 18:03:16 CEST 2012 > root@freebsd-re-9:/usr/obj/mips.mips/usr/src/sys/RSPRO_USB_PROD mips > WARNING: WITNESS option enabled, expect reduced performance. > MEMGUARD DEBUGGING ALLOCATOR INITIALIZED: > MEMGUARD map base: 0xc0800000 > MEMGUARD map limit: 0xc1c00000 > MEMGUARD map size: 20480 KBytes > real memory = 134217728 (131072K bytes) > avail memory = 123117568 (117MB) > random device not loaded; using insecure entropy > nexus0: <MIPS32 root nexus> > clock0: <Generic MIPS32 ticker> on nexus0 > Timecounter "MIPS32" frequency 360000000 Hz quality 800 > Event timer "MIPS32" frequency 360000000 Hz quality 800 > apb0 at irq 4 on nexus0 > uart0: <16550 or compatible> on apb0 > uart0: console (115200,n,8,1) > gpio0: <Atheros AR71XX GPIO driver> on apb0 > gpio0: [GIANT-LOCKED] > gpio0: gpio pinmask=0x0 > gpioc0: <GPIO controller> on gpio0 > gpiobus0: <GPIO bus> on gpio0 > ehci0: <AR71XX Integrated USB 2.0 controller> at mem > 0x1b000000-0x1bffffff irq 1 on nexus0 > usbus0: set host controller mode > usbus0: EHCI version 1.0 > usbus0: set host controller mode > usbus0 on ehci0 > pcib0 at irq 0 on nexus0 > pci0: <PCI bus> on pcib0 > pci0: <old, non-VGA display device> at device 0.0 (no driver attached) > ath0: <Atheros 5413> irq 0 at device 17.0 on pci0 > ath0: AR5413 mac 10.5 RF5413 phy 6.1 > ath0: 2GHz radio: 0x0000; 5GHz radio: 0x0063 > arge0: <Atheros AR71xx built-in ethernet interface> at mem > 0x19000000-0x19000fff irq 2 on nexus0 > arge0: No PHY specified, using mask 16 > miibus0: <MII bus> on arge0 > ukphy0: <Generic IEEE 802.3u media interface> PHY 4 on miibus0 > ukphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, > 1000baseT-FDX, 1000baseT-FDX-master, auto > arge0: Ethernet address: 00:15:6d:c8:c9:2e > arge1: <Atheros AR71xx built-in ethernet interface> at mem > 0x1a000000-0x1a000fff irq 3 on nexus0 > arge1: No PHY specified, using mask 15 > arge1: Ethernet address: 00:15:6d:c8:c9:2f > spi0: <AR71XX SPI> at mem 0x1f000000-0x1f00000f on nexus0 > spibus0: <spibus bus> on spi0 > mx25l0: <M25Pxx Flash Family> at cs 0 on spibus0 > mx25l0: mx25ll128, sector 65536 bytes, 256 sectors > ar71xx_wdog0: <Atheros AR71XX watchdog timer> on nexus0 > Timecounters tick every 1.000 msec > usbus0: 480Mbps High Speed USB v2.0 > ugen0.1: <Atheros> at usbus0 > uhub0: <Atheros EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0 > panic: [pmc,4816] npmc miscomputed: ri=0, md->npmc=2 > KDB: enter: panic > [ thread pid 0 tid 100000 ] > Stopped at kdb_enter+0x4c: lui at,0x8050 > db> tr > Tracing pid 0 tid 100000 td 0x804f76d0 > db_trace_thread+30 (?,?,?,?) ra 8068b94800000018 sp 0 sz 0 > 80075adc+114 (0,?,ffffffff,?) ra 8068b96000000020 sp 100000000 sz 1 > 80074e24+388 (?,?,?,?) ra 8068b980000000a8 sp 0 sz 0 > db_command_loop+70 (?,?,?,?) ra 8068ba2800000018 sp 0 sz 0 > 80077900+f4 (?,?,?,?) ra 8068ba40000001a8 sp 0 sz 0 > kdb_trap+110 (?,?,?,?) ra 8068bbe800000030 sp 0 sz 0 > trap+c7c (?,?,?,?) ra 8068bc18000000b8 sp 0 sz 0 > MipsKernGenException+134 (0,4,8043b1d4,119) ra 8068bcd0000000c8 sp > 100000001 sz 1 > kdb_enter+4c (?,?,?,?) ra 8068bd9800000018 sp 0 sz 0 > panic+11c (?,12d0,0,2) ra 8068bdb000000028 sp 1 sz 1 > 800e8ca8+274 (?,?,?,?) ra 8068bdd800000038 sp 0 sz 0 > syscall_module_handler+b8 (?,?,?,?) ra 8068be1000000028 sp 0 sz 0 > module_register_init+9c (?,?,?,?) ra 8068be3800000028 sp 0 sz 0 > mi_startup+138 (?,?,?,?) ra 8068be6000000020 sp 0 sz 0 > _start+90 (?,?,?,?) ra 8068be8000000000 sp 0 sz 0 > pid 0 > db> > >> Thanks, >> >> >> >> adrian >> >> On 28 March 2012 13:58, Fabien Thomas <[hidden email]> wrote: >>> Author: fabient >>> Date: Wed Mar 28 20:58:30 2012 >>> New Revision: 233628 >>> URL: http://svn.freebsd.org/changeset/base/233628 >>> >>> Log: >>> Add software PMC support. >>> >>> New kernel events can be added at various location for sampling or counting. >>> This will for example allow easy system profiling whatever the processor is >>> with known tools like pmcstat(8). >>> >>> Simultaneous usage of software PMC and hardware PMC is possible, for example >>> looking at the lock acquire failure, page fault while sampling on >>> instructions. >>> >>> Sponsored by: NETASQ >>> MFC after: 1 month >>> >>> Added: >>> head/lib/libpmc/pmc.soft.3 (contents, props changed) >>> head/sys/dev/hwpmc/hwpmc_soft.c (contents, props changed) >>> head/sys/dev/hwpmc/hwpmc_soft.h (contents, props changed) >>> Modified: >>> head/lib/libpmc/Makefile >>> head/lib/libpmc/libpmc.c >>> head/lib/libpmc/pmc.3 >>> head/lib/libpmc/pmc.atom.3 >>> head/lib/libpmc/pmc.core.3 >>> head/lib/libpmc/pmc.core2.3 >>> head/lib/libpmc/pmc.corei7.3 >>> head/lib/libpmc/pmc.corei7uc.3 >>> head/lib/libpmc/pmc.iaf.3 >>> head/lib/libpmc/pmc.k7.3 >>> head/lib/libpmc/pmc.k8.3 >>> head/lib/libpmc/pmc.mips24k.3 >>> head/lib/libpmc/pmc.octeon.3 >>> head/lib/libpmc/pmc.p4.3 >>> head/lib/libpmc/pmc.p5.3 >>> head/lib/libpmc/pmc.p6.3 >>> head/lib/libpmc/pmc.sandybridge.3 >>> head/lib/libpmc/pmc.sandybridgeuc.3 >>> head/lib/libpmc/pmc.tsc.3 >>> head/lib/libpmc/pmc.ucf.3 >>> head/lib/libpmc/pmc.westmere.3 >>> head/lib/libpmc/pmc.westmereuc.3 >>> head/lib/libpmc/pmc.xscale.3 >>> head/lib/libpmc/pmclog.c >>> head/lib/libpmc/pmclog.h >>> head/sys/amd64/amd64/trap.c >>> head/sys/amd64/include/pmc_mdep.h >>> head/sys/arm/include/pmc_mdep.h >>> head/sys/conf/files >>> head/sys/dev/hwpmc/hwpmc_amd.c >>> head/sys/dev/hwpmc/hwpmc_core.c >>> head/sys/dev/hwpmc/hwpmc_intel.c >>> head/sys/dev/hwpmc/hwpmc_logging.c >>> head/sys/dev/hwpmc/hwpmc_mips.c >>> head/sys/dev/hwpmc/hwpmc_mod.c >>> head/sys/dev/hwpmc/hwpmc_piv.c >>> head/sys/dev/hwpmc/hwpmc_powerpc.c >>> head/sys/dev/hwpmc/hwpmc_ppro.c >>> head/sys/dev/hwpmc/hwpmc_tsc.c >>> head/sys/dev/hwpmc/hwpmc_x86.c >>> head/sys/dev/hwpmc/hwpmc_xscale.c >>> head/sys/dev/hwpmc/pmc_events.h >>> head/sys/i386/i386/trap.c >>> head/sys/i386/include/pmc_mdep.h >>> head/sys/kern/kern_clock.c >>> head/sys/kern/kern_lock.c >>> head/sys/kern/kern_mutex.c >>> head/sys/kern/kern_pmc.c >>> head/sys/kern/kern_rwlock.c >>> head/sys/kern/kern_sx.c >>> head/sys/kern/subr_trap.c >>> head/sys/mips/include/pmc_mdep.h >>> head/sys/modules/hwpmc/Makefile >>> head/sys/powerpc/include/pmc_mdep.h >>> head/sys/sys/pmc.h >>> head/sys/sys/pmckern.h >>> head/sys/sys/pmclog.h >>> head/usr.sbin/pmcstat/pmcstat_log.c >>> >>> Modified: head/lib/libpmc/Makefile >>> ============================================================================== >>> --- head/lib/libpmc/Makefile Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/Makefile Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -20,6 +20,7 @@ MAN+= pmc_read.3 >>> MAN+= pmc_set.3 >>> MAN+= pmc_start.3 >>> MAN+= pmclog.3 >>> +MAN+= pmc.soft.3 >>> >>> # PMC-dependent manual pages >>> .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" >>> >>> Modified: head/lib/libpmc/libpmc.c >>> ============================================================================== >>> --- head/lib/libpmc/libpmc.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/libpmc.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_eve >>> static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >>> struct pmc_op_pmcallocate *_pmc_config); >>> #endif >>> - >>> #if defined(__mips__) >>> static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec, >>> struct pmc_op_pmcallocate *_pmc_config); >>> #endif /* __mips__ */ >>> +static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >>> + struct pmc_op_pmcallocate *_pmc_config); >>> >>> #if defined(__powerpc__) >>> static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec, >>> @@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON); >>> PMC_CLASSDEP_TABLE(ucf, UCF); >>> PMC_CLASSDEP_TABLE(ppc7450, PPC7450); >>> >>> +static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; >>> + >>> #undef __PMC_EV_ALIAS >>> #define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE }, >>> >>> @@ -215,21 +218,22 @@ static const struct pmc_event_descr west >>> PMC_CLASS_##C, __VA_ARGS__ \ >>> } >>> >>> -PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>> -PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>> -PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>> -PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC); >>> -PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE); >>> -PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K); >>> -PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON); >>> -PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450); >>> +PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>> +PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>> +PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>> +PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>> +PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); >>> +PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); >>> +PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); >>> +PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); >>> +PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); >>> >>> static const struct pmc_event_descr tsc_event_table[] = >>> { >>> @@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc) >>> #if defined(__XSCALE__) >>> PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale); >>> #endif >>> - >>> #if defined(__mips__) >>> PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); >>> PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); >>> #endif /* __mips__ */ >>> - >>> #if defined(__powerpc__) >>> PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450); >>> #endif >>> >>> +static struct pmc_class_descr soft_class_table_descr = >>> +{ >>> + .pm_evc_name = "SOFT-", >>> + .pm_evc_name_size = sizeof("SOFT-") - 1, >>> + .pm_evc_class = PMC_CLASS_SOFT, >>> + .pm_evc_event_table = NULL, >>> + .pm_evc_event_table_size = 0, >>> + .pm_evc_allocate_pmc = soft_allocate_pmc >>> +}; >>> + >>> #undef PMC_CLASS_TABLE_DESC >>> >>> static const struct pmc_class_descr **pmc_class_table; >>> @@ -343,9 +355,12 @@ static const char * pmc_state_names[] = >>> __PMC_STATES() >>> }; >>> >>> -static int pmc_syscall = -1; /* filled in by pmc_init() */ >>> - >>> -static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */ >>> +/* >>> + * Filled in by pmc_init(). >>> + */ >>> +static int pmc_syscall = -1; >>> +static struct pmc_cpuinfo cpu_info; >>> +static struct pmc_op_getdyneventinfo soft_event_info; >>> >>> /* Event masks for events */ >>> struct pmc_masks { >>> @@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char >>> } >>> #endif >>> >>> +static struct pmc_event_alias generic_aliases[] = { >>> + EV_ALIAS("instructions", "SOFT-CLOCK.HARD"), >>> + EV_ALIAS(NULL, NULL) >>> +}; >>> + >>> +static int >>> +soft_allocate_pmc(enum pmc_event pe, char *ctrspec, >>> + struct pmc_op_pmcallocate *pmc_config) >>> +{ >>> + (void)ctrspec; >>> + (void)pmc_config; >>> + >>> + if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST) >>> + return (-1); >>> + >>> + pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); >>> + return (0); >>> +} >>> + >>> #if defined(__XSCALE__) >>> >>> static struct pmc_event_alias xscale_aliases[] = { >>> @@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class >>> ev = ppc7450_event_table; >>> count = PMC_EVENT_TABLE_SIZE(ppc7450); >>> break; >>> + case PMC_CLASS_SOFT: >>> + ev = soft_event_table; >>> + count = soft_event_info.pm_nevent; >>> + break; >>> default: >>> errno = EINVAL; >>> return (-1); >>> @@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class >>> >>> for (;count--; ev++, names++) >>> *names = ev->pm_ev_name; >>> + >>> return (0); >>> } >>> >>> @@ -2780,11 +2819,34 @@ pmc_init(void) >>> pmc_class_table[n] = NULL; >>> >>> /* >>> + * Get soft events list. >>> + */ >>> + soft_event_info.pm_class = PMC_CLASS_SOFT; >>> + if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0) >>> + return (pmc_syscall = -1); >>> + >>> + /* Map soft events to static list. */ >>> + for (n = 0; n < soft_event_info.pm_nevent; n++) { >>> + soft_event_table[n].pm_ev_name = >>> + soft_event_info.pm_events[n].pm_ev_name; >>> + soft_event_table[n].pm_ev_code = >>> + soft_event_info.pm_events[n].pm_ev_code; >>> + } >>> + soft_class_table_descr.pm_evc_event_table_size = \ >>> + soft_event_info.pm_nevent; >>> + soft_class_table_descr.pm_evc_event_table = \ >>> + soft_event_table; >>> + >>> + /* >>> * Fill in the class table. >>> */ >>> n = 0; >>> + >>> + /* Fill soft events information. */ >>> + pmc_class_table[n++] = &soft_class_table_descr; >>> #if defined(__amd64__) || defined(__i386__) >>> - pmc_class_table[n++] = &tsc_class_table_descr; >>> + if (cpu_info.pm_cputype != PMC_CPU_GENERIC) >>> + pmc_class_table[n++] = &tsc_class_table_descr; >>> >>> /* >>> * Check if this CPU has fixed function counters. >>> @@ -2867,6 +2929,9 @@ pmc_init(void) >>> pmc_class_table[n] = &p4_class_table_descr; >>> break; >>> #endif >>> + case PMC_CPU_GENERIC: >>> + PMC_MDEP_INIT(generic); >>> + break; >>> #if defined(__XSCALE__) >>> case PMC_CPU_INTEL_XSCALE: >>> PMC_MDEP_INIT(xscale); >>> @@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, en >>> evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale); >>> } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) { >>> ev = mips24k_event_table; >>> - evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k >>> -); >>> + evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k); >>> } else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) { >>> ev = octeon_event_table; >>> evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon); >>> } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) { >>> ev = ppc7450_event_table; >>> - evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450 >>> -); >>> + evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450); >>> } else if (pe == PMC_EV_TSC_TSC) { >>> ev = tsc_event_table; >>> evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); >>> + } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) { >>> + ev = soft_event_table; >>> + evfence = soft_event_table + soft_event_info.pm_nevent; >>> } >>> >>> for (; ev != evfence; ev++) >>> >>> Modified: head/lib/libpmc/pmc.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -223,6 +223,8 @@ and >>> CPUs. >>> .It Li PMC_CLASS_TSC >>> The timestamp counter on i386 and amd64 architecture CPUs. >>> +.It Li PMC_CLASS_SOFT >>> +Software events. >>> .El >>> .Ss PMC Capabilities >>> Capabilities of performance monitoring hardware are denoted using >>> @@ -525,6 +527,7 @@ API is >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 , >>> >>> Modified: head/lib/libpmc/pmc.atom.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1176,6 +1176,7 @@ and the underlying hardware events used >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.core.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.core.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.core.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -792,6 +792,7 @@ may not count some transitions. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> >>> Modified: head/lib/libpmc/pmc.core2.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1107,6 +1107,7 @@ and the underlying hardware events used. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.corei7.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1559,6 +1559,7 @@ Counts number of segment register loads. >>> .Xr pmc.corei7uc 3 , >>> .Xr pmc.westmere 3 , >>> .Xr pmc.westmereuc 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.corei7uc.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -863,6 +863,7 @@ refreshed or needs to go into a power do >>> .Xr pmc.corei7 3 , >>> .Xr pmc.westmere 3 , >>> .Xr pmc.westmereuc 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.iaf.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -132,6 +132,7 @@ CPU, use the event specifier >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.k7.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -249,6 +249,7 @@ and the underlying hardware events used. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> >>> Modified: head/lib/libpmc/pmc.k8.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -783,6 +783,7 @@ and the underlying hardware events used. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> >>> Modified: head/lib/libpmc/pmc.mips24k.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -392,6 +392,7 @@ and the underlying hardware events used. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.octeon.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -232,6 +232,7 @@ and the underlying hardware events used. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.p4.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1208,6 +1208,7 @@ and the underlying hardware events used. >>> .Xr pmc.k8 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> >>> Modified: head/lib/libpmc/pmc.p5.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -444,6 +444,7 @@ and the underlying hardware events used. >>> .Xr pmc.k8 3 , >>> .Xr pmc.p4 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> >>> Modified: head/lib/libpmc/pmc.p6.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1010,6 +1010,7 @@ and the underlying hardware events used. >>> .Xr pmc.k8 3 , >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> >>> Modified: head/lib/libpmc/pmc.sandybridge.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -907,6 +907,7 @@ Split locks in SQ. >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> .Xr pmc.sandybridgeuc 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc.ucf 3 , >>> .Xr pmc.westmere 3 , >>> >>> Modified: head/lib/libpmc/pmc.sandybridgeuc.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -208,6 +208,7 @@ Counts the number of core-outgoing entri >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> .Xr pmc.sandybridge 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc.ucf 3 , >>> .Xr pmc.westmere 3 , >>> >>> Added: head/lib/libpmc/pmc.soft.3 >>> ============================================================================== >>> --- /dev/null 00:00:00 1970 (empty, because file is newly added) >>> +++ head/lib/libpmc/pmc.soft.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -0,0 +1,104 @@ >>> +.\" Copyright (c) 2012 Fabien Thomas. All rights reserved. >>> +.\" >>> +.\" Redistribution and use in source and binary forms, with or without >>> +.\" modification, are permitted provided that the following conditions >>> +.\" are met: >>> +.\" 1. Redistributions of source code must retain the above copyright >>> +.\" notice, this list of conditions and the following disclaimer. >>> +.\" 2. Redistributions in binary form must reproduce the above copyright >>> +.\" notice, this list of conditions and the following disclaimer in the >>> +.\" documentation and/or other materials provided with the distribution. >>> +.\" >>> +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >>> +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >>> +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >>> +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >>> +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >>> +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >>> +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >>> +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >>> +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >>> +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >>> +.\" SUCH DAMAGE. >>> +.\" >>> +.\" $FreeBSD$ >>> +.\" >>> +.Dd March 28, 2012 >>> +.Os >>> +.Dt PMC.SOFT 3 >>> +.Sh NAME >>> +.Nm pmc.soft >>> +.Nd measurements using software based events >>> +.Sh LIBRARY >>> +.Lb libpmc >>> +.Sh SYNOPSIS >>> +.In pmc.h >>> +.Sh DESCRIPTION >>> +Software events are used to collect various source of software events. >>> +.Ss PMC Features >>> +16 sampling counters using software events based on various sources. >>> +These PMCs support the following capabilities: >>> +.Bl -column "PMC_CAP_INTERRUPT" "Support" >>> +.It Em Capability Ta Em Support >>> +.It PMC_CAP_CASCADE Ta \&No >>> +.It PMC_CAP_EDGE Ta \&No >>> +.It PMC_CAP_INTERRUPT Ta Yes >>> +.It PMC_CAP_INVERT Ta \&No >>> +.It PMC_CAP_READ Ta Yes >>> +.It PMC_CAP_PRECISE Ta \&No >>> +.It PMC_CAP_SYSTEM Ta Yes >>> +.It PMC_CAP_TAGGING Ta \&No >>> +.It PMC_CAP_THRESHOLD Ta \&No >>> +.It PMC_CAP_USER Ta Yes >>> +.It PMC_CAP_WRITE Ta Yes >>> +.El >>> +.Ss Event Qualifiers >>> +There is no supported event qualifier. >>> +.Pp >>> +The event specifiers supported by software are: >>> +.Bl -tag -width indent >>> +.It Li CLOCK.HARD >>> +Hard clock ticks. >>> +.It Li CLOCK.STAT >>> +Stat clock ticks. >>> +.It Li LOCK.FAILED >>> +Lock acquisition failed. >>> +.It Li PAGE_FAULT.ALL >>> +All page fault type. >>> +.It Li PAGE_FAULT.READ >>> +Read page fault. >>> +.It Li PAGE_FAULT.WRITE >>> +Write page fault. >>> +.El >>> +.Sh SEE ALSO >>> +.Xr pmc 3 , >>> +.Xr pmc.atom 3 , >>> +.Xr pmc.core 3 , >>> +.Xr pmc.iaf 3 , >>> +.Xr pmc.ucf 3 , >>> +.Xr pmc.k7 3 , >>> +.Xr pmc.k8 3 , >>> +.Xr pmc.p4 3 , >>> +.Xr pmc.p5 3 , >>> +.Xr pmc.p6 3 , >>> +.Xr pmc.corei7 3 , >>> +.Xr pmc.corei7uc 3 , >>> +.Xr pmc.westmereuc 3 , >>> +.Xr pmc.tsc 3 , >>> +.Xr pmc_cpuinfo 3 , >>> +.Xr pmclog 3 , >>> +.Xr hwpmc 4 >>> +.Sh HISTORY >>> +The >>> +.Nm pmc >>> +library first appeared in >>> +.Fx 6.0 . >>> +.Sh AUTHORS >>> +The >>> +.Lb libpmc >>> +library was written by >>> +.An "Joseph Koshy" >>> +.Aq [hidden email] . >>> +Software PMC was written by >>> +.An "Fabien Thomas" >>> +.Aq [hidden email] . >>> >>> Modified: head/lib/libpmc/pmc.tsc.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -68,6 +68,7 @@ maps to the TSC. >>> .Xr pmc.p4 3 , >>> .Xr pmc.p5 3 , >>> .Xr pmc.p6 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmclog 3 , >>> .Xr hwpmc 4 >>> .Sh HISTORY >>> >>> Modified: head/lib/libpmc/pmc.ucf.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -96,6 +96,7 @@ offset C0H under device number 0 and Fun >>> .Xr pmc.corei7uc 3 , >>> .Xr pmc.westmere 3 , >>> .Xr pmc.westmereuc 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.westmere.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shif >>> .Xr pmc.corei7 3 , >>> .Xr pmc.corei7uc 3 , >>> .Xr pmc.westmereuc 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.westmereuc.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1066,6 +1066,7 @@ disabled. >>> .Xr pmc.corei7 3 , >>> .Xr pmc.corei7uc 3 , >>> .Xr pmc.westmere 3 , >>> +.Xr pmc.soft 3 , >>> .Xr pmc.tsc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> >>> Modified: head/lib/libpmc/pmc.xscale.3 >>> ============================================================================== >>> --- head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -134,6 +134,7 @@ and the underlying hardware events used. >>> .Xr pmc 3 , >>> .Xr pmc_cpuinfo 3 , >>> .Xr pmclog 3 , >>> +.Xr pmc.soft 3 , >>> .Xr hwpmc 4 >>> .Sh HISTORY >>> The >>> >>> Modified: head/lib/libpmc/pmclog.c >>> ============================================================================== >>> --- head/lib/libpmc/pmclog.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmclog.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **da >>> == NULL) >>> goto error; >>> break; >>> + case PMCLOG_TYPE_PMCALLOCATEDYN: >>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid); >>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event); >>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags); >>> + PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX); >>> + break; >>> case PMCLOG_TYPE_PMCATTACH: >>> PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach); >>> PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid); >>> >>> Modified: head/lib/libpmc/pmclog.h >>> ============================================================================== >>> --- head/lib/libpmc/pmclog.h Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/lib/libpmc/pmclog.h Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate { >>> pmc_id_t pl_pmcid; >>> }; >>> >>> +struct pmclog_ev_pmcallocatedyn { >>> + uint32_t pl_event; >>> + char pl_evname[PMC_NAME_MAX]; >>> + uint32_t pl_flags; >>> + pmc_id_t pl_pmcid; >>> +}; >>> + >>> struct pmclog_ev_pmcattach { >>> pmc_id_t pl_pmcid; >>> pid_t pl_pid; >>> @@ -146,6 +153,7 @@ struct pmclog_ev { >>> struct pmclog_ev_map_out pl_mo; >>> struct pmclog_ev_pcsample pl_s; >>> struct pmclog_ev_pmcallocate pl_a; >>> + struct pmclog_ev_pmcallocatedyn pl_ad; >>> struct pmclog_ev_pmcattach pl_t; >>> struct pmclog_ev_pmcdetach pl_d; >>> struct pmclog_ev_proccsw pl_c; >>> >>> Modified: head/sys/amd64/amd64/trap.c >>> ============================================================================== >>> --- head/sys/amd64/amd64/trap.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/amd64/amd64/trap.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$"); >>> #include <sys/vmmeter.h> >>> #ifdef HWPMC_HOOKS >>> #include <sys/pmckern.h> >>> +PMC_SOFT_DEFINE( , , page_fault, all); >>> +PMC_SOFT_DEFINE( , , page_fault, read); >>> +PMC_SOFT_DEFINE( , , page_fault, write); >>> #endif >>> >>> #include <vm/vm.h> >>> @@ -743,8 +746,20 @@ trap_pfault(frame, usermode) >>> */ >>> rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); >>> } >>> - if (rv == KERN_SUCCESS) >>> + if (rv == KERN_SUCCESS) { >>> +#ifdef HWPMC_HOOKS >>> + if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) { >>> + PMC_SOFT_CALL_TF( , , page_fault, all, frame); >>> + if (ftype == VM_PROT_READ) >>> + PMC_SOFT_CALL_TF( , , page_fault, read, >>> + frame); >>> + else >>> + PMC_SOFT_CALL_TF( , , page_fault, write, >>> + frame); >>> + } >>> +#endif >>> return (0); >>> + } >>> nogo: >>> if (!usermode) { >>> if (td->td_intr_nesting_level == 0 && >>> >>> Modified: head/sys/amd64/include/pmc_mdep.h >>> ============================================================================== >>> --- head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -50,13 +50,13 @@ struct pmc_mdep; >>> * measurement architecture have PMCs of the following classes: TSC, >>> * IAF, IAP, UCF and UCP. >>> */ >>> -#define PMC_MDEP_CLASS_INDEX_TSC 0 >>> -#define PMC_MDEP_CLASS_INDEX_K8 1 >>> -#define PMC_MDEP_CLASS_INDEX_P4 1 >>> -#define PMC_MDEP_CLASS_INDEX_IAP 1 >>> -#define PMC_MDEP_CLASS_INDEX_IAF 2 >>> -#define PMC_MDEP_CLASS_INDEX_UCP 3 >>> -#define PMC_MDEP_CLASS_INDEX_UCF 4 >>> +#define PMC_MDEP_CLASS_INDEX_TSC 1 >>> +#define PMC_MDEP_CLASS_INDEX_K8 2 >>> +#define PMC_MDEP_CLASS_INDEX_P4 2 >>> +#define PMC_MDEP_CLASS_INDEX_IAP 2 >>> +#define PMC_MDEP_CLASS_INDEX_IAF 3 >>> +#define PMC_MDEP_CLASS_INDEX_UCP 4 >>> +#define PMC_MDEP_CLASS_INDEX_UCF 5 >>> >>> /* >>> * On the amd64 platform we support the following PMCs. >>> @@ -119,6 +119,15 @@ union pmc_md_pmc { >>> >>> #define PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS) >>> >>> +/* Build a fake kernel trapframe from current instruction pointer. */ >>> +#define PMC_FAKE_TRAPFRAME(TF) \ >>> + do { \ >>> + (TF)->tf_cs = 0; (TF)->tf_rflags = 0; \ >>> + __asm __volatile("movq %%rbp,%0" : "=r" ((TF)->tf_rbp)); \ >>> + __asm __volatile("movq %%rsp,%0" : "=r" ((TF)->tf_rsp)); \ >>> + __asm __volatile("call 1f \n\t1: pop %0" : "=r"((TF)->tf_rip)); \ >>> + } while (0) >>> + >>> /* >>> * Prototypes >>> */ >>> >>> Modified: head/sys/arm/include/pmc_mdep.h >>> ============================================================================== >>> --- head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -29,7 +29,7 @@ >>> #ifndef _MACHINE_PMC_MDEP_H_ >>> #define _MACHINE_PMC_MDEP_H_ >>> >>> -#define PMC_MDEP_CLASS_INDEX_XSCALE 0 >>> +#define PMC_MDEP_CLASS_INDEX_XSCALE 1 >>> /* >>> * On the ARM platform we support the following PMCs. >>> * >>> >>> Modified: head/sys/conf/files >>> ============================================================================== >>> --- head/sys/conf/files Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/conf/files Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -1260,6 +1260,7 @@ dev/hme/if_hme_sbus.c optional hme sbus >>> dev/hptiop/hptiop.c optional hptiop scbus >>> dev/hwpmc/hwpmc_logging.c optional hwpmc >>> dev/hwpmc/hwpmc_mod.c optional hwpmc >>> +dev/hwpmc/hwpmc_soft.c optional hwpmc >>> dev/ichsmb/ichsmb.c optional ichsmb >>> dev/ichsmb/ichsmb_pci.c optional ichsmb pci >>> dev/ida/ida.c optional ida >>> >>> Modified: head/sys/dev/hwpmc/hwpmc_amd.c >>> ============================================================================== >>> --- head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -687,7 +687,8 @@ amd_intr(int cpu, struct trapframe *tf) >>> wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v)); >>> >>> /* Restart the counter if logging succeeded. */ >>> - error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf)); >>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>> + TRAPF_USERMODE(tf)); >>> if (error == 0) >>> wrmsr(evsel, config | AMD_PMC_ENABLE); >>> } >>> @@ -874,7 +875,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int c >>> struct pmc_mdep * >>> pmc_amd_initialize(void) >>> { >>> - int classindex, error, i, nclasses, ncpus; >>> + int classindex, error, i, ncpus; >>> struct pmc_classdep *pcd; >>> enum pmc_cputype cputype; >>> struct pmc_mdep *pmc_mdep; >>> @@ -926,12 +927,9 @@ pmc_amd_initialize(void) >>> * These processors have two classes of PMCs: the TSC and >>> * programmable PMCs. >>> */ >>> - nclasses = 2; >>> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * sizeof (struct pmc_classdep), >>> - M_PMC, M_WAITOK|M_ZERO); >>> + pmc_mdep = pmc_mdep_alloc(2); >>> >>> pmc_mdep->pmd_cputype = cputype; >>> - pmc_mdep->pmd_nclass = nclasses; >>> >>> ncpus = pmc_cpu_max(); >>> >>> >>> Modified: head/sys/dev/hwpmc/hwpmc_core.c >>> ============================================================================== >>> --- head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -2239,7 +2239,7 @@ core_intr(int cpu, struct trapframe *tf) >>> if (pm->pm_state != PMC_STATE_RUNNING) >>> continue; >>> >>> - error = pmc_process_interrupt(cpu, pm, tf, >>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>> TRAPF_USERMODE(tf)); >>> >>> v = pm->pm_sc.pm_reloadcount; >>> @@ -2326,7 +2326,7 @@ core2_intr(int cpu, struct trapframe *tf >>> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >>> continue; >>> >>> - error = pmc_process_interrupt(cpu, pm, tf, >>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>> TRAPF_USERMODE(tf)); >>> if (error) >>> intrenable &= ~flag; >>> @@ -2354,7 +2354,7 @@ core2_intr(int cpu, struct trapframe *tf >>> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >>> continue; >>> >>> - error = pmc_process_interrupt(cpu, pm, tf, >>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>> TRAPF_USERMODE(tf)); >>> if (error) >>> intrenable &= ~flag; >>> >>> Modified: head/sys/dev/hwpmc/hwpmc_intel.c >>> ============================================================================== >>> --- head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -162,12 +162,10 @@ pmc_intel_initialize(void) >>> return (NULL); >>> } >>> >>> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * >>> - sizeof(struct pmc_classdep), M_PMC, M_WAITOK|M_ZERO); >>> + /* Allocate base class and initialize machine dependent struct */ >>> + pmc_mdep = pmc_mdep_alloc(nclasses); >>> >>> pmc_mdep->pmd_cputype = cputype; >>> - pmc_mdep->pmd_nclass = nclasses; >>> - >>> pmc_mdep->pmd_switch_in = intel_switch_in; >>> pmc_mdep->pmd_switch_out = intel_switch_out; >>> >>> >>> Modified: head/sys/dev/hwpmc/hwpmc_logging.c >>> ============================================================================== >>> --- head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -129,6 +129,7 @@ static struct mtx pmc_kthread_mtx; /* sl >>> >>> /* Emit a string. Caution: does NOT update _le, so needs to be last */ >>> #define PMCLOG_EMITSTRING(S,L) do { bcopy((S), _le, (L)); } while (0) >>> +#define PMCLOG_EMITNULLSTRING(L) do { bzero(_le, (L)); } while (0) >>> >>> #define PMCLOG_DESPATCH(PO) \ >>> pmclog_release((PO)); \ >>> @@ -835,16 +836,33 @@ void >>> pmclog_process_pmcallocate(struct pmc *pm) >>> { >>> struct pmc_owner *po; >>> + struct pmc_soft *ps; >>> >>> po = pm->pm_owner; >>> >>> PMCDBG(LOG,ALL,1, "pm=%p", pm); >>> >>> - PMCLOG_RESERVE(po, PMCALLOCATE, sizeof(struct pmclog_pmcallocate)); >>> - PMCLOG_EMIT32(pm->pm_id); >>> - PMCLOG_EMIT32(pm->pm_event); >>> - PMCLOG_EMIT32(pm->pm_flags); >>> - PMCLOG_DESPATCH(po); >>> + if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) { >>> + PMCLOG_RESERVE(po, PMCALLOCATEDYN, >>> + sizeof(struct pmclog_pmcallocatedyn)); >>> + PMCLOG_EMIT32(pm->pm_id); >>> + PMCLOG_EMIT32(pm->pm_event); >>> + PMCLOG_EMIT32(pm->pm_flags); >>> + ps = pmc_soft_ev_acquire(pm->pm_event); >>> + if (ps != NULL) >>> + PMCLOG_EMITSTRING(ps->ps_ev.pm_ev_name,PMC_NAME_MAX); >>> + else >>> + PMCLOG_EMITNULLSTRING(PMC_NAME_MAX); >>> + pmc_soft_ev_release(ps); >>> + PMCLOG_DESPATCH(po); >>> + } else { >>> + PMCLOG_RESERVE(po, PMCALLOCATE, >>> + sizeof(struct pmclog_pmcallocate)); >>> + PMCLOG_EMIT32(pm->pm_id); >>> + PMCLOG_EMIT32(pm->pm_event); >>> + PMCLOG_EMIT32(pm->pm_flags); >>> + PMCLOG_DESPATCH(po); >>> + } >>> } >>> >>> void >>> >>> Modified: head/sys/dev/hwpmc/hwpmc_mips.c >>> ============================================================================== >>> --- head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -287,7 +287,7 @@ mips_pmc_intr(int cpu, struct trapframe >>> retval = 1; >>> if (pm->pm_state != PMC_STATE_RUNNING) >>> continue; >>> - error = pmc_process_interrupt(cpu, pm, tf, >>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>> TRAPF_USERMODE(tf)); >>> if (error) { >>> /* Clear/disable the relevant counter */ >>> >>> Modified: head/sys/dev/hwpmc/hwpmc_mod.c >>> ============================================================================== >>> --- head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:49:11 2012 (r233627) >>> +++ head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:58:30 2012 (r233628) >>> @@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$"); >>> #include <vm/vm_map.h> >>> #include <vm/vm_object.h> >>> >>> +#include "hwpmc_soft.h" >>> + >>> /* >>> * Types >>> */ >>> @@ -182,7 +184,7 @@ static int pmc_attach_one_process(struct >>> static int pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, >>> int cpu); >>> static int pmc_can_attach(struct pmc *pm, struct proc *p); >>> -static void pmc_capture_user_callchain(int cpu, struct trapframe *tf); >>> +static void pmc_capture_user_callchain(int cpu, int soft, struct trapframe *tf); >>> static void pmc_cleanup(void); >>> static int pmc_detach_process(struct proc *p, struct pmc *pm); >>> static int pmc_detach_one_process(struct proc *p, struct pmc *pm, >>> @@ -206,7 +208,7 @@ static void pmc_process_csw_out(struct t >>> static void pmc_process_exit(void *arg, struct proc *p); >>> static void pmc_process_fork(void *arg, struct proc *p1, >>> struct proc *p2, int n); >>> -static void pmc_process_samples(int cpu); >>> +static void pmc_process_samples(int cpu, int soft); >>> static void pmc_release_pmc_descriptor(struct pmc *pmc); >>> static void pmc_remove_owner(struct pmc_owner *po); >>> static void pmc_remove_process_descriptor(struct pmc_process *pp); >>> @@ -218,12 +220,16 @@ static int pmc_stop(struct pmc *pm); >>> static int pmc_syscall_handler(struct thread *td, void *syscall_args); >>> static void pmc_unlink_target_process(struct pmc *pmc, >>> struct pmc_process *pp); >>> +static int generic_switch_in(struct pmc_cpu *pc, struct pmc_process *pp); >>> +static int generic_switch_out(struct pmc_cpu *pc, struct pmc_process *pp); >>> +static struct pmc_mdep *pmc_generic_cpu_initialize(void); >>> +static void pmc_generic_cpu_finalize(struct pmc_mdep *md); >>> >>> /* >>> * Kernel tunables and sysctl(8) interface. >>> */ >>> >>> -SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters"); >>> +SYSCTL_DECL(_kern_hwpmc); >>> >>> static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; >>> TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "callchaindepth", &pmc_callchaindepth); >>> @@ -1833,7 +1839,9 @@ const char *pmc_hooknames[] = { >>> "KLDUNLOAD", >>> "MMAP", >>> "MUNMAP", >>> - "CALLCHAIN" >>> + "CALLCHAIN-NMI", >>> + "CALLCHAIN-SOFT", >>> + "SOFTSAMPLING" >>> }; >>> #endif >>> >>> @@ -1992,7 +2000,8 @@ pmc_hook_handler(struct thread *td, int >>> * lose the interrupt sample. >>> */ >>> CPU_CLR_ATOMIC(PCPU_GET(cpuid), &pmc_cpumask); >>> - pmc_process_samples(PCPU_GET(cpuid)); >>> + pmc_process_samples(PCPU_GET(cpuid), PMC_HR); >>> + pmc_process_samples(PCPU_GET(cpuid), PMC_SR); >>> break; >>> >>> >>> @@ -2022,11 +2031,30 @@ pmc_hook_handler(struct thread *td, int >>> */ >>> KASSERT(td == curthread, ("[pmc,%d] td != curthread", >>> __LINE__)); >>> - pmc_capture_user_callchain(PCPU_GET(cpuid), >>> + >>> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_HR, >>> (struct trapframe *) arg); >>> td->td_pflags &= ~TDP_CALLCHAIN; >>> break; >>> >>> + case PMC_FN_USER_CALLCHAIN_SOFT: >>> + /* >>> + * Record a call chain. >>> + */ >>> + KASSERT(td == curthread, ("[pmc,%d] td != curthread", >>> + __LINE__)); >>> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_SR, >>> + (struct trapframe *) arg); >>> + td->td_pflags &= ~TDP_CALLCHAIN; >>> + break; >>> + >>> + case PMC_FN_SOFT_SAMPLING: >>> + /* >>> + * Call soft PMC sampling intr. >>> + */ >>> + pmc_soft_intr((struct pmckern_soft *) arg); >>> + break; >>> + >>> default: >>> #ifdef DEBUG >>> KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function)); >>> @@ -2221,18 +2249,17 @@ pmc_destroy_pmc_descriptor(struct pmc *p >>> static void >>> pmc_wait_for_pmc_idle(struct pmc *pm) >>> { >>> -#ifdef DEBUG >>> +#ifdef DEBUG >>> volatile int maxloop; >>> >>> maxloop = 100 * pmc_cpu_max(); >>> #endif >>> - >>> /* >>> * Loop (with a forced context switch) till the PMC's runcount >>> * comes down to zero. >>> */ >>> while (atomic_load_acq_32(&pm->pm_runcount) > 0) { >>> -#ifdef DEBUG >>> +#ifdef DEBUG >>> maxloop--; >>> KASSERT(maxloop > 0, >>> ("[pmc,%d] (ri%d, rc%d) waiting too long for " >>> @@ -2972,6 +2999,53 @@ pmc_syscall_handler(struct thread *td, v >>> } >>> break; >>> >>> + /* >>> + * Retrieve soft events list. >>> + */ >>> + case PMC_OP_GETDYNEVENTINFO: >>> + { >>> + enum pmc_class cl; >>> + enum pmc_event ev; >>> + struct pmc_op_getdyneventinfo *gei; >>> + struct pmc_dyn_event_descr dev; >>> + struct pmc_soft *ps; >>> + uint32_t nevent; >>> + >>> + sx_assert(&pmc_sx, SX_LOCKED); >>> + >>> + gei = (struct pmc_op_getdyneventinfo *) arg; >>> + >>> + if ((error = copyin(&gei->pm_class, &cl, sizeof(cl))) != 0) >>> + break; >>> + >>> + /* Only SOFT class is dynamic. */ >>> + if (cl != PMC_CLASS_SOFT) { >>> + error = EINVAL; >>> + break; >>> + } >>> + >>> + nevent = 0; >>> + for (ev = PMC_EV_SOFT_FIRST; ev <= PMC_EV_SOFT_LAST; ev++) { >>> + ps = pmc_soft_ev_acquire(ev); >>> + if (ps == NULL) >>> + continue; >>> + bcopy(&ps->ps_ev, &dev, sizeof(dev)); >>> + pmc_soft_ev_release(ps); >>> + >>> + error = copyout(&dev, >>> + &gei->pm_events[nevent], >>> + sizeof(struct pmc_dyn_event_descr)); >>> + if (error != 0) >>> + break; >>> + nevent++; >>> + } >>> + if (error != 0) >>> + break; >>> + >>> + error = copyout(&nevent, &gei->pm_nevent, >>> >>> *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** > > > > -- > Monthadar Al Jaberi > <RSPRO_USB_PROD> |
|
On Mon, Apr 23, 2012 at 9:47 AM, Fabien Thomas <[hidden email]> wrote:
> Hi, > > The rumors seems true :) > Can you try the patch attached (I cannot test as i've no MIPS hardware) ? my RSPRO boots fine now, thank you :) > > Thanks, > Fabien > > >> On Mon, Apr 23, 2012 at 8:44 AM, Adrian Chadd <[hidden email]> wrote: >>> Hi Fabien, >>> >>> I've heard some rumours that this broke hwpmc support for mips24k. >>> >>> Monthadar, can you please provide some background info for this? >>> >> >> This is the log output >> >> Using default protocol (TFTP) >> Entry point: 0x80050100, address range: 0x80050000-0x804f1dcc >> RedBoot> exec >> Now booting linux kernel: >> Base address 0x80050000 Entry 0x80050100 >> memsize=0x08000000 >> modetty0=0,n,8,1,hw >> board=RouterStation PRO >> ethaddr=00.15.6d.c8.c9.2e >> CPU platform: Atheros AR7161 rev 2 >> CPU Frequency=720 MHz >> CPU DDR Frequency=360 MHz >> CPU AHB Frequency=180 MHz >> platform frequency: 720000000 >> arguments: >> a0 = 00000002 >> a1 = 80050028 >> a2 = 80050000 >> a3 = 00000001 >> Cmd line: �������m���������������_}������߾q��������������� �����������������߿���������_�w���� �����?-����{������~�� >> Environment: >> memsize = 0x08000000 >> modetty0 = 0,n,8,1,hw >> ethaddr = 00.15.6d.c8.c9.2e >> board = RouterStation PRO >> Cache info: >> picache_stride = 4096 >> picache_loopcount = 16 >> pdcache_stride = 4096 >> pdcache_loopcount = 8 >> cpu0: MIPS Technologies processor v116.147 >> MMU: Standard TLB, 16 entries >> L1 i-cache: 4 ways of 512 sets, 32 bytes per line >> L1 d-cache: 4 ways of 256 sets, 32 bytes per line >> Config1=0x9ee3519e<PerfCount,WatchRegs,MIPS16,EJTAG> >> Config3=0x20 >> KDB: debugger backends: ddb >> KDB: current backend: ddb >> Copyright (c) 1992-2012 The FreeBSD Project. >> Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 >> The Regents of the University of California. All rights reserved. >> FreeBSD is a registered trademark of The FreeBSD Foundation. >> FreeBSD 10.0-CURRENT #12: Fri Apr 20 18:03:16 CEST 2012 >> root@freebsd-re-9:/usr/obj/mips.mips/usr/src/sys/RSPRO_USB_PROD mips >> WARNING: WITNESS option enabled, expect reduced performance. >> MEMGUARD DEBUGGING ALLOCATOR INITIALIZED: >> MEMGUARD map base: 0xc0800000 >> MEMGUARD map limit: 0xc1c00000 >> MEMGUARD map size: 20480 KBytes >> real memory = 134217728 (131072K bytes) >> avail memory = 123117568 (117MB) >> random device not loaded; using insecure entropy >> nexus0: <MIPS32 root nexus> >> clock0: <Generic MIPS32 ticker> on nexus0 >> Timecounter "MIPS32" frequency 360000000 Hz quality 800 >> Event timer "MIPS32" frequency 360000000 Hz quality 800 >> apb0 at irq 4 on nexus0 >> uart0: <16550 or compatible> on apb0 >> uart0: console (115200,n,8,1) >> gpio0: <Atheros AR71XX GPIO driver> on apb0 >> gpio0: [GIANT-LOCKED] >> gpio0: gpio pinmask=0x0 >> gpioc0: <GPIO controller> on gpio0 >> gpiobus0: <GPIO bus> on gpio0 >> ehci0: <AR71XX Integrated USB 2.0 controller> at mem >> 0x1b000000-0x1bffffff irq 1 on nexus0 >> usbus0: set host controller mode >> usbus0: EHCI version 1.0 >> usbus0: set host controller mode >> usbus0 on ehci0 >> pcib0 at irq 0 on nexus0 >> pci0: <PCI bus> on pcib0 >> pci0: <old, non-VGA display device> at device 0.0 (no driver attached) >> ath0: <Atheros 5413> irq 0 at device 17.0 on pci0 >> ath0: AR5413 mac 10.5 RF5413 phy 6.1 >> ath0: 2GHz radio: 0x0000; 5GHz radio: 0x0063 >> arge0: <Atheros AR71xx built-in ethernet interface> at mem >> 0x19000000-0x19000fff irq 2 on nexus0 >> arge0: No PHY specified, using mask 16 >> miibus0: <MII bus> on arge0 >> ukphy0: <Generic IEEE 802.3u media interface> PHY 4 on miibus0 >> ukphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, >> 1000baseT-FDX, 1000baseT-FDX-master, auto >> arge0: Ethernet address: 00:15:6d:c8:c9:2e >> arge1: <Atheros AR71xx built-in ethernet interface> at mem >> 0x1a000000-0x1a000fff irq 3 on nexus0 >> arge1: No PHY specified, using mask 15 >> arge1: Ethernet address: 00:15:6d:c8:c9:2f >> spi0: <AR71XX SPI> at mem 0x1f000000-0x1f00000f on nexus0 >> spibus0: <spibus bus> on spi0 >> mx25l0: <M25Pxx Flash Family> at cs 0 on spibus0 >> mx25l0: mx25ll128, sector 65536 bytes, 256 sectors >> ar71xx_wdog0: <Atheros AR71XX watchdog timer> on nexus0 >> Timecounters tick every 1.000 msec >> usbus0: 480Mbps High Speed USB v2.0 >> ugen0.1: <Atheros> at usbus0 >> uhub0: <Atheros EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0 >> panic: [pmc,4816] npmc miscomputed: ri=0, md->npmc=2 >> KDB: enter: panic >> [ thread pid 0 tid 100000 ] >> Stopped at kdb_enter+0x4c: lui at,0x8050 >> db> tr >> Tracing pid 0 tid 100000 td 0x804f76d0 >> db_trace_thread+30 (?,?,?,?) ra 8068b94800000018 sp 0 sz 0 >> 80075adc+114 (0,?,ffffffff,?) ra 8068b96000000020 sp 100000000 sz 1 >> 80074e24+388 (?,?,?,?) ra 8068b980000000a8 sp 0 sz 0 >> db_command_loop+70 (?,?,?,?) ra 8068ba2800000018 sp 0 sz 0 >> 80077900+f4 (?,?,?,?) ra 8068ba40000001a8 sp 0 sz 0 >> kdb_trap+110 (?,?,?,?) ra 8068bbe800000030 sp 0 sz 0 >> trap+c7c (?,?,?,?) ra 8068bc18000000b8 sp 0 sz 0 >> MipsKernGenException+134 (0,4,8043b1d4,119) ra 8068bcd0000000c8 sp >> 100000001 sz 1 >> kdb_enter+4c (?,?,?,?) ra 8068bd9800000018 sp 0 sz 0 >> panic+11c (?,12d0,0,2) ra 8068bdb000000028 sp 1 sz 1 >> 800e8ca8+274 (?,?,?,?) ra 8068bdd800000038 sp 0 sz 0 >> syscall_module_handler+b8 (?,?,?,?) ra 8068be1000000028 sp 0 sz 0 >> module_register_init+9c (?,?,?,?) ra 8068be3800000028 sp 0 sz 0 >> mi_startup+138 (?,?,?,?) ra 8068be6000000020 sp 0 sz 0 >> _start+90 (?,?,?,?) ra 8068be8000000000 sp 0 sz 0 >> pid 0 >> db> >> >>> Thanks, >>> >>> >>> >>> adrian >>> >>> On 28 March 2012 13:58, Fabien Thomas <[hidden email]> wrote: >>>> Author: fabient >>>> Date: Wed Mar 28 20:58:30 2012 >>>> New Revision: 233628 >>>> URL: http://svn.freebsd.org/changeset/base/233628 >>>> >>>> Log: >>>> Add software PMC support. >>>> >>>> New kernel events can be added at various location for sampling or counting. >>>> This will for example allow easy system profiling whatever the processor is >>>> with known tools like pmcstat(8). >>>> >>>> Simultaneous usage of software PMC and hardware PMC is possible, for example >>>> looking at the lock acquire failure, page fault while sampling on >>>> instructions. >>>> >>>> Sponsored by: NETASQ >>>> MFC after: 1 month >>>> >>>> Added: >>>> head/lib/libpmc/pmc.soft.3 (contents, props changed) >>>> head/sys/dev/hwpmc/hwpmc_soft.c (contents, props changed) >>>> head/sys/dev/hwpmc/hwpmc_soft.h (contents, props changed) >>>> Modified: >>>> head/lib/libpmc/Makefile >>>> head/lib/libpmc/libpmc.c >>>> head/lib/libpmc/pmc.3 >>>> head/lib/libpmc/pmc.atom.3 >>>> head/lib/libpmc/pmc.core.3 >>>> head/lib/libpmc/pmc.core2.3 >>>> head/lib/libpmc/pmc.corei7.3 >>>> head/lib/libpmc/pmc.corei7uc.3 >>>> head/lib/libpmc/pmc.iaf.3 >>>> head/lib/libpmc/pmc.k7.3 >>>> head/lib/libpmc/pmc.k8.3 >>>> head/lib/libpmc/pmc.mips24k.3 >>>> head/lib/libpmc/pmc.octeon.3 >>>> head/lib/libpmc/pmc.p4.3 >>>> head/lib/libpmc/pmc.p5.3 >>>> head/lib/libpmc/pmc.p6.3 >>>> head/lib/libpmc/pmc.sandybridge.3 >>>> head/lib/libpmc/pmc.sandybridgeuc.3 >>>> head/lib/libpmc/pmc.tsc.3 >>>> head/lib/libpmc/pmc.ucf.3 >>>> head/lib/libpmc/pmc.westmere.3 >>>> head/lib/libpmc/pmc.westmereuc.3 >>>> head/lib/libpmc/pmc.xscale.3 >>>> head/lib/libpmc/pmclog.c >>>> head/lib/libpmc/pmclog.h >>>> head/sys/amd64/amd64/trap.c >>>> head/sys/amd64/include/pmc_mdep.h >>>> head/sys/arm/include/pmc_mdep.h >>>> head/sys/conf/files >>>> head/sys/dev/hwpmc/hwpmc_amd.c >>>> head/sys/dev/hwpmc/hwpmc_core.c >>>> head/sys/dev/hwpmc/hwpmc_intel.c >>>> head/sys/dev/hwpmc/hwpmc_logging.c >>>> head/sys/dev/hwpmc/hwpmc_mips.c >>>> head/sys/dev/hwpmc/hwpmc_mod.c >>>> head/sys/dev/hwpmc/hwpmc_piv.c >>>> head/sys/dev/hwpmc/hwpmc_powerpc.c >>>> head/sys/dev/hwpmc/hwpmc_ppro.c >>>> head/sys/dev/hwpmc/hwpmc_tsc.c >>>> head/sys/dev/hwpmc/hwpmc_x86.c >>>> head/sys/dev/hwpmc/hwpmc_xscale.c >>>> head/sys/dev/hwpmc/pmc_events.h >>>> head/sys/i386/i386/trap.c >>>> head/sys/i386/include/pmc_mdep.h >>>> head/sys/kern/kern_clock.c >>>> head/sys/kern/kern_lock.c >>>> head/sys/kern/kern_mutex.c >>>> head/sys/kern/kern_pmc.c >>>> head/sys/kern/kern_rwlock.c >>>> head/sys/kern/kern_sx.c >>>> head/sys/kern/subr_trap.c >>>> head/sys/mips/include/pmc_mdep.h >>>> head/sys/modules/hwpmc/Makefile >>>> head/sys/powerpc/include/pmc_mdep.h >>>> head/sys/sys/pmc.h >>>> head/sys/sys/pmckern.h >>>> head/sys/sys/pmclog.h >>>> head/usr.sbin/pmcstat/pmcstat_log.c >>>> >>>> Modified: head/lib/libpmc/Makefile >>>> ============================================================================== >>>> --- head/lib/libpmc/Makefile Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/Makefile Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -20,6 +20,7 @@ MAN+= pmc_read.3 >>>> MAN+= pmc_set.3 >>>> MAN+= pmc_start.3 >>>> MAN+= pmclog.3 >>>> +MAN+= pmc.soft.3 >>>> >>>> # PMC-dependent manual pages >>>> .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" >>>> >>>> Modified: head/lib/libpmc/libpmc.c >>>> ============================================================================== >>>> --- head/lib/libpmc/libpmc.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/libpmc.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_eve >>>> static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >>>> struct pmc_op_pmcallocate *_pmc_config); >>>> #endif >>>> - >>>> #if defined(__mips__) >>>> static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec, >>>> struct pmc_op_pmcallocate *_pmc_config); >>>> #endif /* __mips__ */ >>>> +static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >>>> + struct pmc_op_pmcallocate *_pmc_config); >>>> >>>> #if defined(__powerpc__) >>>> static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec, >>>> @@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON); >>>> PMC_CLASSDEP_TABLE(ucf, UCF); >>>> PMC_CLASSDEP_TABLE(ppc7450, PPC7450); >>>> >>>> +static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; >>>> + >>>> #undef __PMC_EV_ALIAS >>>> #define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE }, >>>> >>>> @@ -215,21 +218,22 @@ static const struct pmc_event_descr west >>>> PMC_CLASS_##C, __VA_ARGS__ \ >>>> } >>>> >>>> -PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>> -PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>> -PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>> -PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC); >>>> -PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE); >>>> -PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K); >>>> -PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON); >>>> -PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450); >>>> +PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>> +PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>> +PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>> +PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>> +PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); >>>> +PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); >>>> +PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); >>>> +PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); >>>> +PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); >>>> >>>> static const struct pmc_event_descr tsc_event_table[] = >>>> { >>>> @@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc) >>>> #if defined(__XSCALE__) >>>> PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale); >>>> #endif >>>> - >>>> #if defined(__mips__) >>>> PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); >>>> PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); >>>> #endif /* __mips__ */ >>>> - >>>> #if defined(__powerpc__) >>>> PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450); >>>> #endif >>>> >>>> +static struct pmc_class_descr soft_class_table_descr = >>>> +{ >>>> + .pm_evc_name = "SOFT-", >>>> + .pm_evc_name_size = sizeof("SOFT-") - 1, >>>> + .pm_evc_class = PMC_CLASS_SOFT, >>>> + .pm_evc_event_table = NULL, >>>> + .pm_evc_event_table_size = 0, >>>> + .pm_evc_allocate_pmc = soft_allocate_pmc >>>> +}; >>>> + >>>> #undef PMC_CLASS_TABLE_DESC >>>> >>>> static const struct pmc_class_descr **pmc_class_table; >>>> @@ -343,9 +355,12 @@ static const char * pmc_state_names[] = >>>> __PMC_STATES() >>>> }; >>>> >>>> -static int pmc_syscall = -1; /* filled in by pmc_init() */ >>>> - >>>> -static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */ >>>> +/* >>>> + * Filled in by pmc_init(). >>>> + */ >>>> +static int pmc_syscall = -1; >>>> +static struct pmc_cpuinfo cpu_info; >>>> +static struct pmc_op_getdyneventinfo soft_event_info; >>>> >>>> /* Event masks for events */ >>>> struct pmc_masks { >>>> @@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char >>>> } >>>> #endif >>>> >>>> +static struct pmc_event_alias generic_aliases[] = { >>>> + EV_ALIAS("instructions", "SOFT-CLOCK.HARD"), >>>> + EV_ALIAS(NULL, NULL) >>>> +}; >>>> + >>>> +static int >>>> +soft_allocate_pmc(enum pmc_event pe, char *ctrspec, >>>> + struct pmc_op_pmcallocate *pmc_config) >>>> +{ >>>> + (void)ctrspec; >>>> + (void)pmc_config; >>>> + >>>> + if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST) >>>> + return (-1); >>>> + >>>> + pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); >>>> + return (0); >>>> +} >>>> + >>>> #if defined(__XSCALE__) >>>> >>>> static struct pmc_event_alias xscale_aliases[] = { >>>> @@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class >>>> ev = ppc7450_event_table; >>>> count = PMC_EVENT_TABLE_SIZE(ppc7450); >>>> break; >>>> + case PMC_CLASS_SOFT: >>>> + ev = soft_event_table; >>>> + count = soft_event_info.pm_nevent; >>>> + break; >>>> default: >>>> errno = EINVAL; >>>> return (-1); >>>> @@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class >>>> >>>> for (;count--; ev++, names++) >>>> *names = ev->pm_ev_name; >>>> + >>>> return (0); >>>> } >>>> >>>> @@ -2780,11 +2819,34 @@ pmc_init(void) >>>> pmc_class_table[n] = NULL; >>>> >>>> /* >>>> + * Get soft events list. >>>> + */ >>>> + soft_event_info.pm_class = PMC_CLASS_SOFT; >>>> + if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0) >>>> + return (pmc_syscall = -1); >>>> + >>>> + /* Map soft events to static list. */ >>>> + for (n = 0; n < soft_event_info.pm_nevent; n++) { >>>> + soft_event_table[n].pm_ev_name = >>>> + soft_event_info.pm_events[n].pm_ev_name; >>>> + soft_event_table[n].pm_ev_code = >>>> + soft_event_info.pm_events[n].pm_ev_code; >>>> + } >>>> + soft_class_table_descr.pm_evc_event_table_size = \ >>>> + soft_event_info.pm_nevent; >>>> + soft_class_table_descr.pm_evc_event_table = \ >>>> + soft_event_table; >>>> + >>>> + /* >>>> * Fill in the class table. >>>> */ >>>> n = 0; >>>> + >>>> + /* Fill soft events information. */ >>>> + pmc_class_table[n++] = &soft_class_table_descr; >>>> #if defined(__amd64__) || defined(__i386__) >>>> - pmc_class_table[n++] = &tsc_class_table_descr; >>>> + if (cpu_info.pm_cputype != PMC_CPU_GENERIC) >>>> + pmc_class_table[n++] = &tsc_class_table_descr; >>>> >>>> /* >>>> * Check if this CPU has fixed function counters. >>>> @@ -2867,6 +2929,9 @@ pmc_init(void) >>>> pmc_class_table[n] = &p4_class_table_descr; >>>> break; >>>> #endif >>>> + case PMC_CPU_GENERIC: >>>> + PMC_MDEP_INIT(generic); >>>> + break; >>>> #if defined(__XSCALE__) >>>> case PMC_CPU_INTEL_XSCALE: >>>> PMC_MDEP_INIT(xscale); >>>> @@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, en >>>> evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale); >>>> } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) { >>>> ev = mips24k_event_table; >>>> - evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k >>>> -); >>>> + evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k); >>>> } else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) { >>>> ev = octeon_event_table; >>>> evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon); >>>> } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) { >>>> ev = ppc7450_event_table; >>>> - evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450 >>>> -); >>>> + evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450); >>>> } else if (pe == PMC_EV_TSC_TSC) { >>>> ev = tsc_event_table; >>>> evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); >>>> + } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) { >>>> + ev = soft_event_table; >>>> + evfence = soft_event_table + soft_event_info.pm_nevent; >>>> } >>>> >>>> for (; ev != evfence; ev++) >>>> >>>> Modified: head/lib/libpmc/pmc.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -223,6 +223,8 @@ and >>>> CPUs. >>>> .It Li PMC_CLASS_TSC >>>> The timestamp counter on i386 and amd64 architecture CPUs. >>>> +.It Li PMC_CLASS_SOFT >>>> +Software events. >>>> .El >>>> .Ss PMC Capabilities >>>> Capabilities of performance monitoring hardware are denoted using >>>> @@ -525,6 +527,7 @@ API is >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 , >>>> >>>> Modified: head/lib/libpmc/pmc.atom.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1176,6 +1176,7 @@ and the underlying hardware events used >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.core.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.core.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.core.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -792,6 +792,7 @@ may not count some transitions. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> >>>> Modified: head/lib/libpmc/pmc.core2.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1107,6 +1107,7 @@ and the underlying hardware events used. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.corei7.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1559,6 +1559,7 @@ Counts number of segment register loads. >>>> .Xr pmc.corei7uc 3 , >>>> .Xr pmc.westmere 3 , >>>> .Xr pmc.westmereuc 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.corei7uc.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -863,6 +863,7 @@ refreshed or needs to go into a power do >>>> .Xr pmc.corei7 3 , >>>> .Xr pmc.westmere 3 , >>>> .Xr pmc.westmereuc 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.iaf.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -132,6 +132,7 @@ CPU, use the event specifier >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.k7.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -249,6 +249,7 @@ and the underlying hardware events used. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> >>>> Modified: head/lib/libpmc/pmc.k8.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -783,6 +783,7 @@ and the underlying hardware events used. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> >>>> Modified: head/lib/libpmc/pmc.mips24k.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -392,6 +392,7 @@ and the underlying hardware events used. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.octeon.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -232,6 +232,7 @@ and the underlying hardware events used. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.p4.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1208,6 +1208,7 @@ and the underlying hardware events used. >>>> .Xr pmc.k8 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> >>>> Modified: head/lib/libpmc/pmc.p5.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -444,6 +444,7 @@ and the underlying hardware events used. >>>> .Xr pmc.k8 3 , >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> >>>> Modified: head/lib/libpmc/pmc.p6.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1010,6 +1010,7 @@ and the underlying hardware events used. >>>> .Xr pmc.k8 3 , >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> >>>> Modified: head/lib/libpmc/pmc.sandybridge.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -907,6 +907,7 @@ Split locks in SQ. >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> .Xr pmc.sandybridgeuc 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc.ucf 3 , >>>> .Xr pmc.westmere 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.sandybridgeuc.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -208,6 +208,7 @@ Counts the number of core-outgoing entri >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> .Xr pmc.sandybridge 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc.ucf 3 , >>>> .Xr pmc.westmere 3 , >>>> >>>> Added: head/lib/libpmc/pmc.soft.3 >>>> ============================================================================== >>>> --- /dev/null 00:00:00 1970 (empty, because file is newly added) >>>> +++ head/lib/libpmc/pmc.soft.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -0,0 +1,104 @@ >>>> +.\" Copyright (c) 2012 Fabien Thomas. All rights reserved. >>>> +.\" >>>> +.\" Redistribution and use in source and binary forms, with or without >>>> +.\" modification, are permitted provided that the following conditions >>>> +.\" are met: >>>> +.\" 1. Redistributions of source code must retain the above copyright >>>> +.\" notice, this list of conditions and the following disclaimer. >>>> +.\" 2. Redistributions in binary form must reproduce the above copyright >>>> +.\" notice, this list of conditions and the following disclaimer in the >>>> +.\" documentation and/or other materials provided with the distribution. >>>> +.\" >>>> +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >>>> +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >>>> +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >>>> +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >>>> +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >>>> +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >>>> +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >>>> +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >>>> +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >>>> +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >>>> +.\" SUCH DAMAGE. >>>> +.\" >>>> +.\" $FreeBSD$ >>>> +.\" >>>> +.Dd March 28, 2012 >>>> +.Os >>>> +.Dt PMC.SOFT 3 >>>> +.Sh NAME >>>> +.Nm pmc.soft >>>> +.Nd measurements using software based events >>>> +.Sh LIBRARY >>>> +.Lb libpmc >>>> +.Sh SYNOPSIS >>>> +.In pmc.h >>>> +.Sh DESCRIPTION >>>> +Software events are used to collect various source of software events. >>>> +.Ss PMC Features >>>> +16 sampling counters using software events based on various sources. >>>> +These PMCs support the following capabilities: >>>> +.Bl -column "PMC_CAP_INTERRUPT" "Support" >>>> +.It Em Capability Ta Em Support >>>> +.It PMC_CAP_CASCADE Ta \&No >>>> +.It PMC_CAP_EDGE Ta \&No >>>> +.It PMC_CAP_INTERRUPT Ta Yes >>>> +.It PMC_CAP_INVERT Ta \&No >>>> +.It PMC_CAP_READ Ta Yes >>>> +.It PMC_CAP_PRECISE Ta \&No >>>> +.It PMC_CAP_SYSTEM Ta Yes >>>> +.It PMC_CAP_TAGGING Ta \&No >>>> +.It PMC_CAP_THRESHOLD Ta \&No >>>> +.It PMC_CAP_USER Ta Yes >>>> +.It PMC_CAP_WRITE Ta Yes >>>> +.El >>>> +.Ss Event Qualifiers >>>> +There is no supported event qualifier. >>>> +.Pp >>>> +The event specifiers supported by software are: >>>> +.Bl -tag -width indent >>>> +.It Li CLOCK.HARD >>>> +Hard clock ticks. >>>> +.It Li CLOCK.STAT >>>> +Stat clock ticks. >>>> +.It Li LOCK.FAILED >>>> +Lock acquisition failed. >>>> +.It Li PAGE_FAULT.ALL >>>> +All page fault type. >>>> +.It Li PAGE_FAULT.READ >>>> +Read page fault. >>>> +.It Li PAGE_FAULT.WRITE >>>> +Write page fault. >>>> +.El >>>> +.Sh SEE ALSO >>>> +.Xr pmc 3 , >>>> +.Xr pmc.atom 3 , >>>> +.Xr pmc.core 3 , >>>> +.Xr pmc.iaf 3 , >>>> +.Xr pmc.ucf 3 , >>>> +.Xr pmc.k7 3 , >>>> +.Xr pmc.k8 3 , >>>> +.Xr pmc.p4 3 , >>>> +.Xr pmc.p5 3 , >>>> +.Xr pmc.p6 3 , >>>> +.Xr pmc.corei7 3 , >>>> +.Xr pmc.corei7uc 3 , >>>> +.Xr pmc.westmereuc 3 , >>>> +.Xr pmc.tsc 3 , >>>> +.Xr pmc_cpuinfo 3 , >>>> +.Xr pmclog 3 , >>>> +.Xr hwpmc 4 >>>> +.Sh HISTORY >>>> +The >>>> +.Nm pmc >>>> +library first appeared in >>>> +.Fx 6.0 . >>>> +.Sh AUTHORS >>>> +The >>>> +.Lb libpmc >>>> +library was written by >>>> +.An "Joseph Koshy" >>>> +.Aq [hidden email] . >>>> +Software PMC was written by >>>> +.An "Fabien Thomas" >>>> +.Aq [hidden email] . >>>> >>>> Modified: head/lib/libpmc/pmc.tsc.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -68,6 +68,7 @@ maps to the TSC. >>>> .Xr pmc.p4 3 , >>>> .Xr pmc.p5 3 , >>>> .Xr pmc.p6 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmclog 3 , >>>> .Xr hwpmc 4 >>>> .Sh HISTORY >>>> >>>> Modified: head/lib/libpmc/pmc.ucf.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -96,6 +96,7 @@ offset C0H under device number 0 and Fun >>>> .Xr pmc.corei7uc 3 , >>>> .Xr pmc.westmere 3 , >>>> .Xr pmc.westmereuc 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.westmere.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shif >>>> .Xr pmc.corei7 3 , >>>> .Xr pmc.corei7uc 3 , >>>> .Xr pmc.westmereuc 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.westmereuc.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1066,6 +1066,7 @@ disabled. >>>> .Xr pmc.corei7 3 , >>>> .Xr pmc.corei7uc 3 , >>>> .Xr pmc.westmere 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr pmc.tsc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> >>>> Modified: head/lib/libpmc/pmc.xscale.3 >>>> ============================================================================== >>>> --- head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -134,6 +134,7 @@ and the underlying hardware events used. >>>> .Xr pmc 3 , >>>> .Xr pmc_cpuinfo 3 , >>>> .Xr pmclog 3 , >>>> +.Xr pmc.soft 3 , >>>> .Xr hwpmc 4 >>>> .Sh HISTORY >>>> The >>>> >>>> Modified: head/lib/libpmc/pmclog.c >>>> ============================================================================== >>>> --- head/lib/libpmc/pmclog.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmclog.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **da >>>> == NULL) >>>> goto error; >>>> break; >>>> + case PMCLOG_TYPE_PMCALLOCATEDYN: >>>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid); >>>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event); >>>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags); >>>> + PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX); >>>> + break; >>>> case PMCLOG_TYPE_PMCATTACH: >>>> PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach); >>>> PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid); >>>> >>>> Modified: head/lib/libpmc/pmclog.h >>>> ============================================================================== >>>> --- head/lib/libpmc/pmclog.h Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/lib/libpmc/pmclog.h Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate { >>>> pmc_id_t pl_pmcid; >>>> }; >>>> >>>> +struct pmclog_ev_pmcallocatedyn { >>>> + uint32_t pl_event; >>>> + char pl_evname[PMC_NAME_MAX]; >>>> + uint32_t pl_flags; >>>> + pmc_id_t pl_pmcid; >>>> +}; >>>> + >>>> struct pmclog_ev_pmcattach { >>>> pmc_id_t pl_pmcid; >>>> pid_t pl_pid; >>>> @@ -146,6 +153,7 @@ struct pmclog_ev { >>>> struct pmclog_ev_map_out pl_mo; >>>> struct pmclog_ev_pcsample pl_s; >>>> struct pmclog_ev_pmcallocate pl_a; >>>> + struct pmclog_ev_pmcallocatedyn pl_ad; >>>> struct pmclog_ev_pmcattach pl_t; >>>> struct pmclog_ev_pmcdetach pl_d; >>>> struct pmclog_ev_proccsw pl_c; >>>> >>>> Modified: head/sys/amd64/amd64/trap.c >>>> ============================================================================== >>>> --- head/sys/amd64/amd64/trap.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/amd64/amd64/trap.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$"); >>>> #include <sys/vmmeter.h> >>>> #ifdef HWPMC_HOOKS >>>> #include <sys/pmckern.h> >>>> +PMC_SOFT_DEFINE( , , page_fault, all); >>>> +PMC_SOFT_DEFINE( , , page_fault, read); >>>> +PMC_SOFT_DEFINE( , , page_fault, write); >>>> #endif >>>> >>>> #include <vm/vm.h> >>>> @@ -743,8 +746,20 @@ trap_pfault(frame, usermode) >>>> */ >>>> rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); >>>> } >>>> - if (rv == KERN_SUCCESS) >>>> + if (rv == KERN_SUCCESS) { >>>> +#ifdef HWPMC_HOOKS >>>> + if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) { >>>> + PMC_SOFT_CALL_TF( , , page_fault, all, frame); >>>> + if (ftype == VM_PROT_READ) >>>> + PMC_SOFT_CALL_TF( , , page_fault, read, >>>> + frame); >>>> + else >>>> + PMC_SOFT_CALL_TF( , , page_fault, write, >>>> + frame); >>>> + } >>>> +#endif >>>> return (0); >>>> + } >>>> nogo: >>>> if (!usermode) { >>>> if (td->td_intr_nesting_level == 0 && >>>> >>>> Modified: head/sys/amd64/include/pmc_mdep.h >>>> ============================================================================== >>>> --- head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -50,13 +50,13 @@ struct pmc_mdep; >>>> * measurement architecture have PMCs of the following classes: TSC, >>>> * IAF, IAP, UCF and UCP. >>>> */ >>>> -#define PMC_MDEP_CLASS_INDEX_TSC 0 >>>> -#define PMC_MDEP_CLASS_INDEX_K8 1 >>>> -#define PMC_MDEP_CLASS_INDEX_P4 1 >>>> -#define PMC_MDEP_CLASS_INDEX_IAP 1 >>>> -#define PMC_MDEP_CLASS_INDEX_IAF 2 >>>> -#define PMC_MDEP_CLASS_INDEX_UCP 3 >>>> -#define PMC_MDEP_CLASS_INDEX_UCF 4 >>>> +#define PMC_MDEP_CLASS_INDEX_TSC 1 >>>> +#define PMC_MDEP_CLASS_INDEX_K8 2 >>>> +#define PMC_MDEP_CLASS_INDEX_P4 2 >>>> +#define PMC_MDEP_CLASS_INDEX_IAP 2 >>>> +#define PMC_MDEP_CLASS_INDEX_IAF 3 >>>> +#define PMC_MDEP_CLASS_INDEX_UCP 4 >>>> +#define PMC_MDEP_CLASS_INDEX_UCF 5 >>>> >>>> /* >>>> * On the amd64 platform we support the following PMCs. >>>> @@ -119,6 +119,15 @@ union pmc_md_pmc { >>>> >>>> #define PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS) >>>> >>>> +/* Build a fake kernel trapframe from current instruction pointer. */ >>>> +#define PMC_FAKE_TRAPFRAME(TF) \ >>>> + do { \ >>>> + (TF)->tf_cs = 0; (TF)->tf_rflags = 0; \ >>>> + __asm __volatile("movq %%rbp,%0" : "=r" ((TF)->tf_rbp)); \ >>>> + __asm __volatile("movq %%rsp,%0" : "=r" ((TF)->tf_rsp)); \ >>>> + __asm __volatile("call 1f \n\t1: pop %0" : "=r"((TF)->tf_rip)); \ >>>> + } while (0) >>>> + >>>> /* >>>> * Prototypes >>>> */ >>>> >>>> Modified: head/sys/arm/include/pmc_mdep.h >>>> ============================================================================== >>>> --- head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -29,7 +29,7 @@ >>>> #ifndef _MACHINE_PMC_MDEP_H_ >>>> #define _MACHINE_PMC_MDEP_H_ >>>> >>>> -#define PMC_MDEP_CLASS_INDEX_XSCALE 0 >>>> +#define PMC_MDEP_CLASS_INDEX_XSCALE 1 >>>> /* >>>> * On the ARM platform we support the following PMCs. >>>> * >>>> >>>> Modified: head/sys/conf/files >>>> ============================================================================== >>>> --- head/sys/conf/files Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/conf/files Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -1260,6 +1260,7 @@ dev/hme/if_hme_sbus.c optional hme sbus >>>> dev/hptiop/hptiop.c optional hptiop scbus >>>> dev/hwpmc/hwpmc_logging.c optional hwpmc >>>> dev/hwpmc/hwpmc_mod.c optional hwpmc >>>> +dev/hwpmc/hwpmc_soft.c optional hwpmc >>>> dev/ichsmb/ichsmb.c optional ichsmb >>>> dev/ichsmb/ichsmb_pci.c optional ichsmb pci >>>> dev/ida/ida.c optional ida >>>> >>>> Modified: head/sys/dev/hwpmc/hwpmc_amd.c >>>> ============================================================================== >>>> --- head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -687,7 +687,8 @@ amd_intr(int cpu, struct trapframe *tf) >>>> wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v)); >>>> >>>> /* Restart the counter if logging succeeded. */ >>>> - error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf)); >>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>> + TRAPF_USERMODE(tf)); >>>> if (error == 0) >>>> wrmsr(evsel, config | AMD_PMC_ENABLE); >>>> } >>>> @@ -874,7 +875,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int c >>>> struct pmc_mdep * >>>> pmc_amd_initialize(void) >>>> { >>>> - int classindex, error, i, nclasses, ncpus; >>>> + int classindex, error, i, ncpus; >>>> struct pmc_classdep *pcd; >>>> enum pmc_cputype cputype; >>>> struct pmc_mdep *pmc_mdep; >>>> @@ -926,12 +927,9 @@ pmc_amd_initialize(void) >>>> * These processors have two classes of PMCs: the TSC and >>>> * programmable PMCs. >>>> */ >>>> - nclasses = 2; >>>> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * sizeof (struct pmc_classdep), >>>> - M_PMC, M_WAITOK|M_ZERO); >>>> + pmc_mdep = pmc_mdep_alloc(2); >>>> >>>> pmc_mdep->pmd_cputype = cputype; >>>> - pmc_mdep->pmd_nclass = nclasses; >>>> >>>> ncpus = pmc_cpu_max(); >>>> >>>> >>>> Modified: head/sys/dev/hwpmc/hwpmc_core.c >>>> ============================================================================== >>>> --- head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -2239,7 +2239,7 @@ core_intr(int cpu, struct trapframe *tf) >>>> if (pm->pm_state != PMC_STATE_RUNNING) >>>> continue; >>>> >>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>> TRAPF_USERMODE(tf)); >>>> >>>> v = pm->pm_sc.pm_reloadcount; >>>> @@ -2326,7 +2326,7 @@ core2_intr(int cpu, struct trapframe *tf >>>> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >>>> continue; >>>> >>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>> TRAPF_USERMODE(tf)); >>>> if (error) >>>> intrenable &= ~flag; >>>> @@ -2354,7 +2354,7 @@ core2_intr(int cpu, struct trapframe *tf >>>> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >>>> continue; >>>> >>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>> TRAPF_USERMODE(tf)); >>>> if (error) >>>> intrenable &= ~flag; >>>> >>>> Modified: head/sys/dev/hwpmc/hwpmc_intel.c >>>> ============================================================================== >>>> --- head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -162,12 +162,10 @@ pmc_intel_initialize(void) >>>> return (NULL); >>>> } >>>> >>>> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * >>>> - sizeof(struct pmc_classdep), M_PMC, M_WAITOK|M_ZERO); >>>> + /* Allocate base class and initialize machine dependent struct */ >>>> + pmc_mdep = pmc_mdep_alloc(nclasses); >>>> >>>> pmc_mdep->pmd_cputype = cputype; >>>> - pmc_mdep->pmd_nclass = nclasses; >>>> - >>>> pmc_mdep->pmd_switch_in = intel_switch_in; >>>> pmc_mdep->pmd_switch_out = intel_switch_out; >>>> >>>> >>>> Modified: head/sys/dev/hwpmc/hwpmc_logging.c >>>> ============================================================================== >>>> --- head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -129,6 +129,7 @@ static struct mtx pmc_kthread_mtx; /* sl >>>> >>>> /* Emit a string. Caution: does NOT update _le, so needs to be last */ >>>> #define PMCLOG_EMITSTRING(S,L) do { bcopy((S), _le, (L)); } while (0) >>>> +#define PMCLOG_EMITNULLSTRING(L) do { bzero(_le, (L)); } while (0) >>>> >>>> #define PMCLOG_DESPATCH(PO) \ >>>> pmclog_release((PO)); \ >>>> @@ -835,16 +836,33 @@ void >>>> pmclog_process_pmcallocate(struct pmc *pm) >>>> { >>>> struct pmc_owner *po; >>>> + struct pmc_soft *ps; >>>> >>>> po = pm->pm_owner; >>>> >>>> PMCDBG(LOG,ALL,1, "pm=%p", pm); >>>> >>>> - PMCLOG_RESERVE(po, PMCALLOCATE, sizeof(struct pmclog_pmcallocate)); >>>> - PMCLOG_EMIT32(pm->pm_id); >>>> - PMCLOG_EMIT32(pm->pm_event); >>>> - PMCLOG_EMIT32(pm->pm_flags); >>>> - PMCLOG_DESPATCH(po); >>>> + if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) { >>>> + PMCLOG_RESERVE(po, PMCALLOCATEDYN, >>>> + sizeof(struct pmclog_pmcallocatedyn)); >>>> + PMCLOG_EMIT32(pm->pm_id); >>>> + PMCLOG_EMIT32(pm->pm_event); >>>> + PMCLOG_EMIT32(pm->pm_flags); >>>> + ps = pmc_soft_ev_acquire(pm->pm_event); >>>> + if (ps != NULL) >>>> + PMCLOG_EMITSTRING(ps->ps_ev.pm_ev_name,PMC_NAME_MAX); >>>> + else >>>> + PMCLOG_EMITNULLSTRING(PMC_NAME_MAX); >>>> + pmc_soft_ev_release(ps); >>>> + PMCLOG_DESPATCH(po); >>>> + } else { >>>> + PMCLOG_RESERVE(po, PMCALLOCATE, >>>> + sizeof(struct pmclog_pmcallocate)); >>>> + PMCLOG_EMIT32(pm->pm_id); >>>> + PMCLOG_EMIT32(pm->pm_event); >>>> + PMCLOG_EMIT32(pm->pm_flags); >>>> + PMCLOG_DESPATCH(po); >>>> + } >>>> } >>>> >>>> void >>>> >>>> Modified: head/sys/dev/hwpmc/hwpmc_mips.c >>>> ============================================================================== >>>> --- head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -287,7 +287,7 @@ mips_pmc_intr(int cpu, struct trapframe >>>> retval = 1; >>>> if (pm->pm_state != PMC_STATE_RUNNING) >>>> continue; >>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>> TRAPF_USERMODE(tf)); >>>> if (error) { >>>> /* Clear/disable the relevant counter */ >>>> >>>> Modified: head/sys/dev/hwpmc/hwpmc_mod.c >>>> ============================================================================== >>>> --- head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:49:11 2012 (r233627) >>>> +++ head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:58:30 2012 (r233628) >>>> @@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$"); >>>> #include <vm/vm_map.h> >>>> #include <vm/vm_object.h> >>>> >>>> +#include "hwpmc_soft.h" >>>> + >>>> /* >>>> * Types >>>> */ >>>> @@ -182,7 +184,7 @@ static int pmc_attach_one_process(struct >>>> static int pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, >>>> int cpu); >>>> static int pmc_can_attach(struct pmc *pm, struct proc *p); >>>> -static void pmc_capture_user_callchain(int cpu, struct trapframe *tf); >>>> +static void pmc_capture_user_callchain(int cpu, int soft, struct trapframe *tf); >>>> static void pmc_cleanup(void); >>>> static int pmc_detach_process(struct proc *p, struct pmc *pm); >>>> static int pmc_detach_one_process(struct proc *p, struct pmc *pm, >>>> @@ -206,7 +208,7 @@ static void pmc_process_csw_out(struct t >>>> static void pmc_process_exit(void *arg, struct proc *p); >>>> static void pmc_process_fork(void *arg, struct proc *p1, >>>> struct proc *p2, int n); >>>> -static void pmc_process_samples(int cpu); >>>> +static void pmc_process_samples(int cpu, int soft); >>>> static void pmc_release_pmc_descriptor(struct pmc *pmc); >>>> static void pmc_remove_owner(struct pmc_owner *po); >>>> static void pmc_remove_process_descriptor(struct pmc_process *pp); >>>> @@ -218,12 +220,16 @@ static int pmc_stop(struct pmc *pm); >>>> static int pmc_syscall_handler(struct thread *td, void *syscall_args); >>>> static void pmc_unlink_target_process(struct pmc *pmc, >>>> struct pmc_process *pp); >>>> +static int generic_switch_in(struct pmc_cpu *pc, struct pmc_process *pp); >>>> +static int generic_switch_out(struct pmc_cpu *pc, struct pmc_process *pp); >>>> +static struct pmc_mdep *pmc_generic_cpu_initialize(void); >>>> +static void pmc_generic_cpu_finalize(struct pmc_mdep *md); >>>> >>>> /* >>>> * Kernel tunables and sysctl(8) interface. >>>> */ >>>> >>>> -SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters"); >>>> +SYSCTL_DECL(_kern_hwpmc); >>>> >>>> static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; >>>> TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "callchaindepth", &pmc_callchaindepth); >>>> @@ -1833,7 +1839,9 @@ const char *pmc_hooknames[] = { >>>> "KLDUNLOAD", >>>> "MMAP", >>>> "MUNMAP", >>>> - "CALLCHAIN" >>>> + "CALLCHAIN-NMI", >>>> + "CALLCHAIN-SOFT", >>>> + "SOFTSAMPLING" >>>> }; >>>> #endif >>>> >>>> @@ -1992,7 +2000,8 @@ pmc_hook_handler(struct thread *td, int >>>> * lose the interrupt sample. >>>> */ >>>> CPU_CLR_ATOMIC(PCPU_GET(cpuid), &pmc_cpumask); >>>> - pmc_process_samples(PCPU_GET(cpuid)); >>>> + pmc_process_samples(PCPU_GET(cpuid), PMC_HR); >>>> + pmc_process_samples(PCPU_GET(cpuid), PMC_SR); >>>> break; >>>> >>>> >>>> @@ -2022,11 +2031,30 @@ pmc_hook_handler(struct thread *td, int >>>> */ >>>> KASSERT(td == curthread, ("[pmc,%d] td != curthread", >>>> __LINE__)); >>>> - pmc_capture_user_callchain(PCPU_GET(cpuid), >>>> + >>>> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_HR, >>>> (struct trapframe *) arg); >>>> td->td_pflags &= ~TDP_CALLCHAIN; >>>> break; >>>> >>>> + case PMC_FN_USER_CALLCHAIN_SOFT: >>>> + /* >>>> + * Record a call chain. >>>> + */ >>>> + KASSERT(td == curthread, ("[pmc,%d] td != curthread", >>>> + __LINE__)); >>>> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_SR, >>>> + (struct trapframe *) arg); >>>> + td->td_pflags &= ~TDP_CALLCHAIN; >>>> + break; >>>> + >>>> + case PMC_FN_SOFT_SAMPLING: >>>> + /* >>>> + * Call soft PMC sampling intr. >>>> + */ >>>> + pmc_soft_intr((struct pmckern_soft *) arg); >>>> + break; >>>> + >>>> default: >>>> #ifdef DEBUG >>>> KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function)); >>>> @@ -2221,18 +2249,17 @@ pmc_destroy_pmc_descriptor(struct pmc *p >>>> static void >>>> pmc_wait_for_pmc_idle(struct pmc *pm) >>>> { >>>> -#ifdef DEBUG >>>> +#ifdef DEBUG >>>> volatile int maxloop; >>>> >>>> maxloop = 100 * pmc_cpu_max(); >>>> #endif >>>> - >>>> /* >>>> * Loop (with a forced context switch) till the PMC's runcount >>>> * comes down to zero. >>>> */ >>>> while (atomic_load_acq_32(&pm->pm_runcount) > 0) { >>>> -#ifdef DEBUG >>>> +#ifdef DEBUG >>>> maxloop--; >>>> KASSERT(maxloop > 0, >>>> ("[pmc,%d] (ri%d, rc%d) waiting too long for " >>>> @@ -2972,6 +2999,53 @@ pmc_syscall_handler(struct thread *td, v >>>> } >>>> break; >>>> >>>> + /* >>>> + * Retrieve soft events list. >>>> + */ >>>> + case PMC_OP_GETDYNEVENTINFO: >>>> + { >>>> + enum pmc_class cl; >>>> + enum pmc_event ev; >>>> + struct pmc_op_getdyneventinfo *gei; >>>> + struct pmc_dyn_event_descr dev; >>>> + struct pmc_soft *ps; >>>> + uint32_t nevent; >>>> + >>>> + sx_assert(&pmc_sx, SX_LOCKED); >>>> + >>>> + gei = (struct pmc_op_getdyneventinfo *) arg; >>>> + >>>> + if ((error = copyin(&gei->pm_class, &cl, sizeof(cl))) != 0) >>>> + break; >>>> + >>>> + /* Only SOFT class is dynamic. */ >>>> + if (cl != PMC_CLASS_SOFT) { >>>> + error = EINVAL; >>>> + break; >>>> + } >>>> + >>>> + nevent = 0; >>>> + for (ev = PMC_EV_SOFT_FIRST; ev <= PMC_EV_SOFT_LAST; ev++) { >>>> + ps = pmc_soft_ev_acquire(ev); >>>> + if (ps == NULL) >>>> + continue; >>>> + bcopy(&ps->ps_ev, &dev, sizeof(dev)); >>>> + pmc_soft_ev_release(ps); >>>> + >>>> + error = copyout(&dev, >>>> + &gei->pm_events[nevent], >>>> + sizeof(struct pmc_dyn_event_descr)); >>>> + if (error != 0) >>>> + break; >>>> + nevent++; >>>> + } >>>> + if (error != 0) >>>> + break; >>>> + >>>> + error = copyout(&nevent, &gei->pm_nevent, >>>> >>>> *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** >> >> >> >> -- >> Monthadar Al Jaberi >> <RSPRO_USB_PROD> > > -- Monthadar Al Jaberi _______________________________________________ [hidden email] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-mips To unsubscribe, send any mail to "[hidden email]" |
|
Le 23 avr. 2012 à 10:06, Monthadar Al Jaberi a écrit : > On Mon, Apr 23, 2012 at 9:47 AM, Fabien Thomas <[hidden email]> wrote: >> Hi, >> >> The rumors seems true :) >> Can you try the patch attached (I cannot test as i've no MIPS hardware) ? > > my RSPRO boots fine now, thank you :) > commited as r234598. Thanks! >> >> Thanks, >> Fabien >> >> >>> On Mon, Apr 23, 2012 at 8:44 AM, Adrian Chadd <[hidden email]> wrote: >>>> Hi Fabien, >>>> >>>> I've heard some rumours that this broke hwpmc support for mips24k. >>>> >>>> Monthadar, can you please provide some background info for this? >>>> >>> >>> This is the log output >>> >>> Using default protocol (TFTP) >>> Entry point: 0x80050100, address range: 0x80050000-0x804f1dcc >>> RedBoot> exec >>> Now booting linux kernel: >>> Base address 0x80050000 Entry 0x80050100 >>> memsize=0x08000000 >>> modetty0=0,n,8,1,hw >>> board=RouterStation PRO >>> ethaddr=00.15.6d.c8.c9.2e >>> CPU platform: Atheros AR7161 rev 2 >>> CPU Frequency=720 MHz >>> CPU DDR Frequency=360 MHz >>> CPU AHB Frequency=180 MHz >>> platform frequency: 720000000 >>> arguments: >>> a0 = 00000002 >>> a1 = 80050028 >>> a2 = 80050000 >>> a3 = 00000001 >>> Cmd line: �������m���������������_}������߾q��������������� �����������������߿���������_�w���� �����?-����{������~�� >>> Environment: >>> memsize = 0x08000000 >>> modetty0 = 0,n,8,1,hw >>> ethaddr = 00.15.6d.c8.c9.2e >>> board = RouterStation PRO >>> Cache info: >>> picache_stride = 4096 >>> picache_loopcount = 16 >>> pdcache_stride = 4096 >>> pdcache_loopcount = 8 >>> cpu0: MIPS Technologies processor v116.147 >>> MMU: Standard TLB, 16 entries >>> L1 i-cache: 4 ways of 512 sets, 32 bytes per line >>> L1 d-cache: 4 ways of 256 sets, 32 bytes per line >>> Config1=0x9ee3519e<PerfCount,WatchRegs,MIPS16,EJTAG> >>> Config3=0x20 >>> KDB: debugger backends: ddb >>> KDB: current backend: ddb >>> Copyright (c) 1992-2012 The FreeBSD Project. >>> Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 >>> The Regents of the University of California. All rights reserved. >>> FreeBSD is a registered trademark of The FreeBSD Foundation. >>> FreeBSD 10.0-CURRENT #12: Fri Apr 20 18:03:16 CEST 2012 >>> root@freebsd-re-9:/usr/obj/mips.mips/usr/src/sys/RSPRO_USB_PROD mips >>> WARNING: WITNESS option enabled, expect reduced performance. >>> MEMGUARD DEBUGGING ALLOCATOR INITIALIZED: >>> MEMGUARD map base: 0xc0800000 >>> MEMGUARD map limit: 0xc1c00000 >>> MEMGUARD map size: 20480 KBytes >>> real memory = 134217728 (131072K bytes) >>> avail memory = 123117568 (117MB) >>> random device not loaded; using insecure entropy >>> nexus0: <MIPS32 root nexus> >>> clock0: <Generic MIPS32 ticker> on nexus0 >>> Timecounter "MIPS32" frequency 360000000 Hz quality 800 >>> Event timer "MIPS32" frequency 360000000 Hz quality 800 >>> apb0 at irq 4 on nexus0 >>> uart0: <16550 or compatible> on apb0 >>> uart0: console (115200,n,8,1) >>> gpio0: <Atheros AR71XX GPIO driver> on apb0 >>> gpio0: [GIANT-LOCKED] >>> gpio0: gpio pinmask=0x0 >>> gpioc0: <GPIO controller> on gpio0 >>> gpiobus0: <GPIO bus> on gpio0 >>> ehci0: <AR71XX Integrated USB 2.0 controller> at mem >>> 0x1b000000-0x1bffffff irq 1 on nexus0 >>> usbus0: set host controller mode >>> usbus0: EHCI version 1.0 >>> usbus0: set host controller mode >>> usbus0 on ehci0 >>> pcib0 at irq 0 on nexus0 >>> pci0: <PCI bus> on pcib0 >>> pci0: <old, non-VGA display device> at device 0.0 (no driver attached) >>> ath0: <Atheros 5413> irq 0 at device 17.0 on pci0 >>> ath0: AR5413 mac 10.5 RF5413 phy 6.1 >>> ath0: 2GHz radio: 0x0000; 5GHz radio: 0x0063 >>> arge0: <Atheros AR71xx built-in ethernet interface> at mem >>> 0x19000000-0x19000fff irq 2 on nexus0 >>> arge0: No PHY specified, using mask 16 >>> miibus0: <MII bus> on arge0 >>> ukphy0: <Generic IEEE 802.3u media interface> PHY 4 on miibus0 >>> ukphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, >>> 1000baseT-FDX, 1000baseT-FDX-master, auto >>> arge0: Ethernet address: 00:15:6d:c8:c9:2e >>> arge1: <Atheros AR71xx built-in ethernet interface> at mem >>> 0x1a000000-0x1a000fff irq 3 on nexus0 >>> arge1: No PHY specified, using mask 15 >>> arge1: Ethernet address: 00:15:6d:c8:c9:2f >>> spi0: <AR71XX SPI> at mem 0x1f000000-0x1f00000f on nexus0 >>> spibus0: <spibus bus> on spi0 >>> mx25l0: <M25Pxx Flash Family> at cs 0 on spibus0 >>> mx25l0: mx25ll128, sector 65536 bytes, 256 sectors >>> ar71xx_wdog0: <Atheros AR71XX watchdog timer> on nexus0 >>> Timecounters tick every 1.000 msec >>> usbus0: 480Mbps High Speed USB v2.0 >>> ugen0.1: <Atheros> at usbus0 >>> uhub0: <Atheros EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0 >>> panic: [pmc,4816] npmc miscomputed: ri=0, md->npmc=2 >>> KDB: enter: panic >>> [ thread pid 0 tid 100000 ] >>> Stopped at kdb_enter+0x4c: lui at,0x8050 >>> db> tr >>> Tracing pid 0 tid 100000 td 0x804f76d0 >>> db_trace_thread+30 (?,?,?,?) ra 8068b94800000018 sp 0 sz 0 >>> 80075adc+114 (0,?,ffffffff,?) ra 8068b96000000020 sp 100000000 sz 1 >>> 80074e24+388 (?,?,?,?) ra 8068b980000000a8 sp 0 sz 0 >>> db_command_loop+70 (?,?,?,?) ra 8068ba2800000018 sp 0 sz 0 >>> 80077900+f4 (?,?,?,?) ra 8068ba40000001a8 sp 0 sz 0 >>> kdb_trap+110 (?,?,?,?) ra 8068bbe800000030 sp 0 sz 0 >>> trap+c7c (?,?,?,?) ra 8068bc18000000b8 sp 0 sz 0 >>> MipsKernGenException+134 (0,4,8043b1d4,119) ra 8068bcd0000000c8 sp >>> 100000001 sz 1 >>> kdb_enter+4c (?,?,?,?) ra 8068bd9800000018 sp 0 sz 0 >>> panic+11c (?,12d0,0,2) ra 8068bdb000000028 sp 1 sz 1 >>> 800e8ca8+274 (?,?,?,?) ra 8068bdd800000038 sp 0 sz 0 >>> syscall_module_handler+b8 (?,?,?,?) ra 8068be1000000028 sp 0 sz 0 >>> module_register_init+9c (?,?,?,?) ra 8068be3800000028 sp 0 sz 0 >>> mi_startup+138 (?,?,?,?) ra 8068be6000000020 sp 0 sz 0 >>> _start+90 (?,?,?,?) ra 8068be8000000000 sp 0 sz 0 >>> pid 0 >>> db> >>> >>>> Thanks, >>>> >>>> >>>> >>>> adrian >>>> >>>> On 28 March 2012 13:58, Fabien Thomas <[hidden email]> wrote: >>>>> Author: fabient >>>>> Date: Wed Mar 28 20:58:30 2012 >>>>> New Revision: 233628 >>>>> URL: http://svn.freebsd.org/changeset/base/233628 >>>>> >>>>> Log: >>>>> Add software PMC support. >>>>> >>>>> New kernel events can be added at various location for sampling or counting. >>>>> This will for example allow easy system profiling whatever the processor is >>>>> with known tools like pmcstat(8). >>>>> >>>>> Simultaneous usage of software PMC and hardware PMC is possible, for example >>>>> looking at the lock acquire failure, page fault while sampling on >>>>> instructions. >>>>> >>>>> Sponsored by: NETASQ >>>>> MFC after: 1 month >>>>> >>>>> Added: >>>>> head/lib/libpmc/pmc.soft.3 (contents, props changed) >>>>> head/sys/dev/hwpmc/hwpmc_soft.c (contents, props changed) >>>>> head/sys/dev/hwpmc/hwpmc_soft.h (contents, props changed) >>>>> Modified: >>>>> head/lib/libpmc/Makefile >>>>> head/lib/libpmc/libpmc.c >>>>> head/lib/libpmc/pmc.3 >>>>> head/lib/libpmc/pmc.atom.3 >>>>> head/lib/libpmc/pmc.core.3 >>>>> head/lib/libpmc/pmc.core2.3 >>>>> head/lib/libpmc/pmc.corei7.3 >>>>> head/lib/libpmc/pmc.corei7uc.3 >>>>> head/lib/libpmc/pmc.iaf.3 >>>>> head/lib/libpmc/pmc.k7.3 >>>>> head/lib/libpmc/pmc.k8.3 >>>>> head/lib/libpmc/pmc.mips24k.3 >>>>> head/lib/libpmc/pmc.octeon.3 >>>>> head/lib/libpmc/pmc.p4.3 >>>>> head/lib/libpmc/pmc.p5.3 >>>>> head/lib/libpmc/pmc.p6.3 >>>>> head/lib/libpmc/pmc.sandybridge.3 >>>>> head/lib/libpmc/pmc.sandybridgeuc.3 >>>>> head/lib/libpmc/pmc.tsc.3 >>>>> head/lib/libpmc/pmc.ucf.3 >>>>> head/lib/libpmc/pmc.westmere.3 >>>>> head/lib/libpmc/pmc.westmereuc.3 >>>>> head/lib/libpmc/pmc.xscale.3 >>>>> head/lib/libpmc/pmclog.c >>>>> head/lib/libpmc/pmclog.h >>>>> head/sys/amd64/amd64/trap.c >>>>> head/sys/amd64/include/pmc_mdep.h >>>>> head/sys/arm/include/pmc_mdep.h >>>>> head/sys/conf/files >>>>> head/sys/dev/hwpmc/hwpmc_amd.c >>>>> head/sys/dev/hwpmc/hwpmc_core.c >>>>> head/sys/dev/hwpmc/hwpmc_intel.c >>>>> head/sys/dev/hwpmc/hwpmc_logging.c >>>>> head/sys/dev/hwpmc/hwpmc_mips.c >>>>> head/sys/dev/hwpmc/hwpmc_mod.c >>>>> head/sys/dev/hwpmc/hwpmc_piv.c >>>>> head/sys/dev/hwpmc/hwpmc_powerpc.c >>>>> head/sys/dev/hwpmc/hwpmc_ppro.c >>>>> head/sys/dev/hwpmc/hwpmc_tsc.c >>>>> head/sys/dev/hwpmc/hwpmc_x86.c >>>>> head/sys/dev/hwpmc/hwpmc_xscale.c >>>>> head/sys/dev/hwpmc/pmc_events.h >>>>> head/sys/i386/i386/trap.c >>>>> head/sys/i386/include/pmc_mdep.h >>>>> head/sys/kern/kern_clock.c >>>>> head/sys/kern/kern_lock.c >>>>> head/sys/kern/kern_mutex.c >>>>> head/sys/kern/kern_pmc.c >>>>> head/sys/kern/kern_rwlock.c >>>>> head/sys/kern/kern_sx.c >>>>> head/sys/kern/subr_trap.c >>>>> head/sys/mips/include/pmc_mdep.h >>>>> head/sys/modules/hwpmc/Makefile >>>>> head/sys/powerpc/include/pmc_mdep.h >>>>> head/sys/sys/pmc.h >>>>> head/sys/sys/pmckern.h >>>>> head/sys/sys/pmclog.h >>>>> head/usr.sbin/pmcstat/pmcstat_log.c >>>>> >>>>> Modified: head/lib/libpmc/Makefile >>>>> ============================================================================== >>>>> --- head/lib/libpmc/Makefile Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/Makefile Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -20,6 +20,7 @@ MAN+= pmc_read.3 >>>>> MAN+= pmc_set.3 >>>>> MAN+= pmc_start.3 >>>>> MAN+= pmclog.3 >>>>> +MAN+= pmc.soft.3 >>>>> >>>>> # PMC-dependent manual pages >>>>> .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" >>>>> >>>>> Modified: head/lib/libpmc/libpmc.c >>>>> ============================================================================== >>>>> --- head/lib/libpmc/libpmc.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/libpmc.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_eve >>>>> static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >>>>> struct pmc_op_pmcallocate *_pmc_config); >>>>> #endif >>>>> - >>>>> #if defined(__mips__) >>>>> static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec, >>>>> struct pmc_op_pmcallocate *_pmc_config); >>>>> #endif /* __mips__ */ >>>>> +static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec, >>>>> + struct pmc_op_pmcallocate *_pmc_config); >>>>> >>>>> #if defined(__powerpc__) >>>>> static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec, >>>>> @@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON); >>>>> PMC_CLASSDEP_TABLE(ucf, UCF); >>>>> PMC_CLASSDEP_TABLE(ppc7450, PPC7450); >>>>> >>>>> +static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; >>>>> + >>>>> #undef __PMC_EV_ALIAS >>>>> #define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE }, >>>>> >>>>> @@ -215,21 +218,22 @@ static const struct pmc_event_descr west >>>>> PMC_CLASS_##C, __VA_ARGS__ \ >>>>> } >>>>> >>>>> -PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>>> -PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>>> -PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>>> -PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC); >>>>> -PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE); >>>>> -PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K); >>>>> -PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON); >>>>> -PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450); >>>>> +PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>>> +PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>>> +PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); >>>>> +PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC); >>>>> +PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); >>>>> +PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); >>>>> +PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); >>>>> +PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); >>>>> +PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); >>>>> >>>>> static const struct pmc_event_descr tsc_event_table[] = >>>>> { >>>>> @@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc) >>>>> #if defined(__XSCALE__) >>>>> PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale); >>>>> #endif >>>>> - >>>>> #if defined(__mips__) >>>>> PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); >>>>> PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); >>>>> #endif /* __mips__ */ >>>>> - >>>>> #if defined(__powerpc__) >>>>> PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450); >>>>> #endif >>>>> >>>>> +static struct pmc_class_descr soft_class_table_descr = >>>>> +{ >>>>> + .pm_evc_name = "SOFT-", >>>>> + .pm_evc_name_size = sizeof("SOFT-") - 1, >>>>> + .pm_evc_class = PMC_CLASS_SOFT, >>>>> + .pm_evc_event_table = NULL, >>>>> + .pm_evc_event_table_size = 0, >>>>> + .pm_evc_allocate_pmc = soft_allocate_pmc >>>>> +}; >>>>> + >>>>> #undef PMC_CLASS_TABLE_DESC >>>>> >>>>> static const struct pmc_class_descr **pmc_class_table; >>>>> @@ -343,9 +355,12 @@ static const char * pmc_state_names[] = >>>>> __PMC_STATES() >>>>> }; >>>>> >>>>> -static int pmc_syscall = -1; /* filled in by pmc_init() */ >>>>> - >>>>> -static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */ >>>>> +/* >>>>> + * Filled in by pmc_init(). >>>>> + */ >>>>> +static int pmc_syscall = -1; >>>>> +static struct pmc_cpuinfo cpu_info; >>>>> +static struct pmc_op_getdyneventinfo soft_event_info; >>>>> >>>>> /* Event masks for events */ >>>>> struct pmc_masks { >>>>> @@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char >>>>> } >>>>> #endif >>>>> >>>>> +static struct pmc_event_alias generic_aliases[] = { >>>>> + EV_ALIAS("instructions", "SOFT-CLOCK.HARD"), >>>>> + EV_ALIAS(NULL, NULL) >>>>> +}; >>>>> + >>>>> +static int >>>>> +soft_allocate_pmc(enum pmc_event pe, char *ctrspec, >>>>> + struct pmc_op_pmcallocate *pmc_config) >>>>> +{ >>>>> + (void)ctrspec; >>>>> + (void)pmc_config; >>>>> + >>>>> + if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST) >>>>> + return (-1); >>>>> + >>>>> + pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); >>>>> + return (0); >>>>> +} >>>>> + >>>>> #if defined(__XSCALE__) >>>>> >>>>> static struct pmc_event_alias xscale_aliases[] = { >>>>> @@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class >>>>> ev = ppc7450_event_table; >>>>> count = PMC_EVENT_TABLE_SIZE(ppc7450); >>>>> break; >>>>> + case PMC_CLASS_SOFT: >>>>> + ev = soft_event_table; >>>>> + count = soft_event_info.pm_nevent; >>>>> + break; >>>>> default: >>>>> errno = EINVAL; >>>>> return (-1); >>>>> @@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class >>>>> >>>>> for (;count--; ev++, names++) >>>>> *names = ev->pm_ev_name; >>>>> + >>>>> return (0); >>>>> } >>>>> >>>>> @@ -2780,11 +2819,34 @@ pmc_init(void) >>>>> pmc_class_table[n] = NULL; >>>>> >>>>> /* >>>>> + * Get soft events list. >>>>> + */ >>>>> + soft_event_info.pm_class = PMC_CLASS_SOFT; >>>>> + if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0) >>>>> + return (pmc_syscall = -1); >>>>> + >>>>> + /* Map soft events to static list. */ >>>>> + for (n = 0; n < soft_event_info.pm_nevent; n++) { >>>>> + soft_event_table[n].pm_ev_name = >>>>> + soft_event_info.pm_events[n].pm_ev_name; >>>>> + soft_event_table[n].pm_ev_code = >>>>> + soft_event_info.pm_events[n].pm_ev_code; >>>>> + } >>>>> + soft_class_table_descr.pm_evc_event_table_size = \ >>>>> + soft_event_info.pm_nevent; >>>>> + soft_class_table_descr.pm_evc_event_table = \ >>>>> + soft_event_table; >>>>> + >>>>> + /* >>>>> * Fill in the class table. >>>>> */ >>>>> n = 0; >>>>> + >>>>> + /* Fill soft events information. */ >>>>> + pmc_class_table[n++] = &soft_class_table_descr; >>>>> #if defined(__amd64__) || defined(__i386__) >>>>> - pmc_class_table[n++] = &tsc_class_table_descr; >>>>> + if (cpu_info.pm_cputype != PMC_CPU_GENERIC) >>>>> + pmc_class_table[n++] = &tsc_class_table_descr; >>>>> >>>>> /* >>>>> * Check if this CPU has fixed function counters. >>>>> @@ -2867,6 +2929,9 @@ pmc_init(void) >>>>> pmc_class_table[n] = &p4_class_table_descr; >>>>> break; >>>>> #endif >>>>> + case PMC_CPU_GENERIC: >>>>> + PMC_MDEP_INIT(generic); >>>>> + break; >>>>> #if defined(__XSCALE__) >>>>> case PMC_CPU_INTEL_XSCALE: >>>>> PMC_MDEP_INIT(xscale); >>>>> @@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, en >>>>> evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale); >>>>> } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) { >>>>> ev = mips24k_event_table; >>>>> - evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k >>>>> -); >>>>> + evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k); >>>>> } else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) { >>>>> ev = octeon_event_table; >>>>> evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon); >>>>> } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) { >>>>> ev = ppc7450_event_table; >>>>> - evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450 >>>>> -); >>>>> + evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450); >>>>> } else if (pe == PMC_EV_TSC_TSC) { >>>>> ev = tsc_event_table; >>>>> evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); >>>>> + } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) { >>>>> + ev = soft_event_table; >>>>> + evfence = soft_event_table + soft_event_info.pm_nevent; >>>>> } >>>>> >>>>> for (; ev != evfence; ev++) >>>>> >>>>> Modified: head/lib/libpmc/pmc.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -223,6 +223,8 @@ and >>>>> CPUs. >>>>> .It Li PMC_CLASS_TSC >>>>> The timestamp counter on i386 and amd64 architecture CPUs. >>>>> +.It Li PMC_CLASS_SOFT >>>>> +Software events. >>>>> .El >>>>> .Ss PMC Capabilities >>>>> Capabilities of performance monitoring hardware are denoted using >>>>> @@ -525,6 +527,7 @@ API is >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.atom.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.atom.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1176,6 +1176,7 @@ and the underlying hardware events used >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.core.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.core.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.core.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -792,6 +792,7 @@ may not count some transitions. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> >>>>> Modified: head/lib/libpmc/pmc.core2.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.core2.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1107,6 +1107,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.corei7.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.corei7.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1559,6 +1559,7 @@ Counts number of segment register loads. >>>>> .Xr pmc.corei7uc 3 , >>>>> .Xr pmc.westmere 3 , >>>>> .Xr pmc.westmereuc 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.corei7uc.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.corei7uc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -863,6 +863,7 @@ refreshed or needs to go into a power do >>>>> .Xr pmc.corei7 3 , >>>>> .Xr pmc.westmere 3 , >>>>> .Xr pmc.westmereuc 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.iaf.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.iaf.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -132,6 +132,7 @@ CPU, use the event specifier >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.k7.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.k7.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -249,6 +249,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> >>>>> Modified: head/lib/libpmc/pmc.k8.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.k8.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -783,6 +783,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> >>>>> Modified: head/lib/libpmc/pmc.mips24k.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.mips24k.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -392,6 +392,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.octeon.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.octeon.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -232,6 +232,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.p4.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.p4.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1208,6 +1208,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.k8 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> >>>>> Modified: head/lib/libpmc/pmc.p5.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.p5.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -444,6 +444,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.k8 3 , >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> >>>>> Modified: head/lib/libpmc/pmc.p6.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.p6.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1010,6 +1010,7 @@ and the underlying hardware events used. >>>>> .Xr pmc.k8 3 , >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> >>>>> Modified: head/lib/libpmc/pmc.sandybridge.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.sandybridge.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -907,6 +907,7 @@ Split locks in SQ. >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> .Xr pmc.sandybridgeuc 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc.ucf 3 , >>>>> .Xr pmc.westmere 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.sandybridgeuc.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.sandybridgeuc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -208,6 +208,7 @@ Counts the number of core-outgoing entri >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> .Xr pmc.sandybridge 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc.ucf 3 , >>>>> .Xr pmc.westmere 3 , >>>>> >>>>> Added: head/lib/libpmc/pmc.soft.3 >>>>> ============================================================================== >>>>> --- /dev/null 00:00:00 1970 (empty, because file is newly added) >>>>> +++ head/lib/libpmc/pmc.soft.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -0,0 +1,104 @@ >>>>> +.\" Copyright (c) 2012 Fabien Thomas. All rights reserved. >>>>> +.\" >>>>> +.\" Redistribution and use in source and binary forms, with or without >>>>> +.\" modification, are permitted provided that the following conditions >>>>> +.\" are met: >>>>> +.\" 1. Redistributions of source code must retain the above copyright >>>>> +.\" notice, this list of conditions and the following disclaimer. >>>>> +.\" 2. Redistributions in binary form must reproduce the above copyright >>>>> +.\" notice, this list of conditions and the following disclaimer in the >>>>> +.\" documentation and/or other materials provided with the distribution. >>>>> +.\" >>>>> +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >>>>> +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >>>>> +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >>>>> +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >>>>> +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >>>>> +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >>>>> +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >>>>> +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >>>>> +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >>>>> +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >>>>> +.\" SUCH DAMAGE. >>>>> +.\" >>>>> +.\" $FreeBSD$ >>>>> +.\" >>>>> +.Dd March 28, 2012 >>>>> +.Os >>>>> +.Dt PMC.SOFT 3 >>>>> +.Sh NAME >>>>> +.Nm pmc.soft >>>>> +.Nd measurements using software based events >>>>> +.Sh LIBRARY >>>>> +.Lb libpmc >>>>> +.Sh SYNOPSIS >>>>> +.In pmc.h >>>>> +.Sh DESCRIPTION >>>>> +Software events are used to collect various source of software events. >>>>> +.Ss PMC Features >>>>> +16 sampling counters using software events based on various sources. >>>>> +These PMCs support the following capabilities: >>>>> +.Bl -column "PMC_CAP_INTERRUPT" "Support" >>>>> +.It Em Capability Ta Em Support >>>>> +.It PMC_CAP_CASCADE Ta \&No >>>>> +.It PMC_CAP_EDGE Ta \&No >>>>> +.It PMC_CAP_INTERRUPT Ta Yes >>>>> +.It PMC_CAP_INVERT Ta \&No >>>>> +.It PMC_CAP_READ Ta Yes >>>>> +.It PMC_CAP_PRECISE Ta \&No >>>>> +.It PMC_CAP_SYSTEM Ta Yes >>>>> +.It PMC_CAP_TAGGING Ta \&No >>>>> +.It PMC_CAP_THRESHOLD Ta \&No >>>>> +.It PMC_CAP_USER Ta Yes >>>>> +.It PMC_CAP_WRITE Ta Yes >>>>> +.El >>>>> +.Ss Event Qualifiers >>>>> +There is no supported event qualifier. >>>>> +.Pp >>>>> +The event specifiers supported by software are: >>>>> +.Bl -tag -width indent >>>>> +.It Li CLOCK.HARD >>>>> +Hard clock ticks. >>>>> +.It Li CLOCK.STAT >>>>> +Stat clock ticks. >>>>> +.It Li LOCK.FAILED >>>>> +Lock acquisition failed. >>>>> +.It Li PAGE_FAULT.ALL >>>>> +All page fault type. >>>>> +.It Li PAGE_FAULT.READ >>>>> +Read page fault. >>>>> +.It Li PAGE_FAULT.WRITE >>>>> +Write page fault. >>>>> +.El >>>>> +.Sh SEE ALSO >>>>> +.Xr pmc 3 , >>>>> +.Xr pmc.atom 3 , >>>>> +.Xr pmc.core 3 , >>>>> +.Xr pmc.iaf 3 , >>>>> +.Xr pmc.ucf 3 , >>>>> +.Xr pmc.k7 3 , >>>>> +.Xr pmc.k8 3 , >>>>> +.Xr pmc.p4 3 , >>>>> +.Xr pmc.p5 3 , >>>>> +.Xr pmc.p6 3 , >>>>> +.Xr pmc.corei7 3 , >>>>> +.Xr pmc.corei7uc 3 , >>>>> +.Xr pmc.westmereuc 3 , >>>>> +.Xr pmc.tsc 3 , >>>>> +.Xr pmc_cpuinfo 3 , >>>>> +.Xr pmclog 3 , >>>>> +.Xr hwpmc 4 >>>>> +.Sh HISTORY >>>>> +The >>>>> +.Nm pmc >>>>> +library first appeared in >>>>> +.Fx 6.0 . >>>>> +.Sh AUTHORS >>>>> +The >>>>> +.Lb libpmc >>>>> +library was written by >>>>> +.An "Joseph Koshy" >>>>> +.Aq [hidden email] . >>>>> +Software PMC was written by >>>>> +.An "Fabien Thomas" >>>>> +.Aq [hidden email] . >>>>> >>>>> Modified: head/lib/libpmc/pmc.tsc.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.tsc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -68,6 +68,7 @@ maps to the TSC. >>>>> .Xr pmc.p4 3 , >>>>> .Xr pmc.p5 3 , >>>>> .Xr pmc.p6 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmclog 3 , >>>>> .Xr hwpmc 4 >>>>> .Sh HISTORY >>>>> >>>>> Modified: head/lib/libpmc/pmc.ucf.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.ucf.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -96,6 +96,7 @@ offset C0H under device number 0 and Fun >>>>> .Xr pmc.corei7uc 3 , >>>>> .Xr pmc.westmere 3 , >>>>> .Xr pmc.westmereuc 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.westmere.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.westmere.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shif >>>>> .Xr pmc.corei7 3 , >>>>> .Xr pmc.corei7uc 3 , >>>>> .Xr pmc.westmereuc 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.westmereuc.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.westmereuc.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1066,6 +1066,7 @@ disabled. >>>>> .Xr pmc.corei7 3 , >>>>> .Xr pmc.corei7uc 3 , >>>>> .Xr pmc.westmere 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr pmc.tsc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> >>>>> Modified: head/lib/libpmc/pmc.xscale.3 >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmc.xscale.3 Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -134,6 +134,7 @@ and the underlying hardware events used. >>>>> .Xr pmc 3 , >>>>> .Xr pmc_cpuinfo 3 , >>>>> .Xr pmclog 3 , >>>>> +.Xr pmc.soft 3 , >>>>> .Xr hwpmc 4 >>>>> .Sh HISTORY >>>>> The >>>>> >>>>> Modified: head/lib/libpmc/pmclog.c >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmclog.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmclog.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **da >>>>> == NULL) >>>>> goto error; >>>>> break; >>>>> + case PMCLOG_TYPE_PMCALLOCATEDYN: >>>>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid); >>>>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event); >>>>> + PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags); >>>>> + PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX); >>>>> + break; >>>>> case PMCLOG_TYPE_PMCATTACH: >>>>> PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach); >>>>> PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid); >>>>> >>>>> Modified: head/lib/libpmc/pmclog.h >>>>> ============================================================================== >>>>> --- head/lib/libpmc/pmclog.h Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/lib/libpmc/pmclog.h Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate { >>>>> pmc_id_t pl_pmcid; >>>>> }; >>>>> >>>>> +struct pmclog_ev_pmcallocatedyn { >>>>> + uint32_t pl_event; >>>>> + char pl_evname[PMC_NAME_MAX]; >>>>> + uint32_t pl_flags; >>>>> + pmc_id_t pl_pmcid; >>>>> +}; >>>>> + >>>>> struct pmclog_ev_pmcattach { >>>>> pmc_id_t pl_pmcid; >>>>> pid_t pl_pid; >>>>> @@ -146,6 +153,7 @@ struct pmclog_ev { >>>>> struct pmclog_ev_map_out pl_mo; >>>>> struct pmclog_ev_pcsample pl_s; >>>>> struct pmclog_ev_pmcallocate pl_a; >>>>> + struct pmclog_ev_pmcallocatedyn pl_ad; >>>>> struct pmclog_ev_pmcattach pl_t; >>>>> struct pmclog_ev_pmcdetach pl_d; >>>>> struct pmclog_ev_proccsw pl_c; >>>>> >>>>> Modified: head/sys/amd64/amd64/trap.c >>>>> ============================================================================== >>>>> --- head/sys/amd64/amd64/trap.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/amd64/amd64/trap.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$"); >>>>> #include <sys/vmmeter.h> >>>>> #ifdef HWPMC_HOOKS >>>>> #include <sys/pmckern.h> >>>>> +PMC_SOFT_DEFINE( , , page_fault, all); >>>>> +PMC_SOFT_DEFINE( , , page_fault, read); >>>>> +PMC_SOFT_DEFINE( , , page_fault, write); >>>>> #endif >>>>> >>>>> #include <vm/vm.h> >>>>> @@ -743,8 +746,20 @@ trap_pfault(frame, usermode) >>>>> */ >>>>> rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); >>>>> } >>>>> - if (rv == KERN_SUCCESS) >>>>> + if (rv == KERN_SUCCESS) { >>>>> +#ifdef HWPMC_HOOKS >>>>> + if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) { >>>>> + PMC_SOFT_CALL_TF( , , page_fault, all, frame); >>>>> + if (ftype == VM_PROT_READ) >>>>> + PMC_SOFT_CALL_TF( , , page_fault, read, >>>>> + frame); >>>>> + else >>>>> + PMC_SOFT_CALL_TF( , , page_fault, write, >>>>> + frame); >>>>> + } >>>>> +#endif >>>>> return (0); >>>>> + } >>>>> nogo: >>>>> if (!usermode) { >>>>> if (td->td_intr_nesting_level == 0 && >>>>> >>>>> Modified: head/sys/amd64/include/pmc_mdep.h >>>>> ============================================================================== >>>>> --- head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/amd64/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -50,13 +50,13 @@ struct pmc_mdep; >>>>> * measurement architecture have PMCs of the following classes: TSC, >>>>> * IAF, IAP, UCF and UCP. >>>>> */ >>>>> -#define PMC_MDEP_CLASS_INDEX_TSC 0 >>>>> -#define PMC_MDEP_CLASS_INDEX_K8 1 >>>>> -#define PMC_MDEP_CLASS_INDEX_P4 1 >>>>> -#define PMC_MDEP_CLASS_INDEX_IAP 1 >>>>> -#define PMC_MDEP_CLASS_INDEX_IAF 2 >>>>> -#define PMC_MDEP_CLASS_INDEX_UCP 3 >>>>> -#define PMC_MDEP_CLASS_INDEX_UCF 4 >>>>> +#define PMC_MDEP_CLASS_INDEX_TSC 1 >>>>> +#define PMC_MDEP_CLASS_INDEX_K8 2 >>>>> +#define PMC_MDEP_CLASS_INDEX_P4 2 >>>>> +#define PMC_MDEP_CLASS_INDEX_IAP 2 >>>>> +#define PMC_MDEP_CLASS_INDEX_IAF 3 >>>>> +#define PMC_MDEP_CLASS_INDEX_UCP 4 >>>>> +#define PMC_MDEP_CLASS_INDEX_UCF 5 >>>>> >>>>> /* >>>>> * On the amd64 platform we support the following PMCs. >>>>> @@ -119,6 +119,15 @@ union pmc_md_pmc { >>>>> >>>>> #define PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS) >>>>> >>>>> +/* Build a fake kernel trapframe from current instruction pointer. */ >>>>> +#define PMC_FAKE_TRAPFRAME(TF) \ >>>>> + do { \ >>>>> + (TF)->tf_cs = 0; (TF)->tf_rflags = 0; \ >>>>> + __asm __volatile("movq %%rbp,%0" : "=r" ((TF)->tf_rbp)); \ >>>>> + __asm __volatile("movq %%rsp,%0" : "=r" ((TF)->tf_rsp)); \ >>>>> + __asm __volatile("call 1f \n\t1: pop %0" : "=r"((TF)->tf_rip)); \ >>>>> + } while (0) >>>>> + >>>>> /* >>>>> * Prototypes >>>>> */ >>>>> >>>>> Modified: head/sys/arm/include/pmc_mdep.h >>>>> ============================================================================== >>>>> --- head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/arm/include/pmc_mdep.h Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -29,7 +29,7 @@ >>>>> #ifndef _MACHINE_PMC_MDEP_H_ >>>>> #define _MACHINE_PMC_MDEP_H_ >>>>> >>>>> -#define PMC_MDEP_CLASS_INDEX_XSCALE 0 >>>>> +#define PMC_MDEP_CLASS_INDEX_XSCALE 1 >>>>> /* >>>>> * On the ARM platform we support the following PMCs. >>>>> * >>>>> >>>>> Modified: head/sys/conf/files >>>>> ============================================================================== >>>>> --- head/sys/conf/files Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/conf/files Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -1260,6 +1260,7 @@ dev/hme/if_hme_sbus.c optional hme sbus >>>>> dev/hptiop/hptiop.c optional hptiop scbus >>>>> dev/hwpmc/hwpmc_logging.c optional hwpmc >>>>> dev/hwpmc/hwpmc_mod.c optional hwpmc >>>>> +dev/hwpmc/hwpmc_soft.c optional hwpmc >>>>> dev/ichsmb/ichsmb.c optional ichsmb >>>>> dev/ichsmb/ichsmb_pci.c optional ichsmb pci >>>>> dev/ida/ida.c optional ida >>>>> >>>>> Modified: head/sys/dev/hwpmc/hwpmc_amd.c >>>>> ============================================================================== >>>>> --- head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/dev/hwpmc/hwpmc_amd.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -687,7 +687,8 @@ amd_intr(int cpu, struct trapframe *tf) >>>>> wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v)); >>>>> >>>>> /* Restart the counter if logging succeeded. */ >>>>> - error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf)); >>>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>>> + TRAPF_USERMODE(tf)); >>>>> if (error == 0) >>>>> wrmsr(evsel, config | AMD_PMC_ENABLE); >>>>> } >>>>> @@ -874,7 +875,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int c >>>>> struct pmc_mdep * >>>>> pmc_amd_initialize(void) >>>>> { >>>>> - int classindex, error, i, nclasses, ncpus; >>>>> + int classindex, error, i, ncpus; >>>>> struct pmc_classdep *pcd; >>>>> enum pmc_cputype cputype; >>>>> struct pmc_mdep *pmc_mdep; >>>>> @@ -926,12 +927,9 @@ pmc_amd_initialize(void) >>>>> * These processors have two classes of PMCs: the TSC and >>>>> * programmable PMCs. >>>>> */ >>>>> - nclasses = 2; >>>>> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * sizeof (struct pmc_classdep), >>>>> - M_PMC, M_WAITOK|M_ZERO); >>>>> + pmc_mdep = pmc_mdep_alloc(2); >>>>> >>>>> pmc_mdep->pmd_cputype = cputype; >>>>> - pmc_mdep->pmd_nclass = nclasses; >>>>> >>>>> ncpus = pmc_cpu_max(); >>>>> >>>>> >>>>> Modified: head/sys/dev/hwpmc/hwpmc_core.c >>>>> ============================================================================== >>>>> --- head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/dev/hwpmc/hwpmc_core.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -2239,7 +2239,7 @@ core_intr(int cpu, struct trapframe *tf) >>>>> if (pm->pm_state != PMC_STATE_RUNNING) >>>>> continue; >>>>> >>>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>>> TRAPF_USERMODE(tf)); >>>>> >>>>> v = pm->pm_sc.pm_reloadcount; >>>>> @@ -2326,7 +2326,7 @@ core2_intr(int cpu, struct trapframe *tf >>>>> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >>>>> continue; >>>>> >>>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>>> TRAPF_USERMODE(tf)); >>>>> if (error) >>>>> intrenable &= ~flag; >>>>> @@ -2354,7 +2354,7 @@ core2_intr(int cpu, struct trapframe *tf >>>>> !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) >>>>> continue; >>>>> >>>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>>> TRAPF_USERMODE(tf)); >>>>> if (error) >>>>> intrenable &= ~flag; >>>>> >>>>> Modified: head/sys/dev/hwpmc/hwpmc_intel.c >>>>> ============================================================================== >>>>> --- head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/dev/hwpmc/hwpmc_intel.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -162,12 +162,10 @@ pmc_intel_initialize(void) >>>>> return (NULL); >>>>> } >>>>> >>>>> - pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * >>>>> - sizeof(struct pmc_classdep), M_PMC, M_WAITOK|M_ZERO); >>>>> + /* Allocate base class and initialize machine dependent struct */ >>>>> + pmc_mdep = pmc_mdep_alloc(nclasses); >>>>> >>>>> pmc_mdep->pmd_cputype = cputype; >>>>> - pmc_mdep->pmd_nclass = nclasses; >>>>> - >>>>> pmc_mdep->pmd_switch_in = intel_switch_in; >>>>> pmc_mdep->pmd_switch_out = intel_switch_out; >>>>> >>>>> >>>>> Modified: head/sys/dev/hwpmc/hwpmc_logging.c >>>>> ============================================================================== >>>>> --- head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/dev/hwpmc/hwpmc_logging.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -129,6 +129,7 @@ static struct mtx pmc_kthread_mtx; /* sl >>>>> >>>>> /* Emit a string. Caution: does NOT update _le, so needs to be last */ >>>>> #define PMCLOG_EMITSTRING(S,L) do { bcopy((S), _le, (L)); } while (0) >>>>> +#define PMCLOG_EMITNULLSTRING(L) do { bzero(_le, (L)); } while (0) >>>>> >>>>> #define PMCLOG_DESPATCH(PO) \ >>>>> pmclog_release((PO)); \ >>>>> @@ -835,16 +836,33 @@ void >>>>> pmclog_process_pmcallocate(struct pmc *pm) >>>>> { >>>>> struct pmc_owner *po; >>>>> + struct pmc_soft *ps; >>>>> >>>>> po = pm->pm_owner; >>>>> >>>>> PMCDBG(LOG,ALL,1, "pm=%p", pm); >>>>> >>>>> - PMCLOG_RESERVE(po, PMCALLOCATE, sizeof(struct pmclog_pmcallocate)); >>>>> - PMCLOG_EMIT32(pm->pm_id); >>>>> - PMCLOG_EMIT32(pm->pm_event); >>>>> - PMCLOG_EMIT32(pm->pm_flags); >>>>> - PMCLOG_DESPATCH(po); >>>>> + if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) { >>>>> + PMCLOG_RESERVE(po, PMCALLOCATEDYN, >>>>> + sizeof(struct pmclog_pmcallocatedyn)); >>>>> + PMCLOG_EMIT32(pm->pm_id); >>>>> + PMCLOG_EMIT32(pm->pm_event); >>>>> + PMCLOG_EMIT32(pm->pm_flags); >>>>> + ps = pmc_soft_ev_acquire(pm->pm_event); >>>>> + if (ps != NULL) >>>>> + PMCLOG_EMITSTRING(ps->ps_ev.pm_ev_name,PMC_NAME_MAX); >>>>> + else >>>>> + PMCLOG_EMITNULLSTRING(PMC_NAME_MAX); >>>>> + pmc_soft_ev_release(ps); >>>>> + PMCLOG_DESPATCH(po); >>>>> + } else { >>>>> + PMCLOG_RESERVE(po, PMCALLOCATE, >>>>> + sizeof(struct pmclog_pmcallocate)); >>>>> + PMCLOG_EMIT32(pm->pm_id); >>>>> + PMCLOG_EMIT32(pm->pm_event); >>>>> + PMCLOG_EMIT32(pm->pm_flags); >>>>> + PMCLOG_DESPATCH(po); >>>>> + } >>>>> } >>>>> >>>>> void >>>>> >>>>> Modified: head/sys/dev/hwpmc/hwpmc_mips.c >>>>> ============================================================================== >>>>> --- head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/dev/hwpmc/hwpmc_mips.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -287,7 +287,7 @@ mips_pmc_intr(int cpu, struct trapframe >>>>> retval = 1; >>>>> if (pm->pm_state != PMC_STATE_RUNNING) >>>>> continue; >>>>> - error = pmc_process_interrupt(cpu, pm, tf, >>>>> + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, >>>>> TRAPF_USERMODE(tf)); >>>>> if (error) { >>>>> /* Clear/disable the relevant counter */ >>>>> >>>>> Modified: head/sys/dev/hwpmc/hwpmc_mod.c >>>>> ============================================================================== >>>>> --- head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:49:11 2012 (r233627) >>>>> +++ head/sys/dev/hwpmc/hwpmc_mod.c Wed Mar 28 20:58:30 2012 (r233628) >>>>> @@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$"); >>>>> #include <vm/vm_map.h> >>>>> #include <vm/vm_object.h> >>>>> >>>>> +#include "hwpmc_soft.h" >>>>> + >>>>> /* >>>>> * Types >>>>> */ >>>>> @@ -182,7 +184,7 @@ static int pmc_attach_one_process(struct >>>>> static int pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, >>>>> int cpu); >>>>> static int pmc_can_attach(struct pmc *pm, struct proc *p); >>>>> -static void pmc_capture_user_callchain(int cpu, struct trapframe *tf); >>>>> +static void pmc_capture_user_callchain(int cpu, int soft, struct trapframe *tf); >>>>> static void pmc_cleanup(void); >>>>> static int pmc_detach_process(struct proc *p, struct pmc *pm); >>>>> static int pmc_detach_one_process(struct proc *p, struct pmc *pm, >>>>> @@ -206,7 +208,7 @@ static void pmc_process_csw_out(struct t >>>>> static void pmc_process_exit(void *arg, struct proc *p); >>>>> static void pmc_process_fork(void *arg, struct proc *p1, >>>>> struct proc *p2, int n); >>>>> -static void pmc_process_samples(int cpu); >>>>> +static void pmc_process_samples(int cpu, int soft); >>>>> static void pmc_release_pmc_descriptor(struct pmc *pmc); >>>>> static void pmc_remove_owner(struct pmc_owner *po); >>>>> static void pmc_remove_process_descriptor(struct pmc_process *pp); >>>>> @@ -218,12 +220,16 @@ static int pmc_stop(struct pmc *pm); >>>>> static int pmc_syscall_handler(struct thread *td, void *syscall_args); >>>>> static void pmc_unlink_target_process(struct pmc *pmc, >>>>> struct pmc_process *pp); >>>>> +static int generic_switch_in(struct pmc_cpu *pc, struct pmc_process *pp); >>>>> +static int generic_switch_out(struct pmc_cpu *pc, struct pmc_process *pp); >>>>> +static struct pmc_mdep *pmc_generic_cpu_initialize(void); >>>>> +static void pmc_generic_cpu_finalize(struct pmc_mdep *md); >>>>> >>>>> /* >>>>> * Kernel tunables and sysctl(8) interface. >>>>> */ >>>>> >>>>> -SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters"); >>>>> +SYSCTL_DECL(_kern_hwpmc); >>>>> >>>>> static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; >>>>> TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "callchaindepth", &pmc_callchaindepth); >>>>> @@ -1833,7 +1839,9 @@ const char *pmc_hooknames[] = { >>>>> "KLDUNLOAD", >>>>> "MMAP", >>>>> "MUNMAP", >>>>> - "CALLCHAIN" >>>>> + "CALLCHAIN-NMI", >>>>> + "CALLCHAIN-SOFT", >>>>> + "SOFTSAMPLING" >>>>> }; >>>>> #endif >>>>> >>>>> @@ -1992,7 +2000,8 @@ pmc_hook_handler(struct thread *td, int >>>>> * lose the interrupt sample. >>>>> */ >>>>> CPU_CLR_ATOMIC(PCPU_GET(cpuid), &pmc_cpumask); >>>>> - pmc_process_samples(PCPU_GET(cpuid)); >>>>> + pmc_process_samples(PCPU_GET(cpuid), PMC_HR); >>>>> + pmc_process_samples(PCPU_GET(cpuid), PMC_SR); >>>>> break; >>>>> >>>>> >>>>> @@ -2022,11 +2031,30 @@ pmc_hook_handler(struct thread *td, int >>>>> */ >>>>> KASSERT(td == curthread, ("[pmc,%d] td != curthread", >>>>> __LINE__)); >>>>> - pmc_capture_user_callchain(PCPU_GET(cpuid), >>>>> + >>>>> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_HR, >>>>> (struct trapframe *) arg); >>>>> td->td_pflags &= ~TDP_CALLCHAIN; >>>>> break; >>>>> >>>>> + case PMC_FN_USER_CALLCHAIN_SOFT: >>>>> + /* >>>>> + * Record a call chain. >>>>> + */ >>>>> + KASSERT(td == curthread, ("[pmc,%d] td != curthread", >>>>> + __LINE__)); >>>>> + pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_SR, >>>>> + (struct trapframe *) arg); >>>>> + td->td_pflags &= ~TDP_CALLCHAIN; >>>>> + break; >>>>> + >>>>> + case PMC_FN_SOFT_SAMPLING: >>>>> + /* >>>>> + * Call soft PMC sampling intr. >>>>> + */ >>>>> + pmc_soft_intr((struct pmckern_soft *) arg); >>>>> + break; >>>>> + >>>>> default: >>>>> #ifdef DEBUG >>>>> KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function)); >>>>> @@ -2221,18 +2249,17 @@ pmc_destroy_pmc_descriptor(struct pmc *p >>>>> static void >>>>> pmc_wait_for_pmc_idle(struct pmc *pm) >>>>> { >>>>> -#ifdef DEBUG >>>>> +#ifdef DEBUG >>>>> volatile int maxloop; >>>>> >>>>> maxloop = 100 * pmc_cpu_max(); >>>>> #endif >>>>> - >>>>> /* >>>>> * Loop (with a forced context switch) till the PMC's runcount >>>>> * comes down to zero. >>>>> */ >>>>> while (atomic_load_acq_32(&pm->pm_runcount) > 0) { >>>>> -#ifdef DEBUG >>>>> +#ifdef DEBUG >>>>> maxloop--; >>>>> KASSERT(maxloop > 0, >>>>> ("[pmc,%d] (ri%d, rc%d) waiting too long for " >>>>> @@ -2972,6 +2999,53 @@ pmc_syscall_handler(struct thread *td, v >>>>> } >>>>> break; >>>>> >>>>> + /* >>>>> + * Retrieve soft events list. >>>>> + */ >>>>> + case PMC_OP_GETDYNEVENTINFO: >>>>> + { >>>>> + enum pmc_class cl; >>>>> + enum pmc_event ev; >>>>> + struct pmc_op_getdyneventinfo *gei; >>>>> + struct pmc_dyn_event_descr dev; >>>>> + struct pmc_soft *ps; >>>>> + uint32_t nevent; >>>>> + >>>>> + sx_assert(&pmc_sx, SX_LOCKED); >>>>> + >>>>> + gei = (struct pmc_op_getdyneventinfo *) arg; >>>>> + >>>>> + if ((error = copyin(&gei->pm_class, &cl, sizeof(cl))) != 0) >>>>> + break; >>>>> + >>>>> + /* Only SOFT class is dynamic. */ >>>>> + if (cl != PMC_CLASS_SOFT) { >>>>> + error = EINVAL; >>>>> + break; >>>>> + } >>>>> + >>>>> + nevent = 0; >>>>> + for (ev = PMC_EV_SOFT_FIRST; ev <= PMC_EV_SOFT_LAST; ev++) { >>>>> + ps = pmc_soft_ev_acquire(ev); >>>>> + if (ps == NULL) >>>>> + continue; >>>>> + bcopy(&ps->ps_ev, &dev, sizeof(dev)); >>>>> + pmc_soft_ev_release(ps); >>>>> + >>>>> + error = copyout(&dev, >>>>> + &gei->pm_events[nevent], >>>>> + sizeof(struct pmc_dyn_event_descr)); >>>>> + if (error != 0) >>>>> + break; >>>>> + nevent++; >>>>> + } >>>>> + if (error != 0) >>>>> + break; >>>>> + >>>>> + error = copyout(&nevent, &gei->pm_nevent, >>>>> >>>>> *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** >>> >>> >>> >>> -- >>> Monthadar Al Jaberi >>> <RSPRO_USB_PROD> >> >> > > > > -- > Monthadar Al Jaberi |
| Powered by Nabble | Edit this page |
