Re: 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...

From: Monthadar Al Jaberi <monthadar_at_gmail.com>
Date: Mon, 23 Apr 2012 08:55:21 +0200
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

Received on Mon Apr 23 2012 - 04:55:24 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:26 UTC