svn commit: r233628 - in head: lib/libpmc sys/amd64/amd64
sys/amd64/include sys/arm/include sys/conf sys/dev/hwpmc sys/i386/i386
sys/i386/include sys/kern sys/mips/include sys/modules/hwpmc sys/pow...
Monthadar Al Jaberi
monthadar at gmail.com
Mon Apr 23 08:06:45 UTC 2012
On Mon, Apr 23, 2012 at 9:47 AM, Fabien Thomas <fabien.thomas at netasq.com> 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 <adrian at freebsd.org> 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 at 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 <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)
>>>> @@ -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 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)
>>>> @@ -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
More information about the freebsd-current
mailing list