svn commit: r236238 - in stable/9: lib/libpmc sys/amd64/amd64 sys/amd64/include sys/arm/arm sys/arm/include sys/conf sys/dev/hwpmc sys/i386/i386 sys/i386/include sys/kern sys/mips/include sys/modul...

Fabien Thomas fabient at FreeBSD.org
Tue May 29 14:50:23 UTC 2012


Author: fabient
Date: Tue May 29 14:50:21 2012
New Revision: 236238
URL: http://svn.freebsd.org/changeset/base/236238

Log:
  MFC r233628, r234598, r235229, r235831, r226986.
  
  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

Added:
  stable/9/lib/libpmc/pmc.soft.3
     - copied unchanged from r233628, head/lib/libpmc/pmc.soft.3
  stable/9/sys/dev/hwpmc/hwpmc_soft.c
     - copied unchanged from r233628, head/sys/dev/hwpmc/hwpmc_soft.c
  stable/9/sys/dev/hwpmc/hwpmc_soft.h
     - copied unchanged from r233628, head/sys/dev/hwpmc/hwpmc_soft.h
Modified:
  stable/9/lib/libpmc/Makefile
  stable/9/lib/libpmc/libpmc.c
  stable/9/lib/libpmc/pmc.3
  stable/9/lib/libpmc/pmc.atom.3
  stable/9/lib/libpmc/pmc.core.3
  stable/9/lib/libpmc/pmc.core2.3
  stable/9/lib/libpmc/pmc.corei7.3
  stable/9/lib/libpmc/pmc.corei7uc.3
  stable/9/lib/libpmc/pmc.iaf.3
  stable/9/lib/libpmc/pmc.k7.3
  stable/9/lib/libpmc/pmc.k8.3
  stable/9/lib/libpmc/pmc.p4.3
  stable/9/lib/libpmc/pmc.p5.3
  stable/9/lib/libpmc/pmc.p6.3
  stable/9/lib/libpmc/pmc.sandybridge.3
  stable/9/lib/libpmc/pmc.sandybridgeuc.3
  stable/9/lib/libpmc/pmc.tsc.3
  stable/9/lib/libpmc/pmc.ucf.3
  stable/9/lib/libpmc/pmc.westmere.3
  stable/9/lib/libpmc/pmc.westmereuc.3
  stable/9/lib/libpmc/pmc.xscale.3
  stable/9/lib/libpmc/pmclog.c
  stable/9/lib/libpmc/pmclog.h
  stable/9/sys/amd64/amd64/trap.c
  stable/9/sys/amd64/include/pmc_mdep.h
  stable/9/sys/arm/arm/machdep.c
  stable/9/sys/arm/include/pmc_mdep.h
  stable/9/sys/conf/files
  stable/9/sys/dev/hwpmc/hwpmc_amd.c
  stable/9/sys/dev/hwpmc/hwpmc_arm.c
  stable/9/sys/dev/hwpmc/hwpmc_core.c
  stable/9/sys/dev/hwpmc/hwpmc_intel.c
  stable/9/sys/dev/hwpmc/hwpmc_logging.c
  stable/9/sys/dev/hwpmc/hwpmc_mod.c
  stable/9/sys/dev/hwpmc/hwpmc_piv.c
  stable/9/sys/dev/hwpmc/hwpmc_powerpc.c
  stable/9/sys/dev/hwpmc/hwpmc_ppro.c
  stable/9/sys/dev/hwpmc/hwpmc_tsc.c
  stable/9/sys/dev/hwpmc/hwpmc_x86.c
  stable/9/sys/dev/hwpmc/hwpmc_xscale.c
  stable/9/sys/dev/hwpmc/pmc_events.h
  stable/9/sys/i386/i386/trap.c
  stable/9/sys/i386/include/pmc_mdep.h
  stable/9/sys/kern/kern_clock.c
  stable/9/sys/kern/kern_lock.c
  stable/9/sys/kern/kern_mutex.c
  stable/9/sys/kern/kern_pmc.c
  stable/9/sys/kern/kern_rwlock.c
  stable/9/sys/kern/kern_sx.c
  stable/9/sys/kern/subr_trap.c
  stable/9/sys/mips/include/pmc_mdep.h
  stable/9/sys/modules/hwpmc/Makefile
  stable/9/sys/powerpc/include/pmc_mdep.h
  stable/9/sys/sys/pmc.h
  stable/9/sys/sys/pmckern.h
  stable/9/sys/sys/pmclog.h
  stable/9/usr.sbin/pmcstat/pmcstat.c
  stable/9/usr.sbin/pmcstat/pmcstat_log.c
Directory Properties:
  stable/9/lib/libpmc/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/dev/   (props changed)
  stable/9/sys/modules/   (props changed)
  stable/9/usr.sbin/pmcstat/   (props changed)

