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 <fabient_at_freebsd.org> 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) > _at__at_ -20,6 +20,7 _at__at_ 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) > _at__at_ -77,11 +77,12 _at__at_ 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, > _at__at_ -156,6 +157,8 _at__at_ 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 }, > > _at__at_ -215,21 +218,22 _at__at_ 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[] = > { > _at__at_ -279,16 +283,24 _at__at_ 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; > _at__at_ -343,9 +355,12 _at__at_ 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 { > _at__at_ -2179,6 +2194,25 _at__at_ 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[] = { > _at__at_ -2663,6 +2697,10 _at__at_ 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); > _at__at_ -2676,6 +2714,7 _at__at_ pmc_event_names_of_class(enum pmc_class > > for (;count--; ev++, names++) > *names = ev->pm_ev_name; > + > return (0); > } > > _at__at_ -2780,11 +2819,34 _at__at_ 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. > _at__at_ -2867,6 +2929,9 _at__at_ 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); > _at__at_ -3035,18 +3100,19 _at__at_ _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) > _at__at_ -223,6 +223,8 _at__at_ 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 > _at__at_ -525,6 +527,7 _at__at_ 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) > _at__at_ -1176,6 +1176,7 _at__at_ 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) > _at__at_ -792,6 +792,7 _at__at_ 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) > _at__at_ -1107,6 +1107,7 _at__at_ 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) > _at__at_ -1559,6 +1559,7 _at__at_ 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) > _at__at_ -863,6 +863,7 _at__at_ 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) > _at__at_ -132,6 +132,7 _at__at_ 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) > _at__at_ -249,6 +249,7 _at__at_ 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) > _at__at_ -783,6 +783,7 _at__at_ 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) > _at__at_ -392,6 +392,7 _at__at_ 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) > _at__at_ -232,6 +232,7 _at__at_ 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) > _at__at_ -1208,6 +1208,7 _at__at_ 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) > _at__at_ -444,6 +444,7 _at__at_ 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) > _at__at_ -1010,6 +1010,7 _at__at_ 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) > _at__at_ -907,6 +907,7 _at__at_ 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) > _at__at_ -208,6 +208,7 _at__at_ 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) > _at__at_ -0,0 +1,104 _at__at_ > +.\" 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 jkoshy_at_FreeBSD.org . > +Software PMC was written by > +.An "Fabien Thomas" > +.Aq fabient_at_FreeBSD.org . > > 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) > _at__at_ -68,6 +68,7 _at__at_ 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) > _at__at_ -96,6 +96,7 _at__at_ 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) > _at__at_ -1381,6 +1381,7 _at__at_ 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) > _at__at_ -1066,6 +1066,7 _at__at_ 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) > _at__at_ -134,6 +134,7 _at__at_ 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) > _at__at_ -369,6 +369,12 _at__at_ 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) > _at__at_ -88,6 +88,13 _at__at_ 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; > _at__at_ -146,6 +153,7 _at__at_ 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) > _at__at_ -71,6 +71,9 _at__at_ __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> > _at__at_ -743,8 +746,20 _at__at_ 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) > _at__at_ -50,13 +50,13 _at__at_ 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. > _at__at_ -119,6 +119,15 _at__at_ 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) > _at__at_ -29,7 +29,7 _at__at_ > #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) > _at__at_ -1260,6 +1260,7 _at__at_ 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) > _at__at_ -687,7 +687,8 _at__at_ 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); > } > _at__at_ -874,7 +875,7 _at__at_ 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; > _at__at_ -926,12 +927,9 _at__at_ 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) > _at__at_ -2239,7 +2239,7 _at__at_ 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; > _at__at_ -2326,7 +2326,7 _at__at_ 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; > _at__at_ -2354,7 +2354,7 _at__at_ 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) > _at__at_ -162,12 +162,10 _at__at_ 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) > _at__at_ -129,6 +129,7 _at__at_ 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)); \ > _at__at_ -835,16 +836,33 _at__at_ 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) > _at__at_ -287,7 +287,7 _at__at_ 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) > _at__at_ -70,6 +70,8 _at__at_ __FBSDID("$FreeBSD$"); > #include <vm/vm_map.h> > #include <vm/vm_object.h> > > +#include "hwpmc_soft.h" > + > /* > * Types > */ > _at__at_ -182,7 +184,7 _at__at_ 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, > _at__at_ -206,7 +208,7 _at__at_ 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); > _at__at_ -218,12 +220,16 _at__at_ 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); > _at__at_ -1833,7 +1839,9 _at__at_ const char *pmc_hooknames[] = { > "KLDUNLOAD", > "MMAP", > "MUNMAP", > - "CALLCHAIN" > + "CALLCHAIN-NMI", > + "CALLCHAIN-SOFT", > + "SOFTSAMPLING" > }; > #endif > > _at__at_ -1992,7 +2000,8 _at__at_ 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; > > > _at__at_ -2022,11 +2031,30 _at__at_ 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)); > _at__at_ -2221,18 +2249,17 _at__at_ 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 " > _at__at_ -2972,6 +2999,53 _at__at_ 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 ***Received on Mon Apr 23 2012 - 04:44:13 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:26 UTC