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) >>>> _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 *** >> >> >> >> -- >> Monthadar Al Jaberi >> <RSPRO_USB_PROD> > > -- Monthadar Al JaberiReceived on Mon Apr 23 2012 - 06:06:44 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:26 UTC