Modified: stable/9/lib/libpmc/Makefile
==============================================================================
--- stable/9/lib/libpmc/Makefile	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/Makefile	Tue May 29 14:50:21 2012	(r236238)
@@ -20,6 +20,7 @@ MAN+=	pmc_read.3
 MAN+=	pmc_set.3
 MAN+=	pmc_start.3
 MAN+=	pmclog.3
+MAN+=	pmc.soft.3
 
 # PMC-dependent manual pages
 .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"

Modified: stable/9/lib/libpmc/libpmc.c
==============================================================================
--- stable/9/lib/libpmc/libpmc.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/libpmc.c	Tue May 29 14:50:21 2012	(r236238)
@@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_eve
 static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
     struct pmc_op_pmcallocate *_pmc_config);
 #endif
-
 #if defined(__mips__)
 static int mips24k_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,
@@ -155,6 +156,8 @@ PMC_CLASSDEP_TABLE(mips24k, MIPS24K);
 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 },
 
@@ -214,20 +217,21 @@ 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(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(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[] =
 {
@@ -277,15 +281,23 @@ 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, mips24k);
 #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;
@@ -340,9 +352,12 @@ static const char * pmc_state_names[] = 
 	__PMC_STATES()
 };
 
-static int pmc_syscall = -1;		/* filled in by pmc_init() */
-
-static struct pmc_cpuinfo cpu_info;	/* filled in by pmc_init() */
+/*
+ * Filled in by pmc_init().
+ */
+static int pmc_syscall = -1;
+static struct pmc_cpuinfo cpu_info;
+static struct pmc_op_getdyneventinfo soft_event_info;
 
 /* Event masks for events */
 struct pmc_masks {
@@ -2176,6 +2191,25 @@ tsc_allocate_pmc(enum pmc_event pe, char
 }
 #endif
 
+static struct pmc_event_alias generic_aliases[] = {
+	EV_ALIAS("instructions",		"SOFT-CLOCK.HARD"),
+	EV_ALIAS(NULL, NULL)
+};
+
+static int
+soft_allocate_pmc(enum pmc_event pe, char *ctrspec,
+    struct pmc_op_pmcallocate *pmc_config)
+{
+	(void)ctrspec;
+	(void)pmc_config;
+
+	if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST)
+		return (-1);
+
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+	return (0);
+}
+
 #if	defined(__XSCALE__)
 
 static struct pmc_event_alias xscale_aliases[] = {
@@ -2648,6 +2682,10 @@ pmc_event_names_of_class(enum pmc_class 
 		ev = ppc7450_event_table;
 		count = PMC_EVENT_TABLE_SIZE(ppc7450);
 		break;
+	case PMC_CLASS_SOFT:
+		ev = soft_event_table;
+		count = soft_event_info.pm_nevent;
+		break;
 	default:
 		errno = EINVAL;
 		return (-1);
@@ -2661,6 +2699,7 @@ pmc_event_names_of_class(enum pmc_class 
 
 	for (;count--; ev++, names++)
 		*names = ev->pm_ev_name;
+
 	return (0);
 }
 
@@ -2765,11 +2804,34 @@ pmc_init(void)
 		pmc_class_table[n] = NULL;
 
 	/*
+	 * Get soft events list.
+	 */
+	soft_event_info.pm_class = PMC_CLASS_SOFT;
+	if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0)
+		return (pmc_syscall = -1);
+
+	/* Map soft events to static list. */
+	for (n = 0; n < soft_event_info.pm_nevent; n++) {
+		soft_event_table[n].pm_ev_name =
+		    soft_event_info.pm_events[n].pm_ev_name;
+		soft_event_table[n].pm_ev_code =
+		    soft_event_info.pm_events[n].pm_ev_code;
+	}
+	soft_class_table_descr.pm_evc_event_table_size = \
+	    soft_event_info.pm_nevent;
+	soft_class_table_descr.pm_evc_event_table = \
+	    soft_event_table;
+
+	/*
 	 * Fill in the class table.
 	 */
 	n = 0;
+
+	/* Fill soft events information. */
+	pmc_class_table[n++] = &soft_class_table_descr;
 #if defined(__amd64__) || defined(__i386__)
-	pmc_class_table[n++] = &tsc_class_table_descr;
+	if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
+		pmc_class_table[n++] = &tsc_class_table_descr;
 
 	/*
  	 * Check if this CPU has fixed function counters.
@@ -2852,6 +2914,9 @@ pmc_init(void)
 		pmc_class_table[n] = &p4_class_table_descr;
 		break;
 #endif
+	case PMC_CPU_GENERIC:
+		PMC_MDEP_INIT(generic);
+		break;
 #if defined(__XSCALE__)
 	case PMC_CPU_INTEL_XSCALE:
 		PMC_MDEP_INIT(xscale);
@@ -3016,15 +3081,16 @@ _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_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: stable/9/lib/libpmc/pmc.3
==============================================================================
--- stable/9/lib/libpmc/pmc.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.3	Tue May 29 14:50:21 2012	(r236238)
@@ -223,6 +223,8 @@ and
 CPUs.
 .It Li PMC_CLASS_TSC
 The timestamp counter on i386 and amd64 architecture CPUs.
+.It Li PMC_CLASS_SOFT
+Software events.
 .El
 .Ss PMC Capabilities
 .Pp
@@ -526,6 +528,7 @@ API is
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4 ,

Modified: stable/9/lib/libpmc/pmc.atom.3
==============================================================================
--- stable/9/lib/libpmc/pmc.atom.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.atom.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1176,6 +1176,7 @@ and the underlying hardware events used 
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.core.3
==============================================================================
--- stable/9/lib/libpmc/pmc.core.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.core.3	Tue May 29 14:50:21 2012	(r236238)
@@ -792,6 +792,7 @@ may not count some transitions.
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4

Modified: stable/9/lib/libpmc/pmc.core2.3
==============================================================================
--- stable/9/lib/libpmc/pmc.core2.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.core2.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1107,6 +1107,7 @@ and the underlying hardware events used.
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.corei7.3
==============================================================================
--- stable/9/lib/libpmc/pmc.corei7.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.corei7.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1559,6 +1559,7 @@ Counts number of segment register loads.
 .Xr pmc.corei7uc 3 ,
 .Xr pmc.westmere 3 ,
 .Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.corei7uc.3
==============================================================================
--- stable/9/lib/libpmc/pmc.corei7uc.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.corei7uc.3	Tue May 29 14:50:21 2012	(r236238)
@@ -863,6 +863,7 @@ refreshed or needs to go into a power do
 .Xr pmc.corei7 3 ,
 .Xr pmc.westmere 3 ,
 .Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.iaf.3
==============================================================================
--- stable/9/lib/libpmc/pmc.iaf.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.iaf.3	Tue May 29 14:50:21 2012	(r236238)
@@ -132,6 +132,7 @@ CPU, use the event specifier
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.k7.3
==============================================================================
--- stable/9/lib/libpmc/pmc.k7.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.k7.3	Tue May 29 14:50:21 2012	(r236238)
@@ -250,6 +250,7 @@ and the underlying hardware events used.
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4

Modified: stable/9/lib/libpmc/pmc.k8.3
==============================================================================
--- stable/9/lib/libpmc/pmc.k8.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.k8.3	Tue May 29 14:50:21 2012	(r236238)
@@ -784,6 +784,7 @@ and the underlying hardware events used.
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4

Modified: stable/9/lib/libpmc/pmc.p4.3
==============================================================================
--- stable/9/lib/libpmc/pmc.p4.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.p4.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1209,6 +1209,7 @@ and the underlying hardware events used.
 .Xr pmc.k8 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4

Modified: stable/9/lib/libpmc/pmc.p5.3
==============================================================================
--- stable/9/lib/libpmc/pmc.p5.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.p5.3	Tue May 29 14:50:21 2012	(r236238)
@@ -444,6 +444,7 @@ and the underlying hardware events used.
 .Xr pmc.k8 3 ,
 .Xr pmc.p4 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4

Modified: stable/9/lib/libpmc/pmc.p6.3
==============================================================================
--- stable/9/lib/libpmc/pmc.p6.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.p6.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1010,6 +1010,7 @@ and the underlying hardware events used.
 .Xr pmc.k8 3 ,
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4

Modified: stable/9/lib/libpmc/pmc.sandybridge.3
==============================================================================
--- stable/9/lib/libpmc/pmc.sandybridge.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.sandybridge.3	Tue May 29 14:50:21 2012	(r236238)
@@ -907,6 +907,7 @@ Split locks in SQ.
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
 .Xr pmc.sandybridgeuc 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc.ucf 3 ,
 .Xr pmc.westmere 3 ,

Modified: stable/9/lib/libpmc/pmc.sandybridgeuc.3
==============================================================================
--- stable/9/lib/libpmc/pmc.sandybridgeuc.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.sandybridgeuc.3	Tue May 29 14:50:21 2012	(r236238)
@@ -208,6 +208,7 @@ Counts the number of core-outgoing entri
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
 .Xr pmc.sandybridge 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc.ucf 3 ,
 .Xr pmc.westmere 3 ,

Copied: stable/9/lib/libpmc/pmc.soft.3 (from r233628, head/lib/libpmc/pmc.soft.3)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/9/lib/libpmc/pmc.soft.3	Tue May 29 14:50:21 2012	(r236238, copy of r233628, head/lib/libpmc/pmc.soft.3)
@@ -0,0 +1,104 @@
+.\" Copyright (c) 2012 Fabien Thomas.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 28, 2012
+.Os
+.Dt PMC.SOFT 3
+.Sh NAME
+.Nm pmc.soft
+.Nd measurements using software based events
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+Software events are used to collect various source of software events.
+.Ss PMC Features
+16 sampling counters using software events based on various sources.
+These PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta \&No
+.It PMC_CAP_INTERRUPT Ta Yes
+.It PMC_CAP_INVERT Ta \&No
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta Yes
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta \&No
+.It PMC_CAP_USER Ta Yes
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+There is no supported event qualifier.
+.Pp
+The event specifiers supported by software are:
+.Bl -tag -width indent
+.It Li CLOCK.HARD
+Hard clock ticks.
+.It Li CLOCK.STAT
+Stat clock ticks.
+.It Li LOCK.FAILED
+Lock acquisition failed.
+.It Li PAGE_FAULT.ALL
+All page fault type.
+.It Li PAGE_FAULT.READ
+Read page fault.
+.It Li PAGE_FAULT.WRITE
+Write page fault.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy at FreeBSD.org .
+Software PMC was written by
+.An "Fabien Thomas"
+.Aq fabient at FreeBSD.org .

Modified: stable/9/lib/libpmc/pmc.tsc.3
==============================================================================
--- stable/9/lib/libpmc/pmc.tsc.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.tsc.3	Tue May 29 14:50:21 2012	(r236238)
@@ -68,6 +68,7 @@ maps to the TSC.
 .Xr pmc.p4 3 ,
 .Xr pmc.p5 3 ,
 .Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmclog 3 ,
 .Xr hwpmc 4
 .Sh HISTORY

Modified: stable/9/lib/libpmc/pmc.ucf.3
==============================================================================
--- stable/9/lib/libpmc/pmc.ucf.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.ucf.3	Tue May 29 14:50:21 2012	(r236238)
@@ -96,6 +96,7 @@ offset C0H under device number 0 and Fun
 .Xr pmc.corei7uc 3 ,
 .Xr pmc.westmere 3 ,
 .Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.westmere.3
==============================================================================
--- stable/9/lib/libpmc/pmc.westmere.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.westmere.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shif
 .Xr pmc.corei7 3 ,
 .Xr pmc.corei7uc 3 ,
 .Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.westmereuc.3
==============================================================================
--- stable/9/lib/libpmc/pmc.westmereuc.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.westmereuc.3	Tue May 29 14:50:21 2012	(r236238)
@@ -1066,6 +1066,7 @@ disabled.
 .Xr pmc.corei7 3 ,
 .Xr pmc.corei7uc 3 ,
 .Xr pmc.westmere 3 ,
+.Xr pmc.soft 3 ,
 .Xr pmc.tsc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,

Modified: stable/9/lib/libpmc/pmc.xscale.3
==============================================================================
--- stable/9/lib/libpmc/pmc.xscale.3	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmc.xscale.3	Tue May 29 14:50:21 2012	(r236238)
@@ -134,6 +134,7 @@ and the underlying hardware events used.
 .Xr pmc 3 ,
 .Xr pmc_cpuinfo 3 ,
 .Xr pmclog 3 ,
+.Xr pmc.soft 3 ,
 .Xr hwpmc 4
 .Sh HISTORY
 The

Modified: stable/9/lib/libpmc/pmclog.c
==============================================================================
--- stable/9/lib/libpmc/pmclog.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmclog.c	Tue May 29 14:50:21 2012	(r236238)
@@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **da
 		    == NULL)
 			goto error;
 		break;
+	case PMCLOG_TYPE_PMCALLOCATEDYN:
+		PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid);
+		PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event);
+		PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags);
+		PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX);
+		break;
 	case PMCLOG_TYPE_PMCATTACH:
 		PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach);
 		PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid);

Modified: stable/9/lib/libpmc/pmclog.h
==============================================================================
--- stable/9/lib/libpmc/pmclog.h	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/lib/libpmc/pmclog.h	Tue May 29 14:50:21 2012	(r236238)
@@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate {
 	pmc_id_t	pl_pmcid;
 };
 
+struct pmclog_ev_pmcallocatedyn {
+	uint32_t	pl_event;
+	char 		pl_evname[PMC_NAME_MAX];
+	uint32_t	pl_flags;
+	pmc_id_t	pl_pmcid;
+};
+
 struct pmclog_ev_pmcattach {
 	pmc_id_t	pl_pmcid;
 	pid_t		pl_pid;
@@ -146,6 +153,7 @@ struct pmclog_ev {
 		struct pmclog_ev_map_out	pl_mo;
 		struct pmclog_ev_pcsample	pl_s;
 		struct pmclog_ev_pmcallocate	pl_a;
+		struct pmclog_ev_pmcallocatedyn	pl_ad;
 		struct pmclog_ev_pmcattach	pl_t;
 		struct pmclog_ev_pmcdetach	pl_d;
 		struct pmclog_ev_proccsw	pl_c;

Modified: stable/9/sys/amd64/amd64/trap.c
==============================================================================
--- stable/9/sys/amd64/amd64/trap.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/amd64/amd64/trap.c	Tue May 29 14:50:21 2012	(r236238)
@@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/vmmeter.h>
 #ifdef HWPMC_HOOKS
 #include <sys/pmckern.h>
+PMC_SOFT_DEFINE( , , page_fault, all);
+PMC_SOFT_DEFINE( , , page_fault, read);
+PMC_SOFT_DEFINE( , , page_fault, write);
 #endif
 
 #include <vm/vm.h>
@@ -746,8 +749,20 @@ trap_pfault(frame, usermode)
 		 */
 		rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
 	}
-	if (rv == KERN_SUCCESS)
+	if (rv == KERN_SUCCESS) {
+#ifdef HWPMC_HOOKS
+		if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) {
+			PMC_SOFT_CALL_TF( , , page_fault, all, frame);
+			if (ftype == VM_PROT_READ)
+				PMC_SOFT_CALL_TF( , , page_fault, read,
+				    frame);
+			else
+				PMC_SOFT_CALL_TF( , , page_fault, write,
+				    frame);
+		}
+#endif
 		return (0);
+	}
 nogo:
 	if (!usermode) {
 		if (td->td_intr_nesting_level == 0 &&

Modified: stable/9/sys/amd64/include/pmc_mdep.h
==============================================================================
--- stable/9/sys/amd64/include/pmc_mdep.h	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/amd64/include/pmc_mdep.h	Tue May 29 14:50:21 2012	(r236238)
@@ -50,13 +50,13 @@ struct pmc_mdep;
  * measurement architecture have PMCs of the following classes: TSC,
  * IAF, IAP, UCF and UCP.
  */
-#define	PMC_MDEP_CLASS_INDEX_TSC	0
-#define	PMC_MDEP_CLASS_INDEX_K8		1
-#define	PMC_MDEP_CLASS_INDEX_P4		1
-#define	PMC_MDEP_CLASS_INDEX_IAP	1
-#define	PMC_MDEP_CLASS_INDEX_IAF	2
-#define	PMC_MDEP_CLASS_INDEX_UCP	3
-#define	PMC_MDEP_CLASS_INDEX_UCF	4
+#define	PMC_MDEP_CLASS_INDEX_TSC	1
+#define	PMC_MDEP_CLASS_INDEX_K8		2
+#define	PMC_MDEP_CLASS_INDEX_P4		2
+#define	PMC_MDEP_CLASS_INDEX_IAP	2
+#define	PMC_MDEP_CLASS_INDEX_IAF	3
+#define	PMC_MDEP_CLASS_INDEX_UCP	4
+#define	PMC_MDEP_CLASS_INDEX_UCF	5
 
 /*
  * On the amd64 platform we support the following PMCs.
@@ -119,6 +119,15 @@ union pmc_md_pmc {
 
 #define	PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS)
 
+/* Build a fake kernel trapframe from current instruction pointer. */
+#define PMC_FAKE_TRAPFRAME(TF)						\
+	do {								\
+	(TF)->tf_cs = 0; (TF)->tf_rflags = 0;				\
+	__asm __volatile("movq %%rbp,%0" : "=r" ((TF)->tf_rbp));	\
+	__asm __volatile("movq %%rsp,%0" : "=r" ((TF)->tf_rsp));	\
+	__asm __volatile("call 1f \n\t1: pop %0" : "=r"((TF)->tf_rip));	\
+	} while (0)
+
 /*
  * Prototypes
  */

Modified: stable/9/sys/arm/arm/machdep.c
==============================================================================
--- stable/9/sys/arm/arm/machdep.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/arm/arm/machdep.c	Tue May 29 14:50:21 2012	(r236238)
@@ -674,9 +674,9 @@ fake_preload_metadata(void)
 	static uint32_t fake_preload[35];
 
 	fake_preload[i++] = MODINFO_NAME;
-	fake_preload[i++] = strlen("elf kernel") + 1;
-	strcpy((char*)&fake_preload[i++], "elf kernel");
-	i += 2;
+	fake_preload[i++] = strlen("kernel") + 1;
+	strcpy((char*)&fake_preload[i++], "kernel");
+	i += 1;
 	fake_preload[i++] = MODINFO_TYPE;
 	fake_preload[i++] = strlen("elf kernel") + 1;
 	strcpy((char*)&fake_preload[i++], "elf kernel");

Modified: stable/9/sys/arm/include/pmc_mdep.h
==============================================================================
--- stable/9/sys/arm/include/pmc_mdep.h	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/arm/include/pmc_mdep.h	Tue May 29 14:50:21 2012	(r236238)
@@ -29,7 +29,7 @@
 #ifndef _MACHINE_PMC_MDEP_H_
 #define	_MACHINE_PMC_MDEP_H_
 
-#define	PMC_MDEP_CLASS_INDEX_XSCALE	0
+#define	PMC_MDEP_CLASS_INDEX_XSCALE	1
 /*
  * On the ARM platform we support the following PMCs.
  *
@@ -54,6 +54,12 @@ union pmc_md_pmc {
 #define	PMC_TRAPFRAME_TO_FP(TF)	((TF)->tf_usr_lr)
 #define	PMC_TRAPFRAME_TO_SP(TF)	((TF)->tf_usr_sp)
 
+/* Build a fake kernel trapframe from current instruction pointer. */
+#define PMC_FAKE_TRAPFRAME(TF)						\
+	do {								\
+	__asm __volatile("mov %0, pc" : "=r" ((TF)->tf_pc));		\
+	} while (0)
+
 /*
  * Prototypes
  */

Modified: stable/9/sys/conf/files
==============================================================================
--- stable/9/sys/conf/files	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/conf/files	Tue May 29 14:50:21 2012	(r236238)
@@ -1121,6 +1121,7 @@ dev/hme/if_hme_sbus.c		optional hme sbus
 dev/hptiop/hptiop.c		optional hptiop scbus
 dev/hwpmc/hwpmc_logging.c	optional hwpmc
 dev/hwpmc/hwpmc_mod.c		optional hwpmc
+dev/hwpmc/hwpmc_soft.c		optional hwpmc
 dev/ichsmb/ichsmb.c		optional ichsmb
 dev/ichsmb/ichsmb_pci.c		optional ichsmb pci
 dev/ida/ida.c			optional ida

Modified: stable/9/sys/dev/hwpmc/hwpmc_amd.c
==============================================================================
--- stable/9/sys/dev/hwpmc/hwpmc_amd.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/dev/hwpmc/hwpmc_amd.c	Tue May 29 14:50:21 2012	(r236238)
@@ -687,7 +687,8 @@ amd_intr(int cpu, struct trapframe *tf)
 		wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v));
 
 		/* Restart the counter if logging succeeded. */
-		error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf));
+		error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
+		    TRAPF_USERMODE(tf));
 		if (error == 0)
 			wrmsr(evsel, config | AMD_PMC_ENABLE);
 	}
@@ -874,7 +875,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int c
 struct pmc_mdep *
 pmc_amd_initialize(void)
 {
-	int classindex, error, i, nclasses, ncpus;
+	int classindex, error, i, ncpus;
 	struct pmc_classdep *pcd;
 	enum pmc_cputype cputype;
 	struct pmc_mdep *pmc_mdep;
@@ -926,12 +927,9 @@ pmc_amd_initialize(void)
 	 * These processors have two classes of PMCs: the TSC and
 	 * programmable PMCs.
 	 */
-	nclasses = 2;
-	pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses * sizeof (struct pmc_classdep),
-	    M_PMC, M_WAITOK|M_ZERO);
+	pmc_mdep = pmc_mdep_alloc(2);
 
 	pmc_mdep->pmd_cputype = cputype;
-	pmc_mdep->pmd_nclass  = nclasses;
 
 	ncpus = pmc_cpu_max();
 

Modified: stable/9/sys/dev/hwpmc/hwpmc_arm.c
==============================================================================
--- stable/9/sys/dev/hwpmc/hwpmc_arm.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/dev/hwpmc/hwpmc_arm.c	Tue May 29 14:50:21 2012	(r236238)
@@ -38,38 +38,47 @@ __FBSDID("$FreeBSD$");
 struct pmc_mdep *
 pmc_md_initialize()
 {
+#ifdef CPU_XSCALE_IXP425
 	if (cpu_class == CPU_CLASS_XSCALE)
 		return pmc_xscale_initialize();
 	else
+#endif
 		return NULL;
 }
 
 void
 pmc_md_finalize(struct pmc_mdep *md)
 {
+#ifdef CPU_XSCALE_IXP425
 	if (cpu_class == CPU_CLASS_XSCALE)
 		pmc_xscale_finalize(md);
 	else
 		KASSERT(0, ("[arm,%d] Unknown CPU Class 0x%x", __LINE__,
 		    cpu_class));
+#endif
+}
+
+static int
+pmc_save_callchain(uintptr_t *cc, int maxsamples,
+    struct trapframe *tf)
+{
+
+	*cc = PMC_TRAPFRAME_TO_PC(tf);
+	return (1);
 }
 
 int
 pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples,
     struct trapframe *tf)
 {
-	(void) cc;
-	(void) maxsamples;
-	(void) tf;
-	return (0);
+
+	return pmc_save_callchain(cc, maxsamples, tf);
 }
 
 int
 pmc_save_user_callchain(uintptr_t *cc, int maxsamples,
     struct trapframe *tf)
 {
-	(void) cc;
-	(void) maxsamples;
-	(void) tf;
-	return (0);
+
+	return pmc_save_callchain(cc, maxsamples, tf);
 }

Modified: stable/9/sys/dev/hwpmc/hwpmc_core.c
==============================================================================
--- stable/9/sys/dev/hwpmc/hwpmc_core.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/dev/hwpmc/hwpmc_core.c	Tue May 29 14:50:21 2012	(r236238)
@@ -2239,7 +2239,7 @@ core_intr(int cpu, struct trapframe *tf)
 		if (pm->pm_state != PMC_STATE_RUNNING)
 			continue;
 
-		error = pmc_process_interrupt(cpu, pm, tf,
+		error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
 		    TRAPF_USERMODE(tf));
 
 		v = pm->pm_sc.pm_reloadcount;
@@ -2326,7 +2326,7 @@ core2_intr(int cpu, struct trapframe *tf
 		    !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
 			continue;
 
-		error = pmc_process_interrupt(cpu, pm, tf,
+		error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
 		    TRAPF_USERMODE(tf));
 		if (error)
 			intrenable &= ~flag;
@@ -2354,7 +2354,7 @@ core2_intr(int cpu, struct trapframe *tf
 		    !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
 			continue;
 
-		error = pmc_process_interrupt(cpu, pm, tf,
+		error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
 		    TRAPF_USERMODE(tf));
 		if (error)
 			intrenable &= ~flag;

Modified: stable/9/sys/dev/hwpmc/hwpmc_intel.c
==============================================================================
--- stable/9/sys/dev/hwpmc/hwpmc_intel.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/dev/hwpmc/hwpmc_intel.c	Tue May 29 14:50:21 2012	(r236238)
@@ -162,12 +162,10 @@ pmc_intel_initialize(void)
 		return (NULL);
 	}
 
-	pmc_mdep = malloc(sizeof(struct pmc_mdep) + nclasses *
-	    sizeof(struct pmc_classdep), M_PMC, M_WAITOK|M_ZERO);
+	/* Allocate base class and initialize machine dependent struct */
+	pmc_mdep = pmc_mdep_alloc(nclasses);
 
 	pmc_mdep->pmd_cputype 	 = cputype;
-	pmc_mdep->pmd_nclass	 = nclasses;
-
 	pmc_mdep->pmd_switch_in	 = intel_switch_in;
 	pmc_mdep->pmd_switch_out = intel_switch_out;
 
@@ -198,10 +196,6 @@ pmc_intel_initialize(void)
 
 	case PMC_CPU_INTEL_PIV:
 		error = pmc_p4_initialize(pmc_mdep, ncpus);
-
-		KASSERT(pmc_mdep->pmd_npmc == TSC_NPMCS + P4_NPMCS,
-		    ("[intel,%d] incorrect npmc count %d", __LINE__,
-		    pmc_mdep->pmd_npmc));
 		break;
 #endif
 
@@ -216,10 +210,6 @@ pmc_intel_initialize(void)
 	case PMC_CPU_INTEL_PIII:
 	case PMC_CPU_INTEL_PM:
 		error = pmc_p6_initialize(pmc_mdep, ncpus);
-
-		KASSERT(pmc_mdep->pmd_npmc == TSC_NPMCS + P6_NPMCS,
-		    ("[intel,%d] incorrect npmc count %d", __LINE__,
-		    pmc_mdep->pmd_npmc));
 		break;
 
 		/*
@@ -228,10 +218,6 @@ pmc_intel_initialize(void)
 
 	case PMC_CPU_INTEL_P5:
 		error = pmc_p5_initialize(pmc_mdep, ncpus);
-
-		KASSERT(pmc_mdep->pmd_npmc == TSC_NPMCS + PENTIUM_NPMCS,
-		    ("[intel,%d] incorrect npmc count %d", __LINE__,
-		    pmc_mdep->pmd_npmc));
 		break;
 #endif
 

Modified: stable/9/sys/dev/hwpmc/hwpmc_logging.c
==============================================================================
--- stable/9/sys/dev/hwpmc/hwpmc_logging.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/dev/hwpmc/hwpmc_logging.c	Tue May 29 14:50:21 2012	(r236238)
@@ -129,6 +129,7 @@ static struct mtx pmc_kthread_mtx;	/* sl
 
 /* Emit a string.  Caution: does NOT update _le, so needs to be last */
 #define	PMCLOG_EMITSTRING(S,L)	do { bcopy((S), _le, (L)); } while (0)
+#define	PMCLOG_EMITNULLSTRING(L) do { bzero(_le, (L)); } while (0)
 
 #define	PMCLOG_DESPATCH(PO)						\
 		pmclog_release((PO));					\
@@ -835,16 +836,33 @@ void
 pmclog_process_pmcallocate(struct pmc *pm)
 {
 	struct pmc_owner *po;
+	struct pmc_soft *ps;
 
 	po = pm->pm_owner;
 
 	PMCDBG(LOG,ALL,1, "pm=%p", pm);
 
-	PMCLOG_RESERVE(po, PMCALLOCATE, sizeof(struct pmclog_pmcallocate));
-	PMCLOG_EMIT32(pm->pm_id);
-	PMCLOG_EMIT32(pm->pm_event);
-	PMCLOG_EMIT32(pm->pm_flags);
-	PMCLOG_DESPATCH(po);
+	if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) {
+		PMCLOG_RESERVE(po, PMCALLOCATEDYN,
+		    sizeof(struct pmclog_pmcallocatedyn));
+		PMCLOG_EMIT32(pm->pm_id);
+		PMCLOG_EMIT32(pm->pm_event);
+		PMCLOG_EMIT32(pm->pm_flags);
+		ps = pmc_soft_ev_acquire(pm->pm_event);
+		if (ps != NULL)
+			PMCLOG_EMITSTRING(ps->ps_ev.pm_ev_name,PMC_NAME_MAX);
+		else
+			PMCLOG_EMITNULLSTRING(PMC_NAME_MAX);
+		pmc_soft_ev_release(ps);
+		PMCLOG_DESPATCH(po);
+	} else {
+		PMCLOG_RESERVE(po, PMCALLOCATE,
+		    sizeof(struct pmclog_pmcallocate));
+		PMCLOG_EMIT32(pm->pm_id);
+		PMCLOG_EMIT32(pm->pm_event);
+		PMCLOG_EMIT32(pm->pm_flags);
+		PMCLOG_DESPATCH(po);
+	}
 }
 
 void

Modified: stable/9/sys/dev/hwpmc/hwpmc_mod.c
==============================================================================
--- stable/9/sys/dev/hwpmc/hwpmc_mod.c	Tue May 29 14:41:16 2012	(r236237)
+++ stable/9/sys/dev/hwpmc/hwpmc_mod.c	Tue May 29 14:50:21 2012	(r236238)
@@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_map.h>
 #include <vm/vm_object.h>
 
+#include "hwpmc_soft.h"
+
 /*
  * Types
  */
@@ -182,7 +184,7 @@ static int	pmc_attach_one_process(struct
 static int	pmc_can_allocate_rowindex(struct proc *p, unsigned int ri,
     int cpu);
 static int	pmc_can_attach(struct pmc *pm, struct proc *p);
-static void	pmc_capture_user_callchain(int cpu, struct trapframe *tf);
+static void	pmc_capture_user_callchain(int cpu, int soft, struct trapframe *tf);
 static void	pmc_cleanup(void);
 static int	pmc_detach_process(struct proc *p, struct pmc *pm);
 static int	pmc_detach_one_process(struct proc *p, struct pmc *pm,
@@ -206,7 +208,7 @@ static void	pmc_process_csw_out(struct t
 static void	pmc_process_exit(void *arg, struct proc *p);
 static void	pmc_process_fork(void *arg, struct proc *p1,
     struct proc *p2, int n);
-static void	pmc_process_samples(int cpu);
+static void	pmc_process_samples(int cpu, int soft);
 static void	pmc_release_pmc_descriptor(struct pmc *pmc);
 static void	pmc_remove_owner(struct pmc_owner *po);
 static void	pmc_remove_process_descriptor(struct pmc_process *pp);
@@ -218,12 +220,16 @@ static int	pmc_stop(struct pmc *pm);
 static int	pmc_syscall_handler(struct thread *td, void *syscall_args);
 static void	pmc_unlink_target_process(struct pmc *pmc,
     struct pmc_process *pp);
+static int generic_switch_in(struct pmc_cpu *pc, struct pmc_process *pp);
+static int generic_switch_out(struct pmc_cpu *pc, struct pmc_process *pp);
+static struct pmc_mdep *pmc_generic_cpu_initialize(void);
+static void pmc_generic_cpu_finalize(struct pmc_mdep *md);
 
 /*
  * Kernel tunables and sysctl(8) interface.
  */
 
-SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters");
+SYSCTL_DECL(_kern_hwpmc);
 
 static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH;
 TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "callchaindepth", &pmc_callchaindepth);
@@ -1833,7 +1839,9 @@ const char *pmc_hooknames[] = {
 	"KLDUNLOAD",
 	"MMAP",
 	"MUNMAP",
-	"CALLCHAIN"
+	"CALLCHAIN-NMI",
+	"CALLCHAIN-SOFT",
+	"SOFTSAMPLING"
 };
 #endif
 
@@ -1992,7 +2000,8 @@ pmc_hook_handler(struct thread *td, int 
 		 * lose the interrupt sample.
 		 */
 		CPU_CLR_ATOMIC(PCPU_GET(cpuid), &pmc_cpumask);
-		pmc_process_samples(PCPU_GET(cpuid));
+		pmc_process_samples(PCPU_GET(cpuid), PMC_HR);
+		pmc_process_samples(PCPU_GET(cpuid), PMC_SR);
 		break;
 
 
@@ -2022,11 +2031,30 @@ pmc_hook_handler(struct thread *td, int 
 		 */
 		KASSERT(td == curthread, ("[pmc,%d] td != curthread",
 		    __LINE__));
-		pmc_capture_user_callchain(PCPU_GET(cpuid),
+
+		pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_HR,
 		    (struct trapframe *) arg);
 		td->td_pflags &= ~TDP_CALLCHAIN;
 		break;
 
+	case PMC_FN_USER_CALLCHAIN_SOFT:
+		/*
+		 * Record a call chain.
+		 */
+		KASSERT(td == curthread, ("[pmc,%d] td != curthread",
+		    __LINE__));
+		pmc_capture_user_callchain(PCPU_GET(cpuid), PMC_SR,
+		    (struct trapframe *) arg);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable-9 mailing list