[Midnightbsd-cvs] src: dev/hwpmc: Sync hwpmc

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Nov 30 14:34:04 EST 2008


Log Message:
-----------
Sync hwpmc

Modified Files:
--------------
    src/sys/dev/hwpmc:
        hwpmc_amd.c (r1.1.1.1 -> r1.2)
        hwpmc_logging.c (r1.2 -> r1.3)
        hwpmc_mod.c (r1.2 -> r1.3)
        hwpmc_piv.c (r1.1.1.1 -> r1.2)
        hwpmc_ppro.c (r1.1.1.1 -> r1.2)
        hwpmc_x86.c (r1.1.1.1 -> r1.2)

Removed Files:
-------------
    src/sys/dev/hwpmc:
        hwpmc_alpha.c

-------------- next part --------------
--- sys/dev/hwpmc/hwpmc_alpha.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * Copyright (c) 2005, Joseph Koshy
- * 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_alpha.c,v 1.1 2005/06/09 19:45:07 jkoshy Exp $");
-
-#include <sys/param.h>
-#include <sys/pmc.h>
-
-#include <machine/pmc_mdep.h>
-
-struct pmc_mdep *
-pmc_md_initialize()
-{
-	return NULL;
-}
Index: hwpmc_mod.c
===================================================================
RCS file: /home/cvs/src/sys/dev/hwpmc/hwpmc_mod.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/hwpmc/hwpmc_mod.c -L sys/dev/hwpmc/hwpmc_mod.c -u -r1.2 -r1.3
--- sys/dev/hwpmc/hwpmc_mod.c
+++ sys/dev/hwpmc/hwpmc_mod.c
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/hwpmc/hwpmc_mod.c,v 1.10.2.7 2006/06/16 22:11:55 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_mod.c,v 1.29 2007/06/05 00:00:50 jeff Exp $");
 
 #include <sys/param.h>
 #include <sys/eventhandler.h>
@@ -41,6 +41,7 @@
 #include <sys/pmc.h>
 #include <sys/pmckern.h>
 #include <sys/pmclog.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/queue.h>
 #include <sys/resourcevar.h>
@@ -53,6 +54,8 @@
 #include <sys/systm.h>
 #include <sys/vnode.h>
 
+#include <sys/linker.h>		/* needs to be after <sys/malloc.h> */
+
 #include <machine/atomic.h>
 #include <machine/md_var.h>
 
@@ -150,7 +153,7 @@
  * Prototypes
  */
 
-#if	DEBUG
+#ifdef	DEBUG
 static int	pmc_debugflags_sysctl_handler(SYSCTL_HANDLER_ARGS);
 static int	pmc_debugflags_parse(char *newstr, char *fence);
 #endif
@@ -202,7 +205,7 @@
 
 SYSCTL_NODE(_kern, OID_AUTO, hwpmc, CTLFLAG_RW, 0, "HWPMC parameters");
 
-#if	DEBUG
+#ifdef	DEBUG
 struct pmc_debugflags pmc_debugflags = PMC_DEBUG_DEFAULT_FLAGS;
 char	pmc_debugstr[PMC_DEBUG_STRSIZE];
 TUNABLE_STR(PMC_SYSCTL_NAME_PREFIX "debugflags", pmc_debugstr,
@@ -250,8 +253,6 @@
  * per-process measurements.  This feature is turned off by default.
  */
 
-SYSCTL_DECL(_security_bsd);
-
 static int pmc_unprivileged_syspmcs = 0;
 TUNABLE_INT("security.bsd.unprivileged_syspmcs", &pmc_unprivileged_syspmcs);
 SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_syspmcs, CTLFLAG_RW,
@@ -301,7 +302,7 @@
 DECLARE_MODULE(pmc, pmc_mod, SI_SUB_SMP, SI_ORDER_ANY);
 MODULE_VERSION(pmc, PMC_VERSION);
 
-#if	DEBUG
+#ifdef	DEBUG
 enum pmc_dbgparse_state {
 	PMCDS_WS,		/* in whitespace */
 	PMCDS_MAJOR,		/* seen a major keyword */
@@ -494,33 +495,32 @@
  *
  * The driver uses four locking strategies for its operation:
  *
- * - There is a 'global' SX lock "pmc_sx" that is used to protect
- *   the its 'meta-data'.
+ * - The global SX lock "pmc_sx" is used to protect internal
+ *   data structures.
  *
- *   Calls into the module (via syscall() or by the kernel) start with
- *   this lock being held in exclusive mode.  Depending on the requested
- *   operation, the lock may be downgraded to 'shared' mode to allow
- *   more concurrent readers into the module.
+ *   Calls into the module by syscall() start with this lock being
+ *   held in exclusive mode.  Depending on the requested operation,
+ *   the lock may be downgraded to 'shared' mode to allow more
+ *   concurrent readers into the module.  Calls into the module from
+ *   other parts of the kernel acquire the lock in shared mode.
  *
  *   This SX lock is held in exclusive mode for any operations that
  *   modify the linkages between the driver's internal data structures.
  *
  *   The 'pmc_hook' function pointer is also protected by this lock.
  *   It is only examined with the sx lock held in exclusive mode.  The
- *   kernel module is allowed to be unloaded only with the sx lock
- *   held in exclusive mode.  In normal syscall handling, after
- *   acquiring the pmc_sx lock we first check that 'pmc_hook' is
- *   non-null before proceeding.  This prevents races between the
- *   thread unloading the module and other threads seeking to use the
- *   module.
+ *   kernel module is allowed to be unloaded only with the sx lock held
+ *   in exclusive mode.  In normal syscall handling, after acquiring the
+ *   pmc_sx lock we first check that 'pmc_hook' is non-null before
+ *   proceeding.  This prevents races between the thread unloading the module
+ *   and other threads seeking to use the module.
  *
  * - Lookups of target process structures and owner process structures
  *   cannot use the global "pmc_sx" SX lock because these lookups need
  *   to happen during context switches and in other critical sections
  *   where sleeping is not allowed.  We protect these lookup tables
  *   with their own private spin-mutexes, "pmc_processhash_mtx" and
- *   "pmc_ownerhash_mtx".  These are 'leaf' mutexes, in that no other
- *   lock is acquired with these locks held.
+ *   "pmc_ownerhash_mtx".
  *
  * - Interrupt handlers work in a lock free manner.  At interrupt
  *   time, handlers look at the PMC pointer (phw->phw_pmc) configured
@@ -570,9 +570,17 @@
  *     We prevent further scheduling of the PMC by marking it as in
  *     state 'DELETED'.  If the runcount of the PMC is non-zero then
  *     this PMC is currently running on a CPU somewhere.  The thread
- *     doing the PMCRELEASE operation waits by repeatedly doing an
- *     tsleep() till the runcount comes to zero.
+ *     doing the PMCRELEASE operation waits by repeatedly doing a
+ *     pause() till the runcount comes to zero.
  *
+ * The contents of a PMC descriptor (struct pmc) are protected using
+ * a spin-mutex.  In order to save space, we use a mutex pool.
+ *
+ * In terms of lock types used by witness(4), we use:
+ * - Type "pmc-sx", used by the global SX lock.
+ * - Type "pmc-sleep", for sleep mutexes used by logger threads.
+ * - Type "pmc-per-proc", for protecting PMC owner descriptors.
+ * - Type "pmc-leaf", used for all other spin mutexes.
  */
 
 /*
@@ -583,10 +591,10 @@
 pmc_save_cpu_binding(struct pmc_binding *pb)
 {
 	PMCDBG(CPU,BND,2, "%s", "save-cpu");
-	mtx_lock_spin(&sched_lock);
+	thread_lock(curthread);
 	pb->pb_bound = sched_is_bound(curthread);
 	pb->pb_cpu   = curthread->td_oncpu;
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(curthread);
 	PMCDBG(CPU,BND,2, "save-cpu cpu=%d", pb->pb_cpu);
 }
 
@@ -599,12 +607,12 @@
 {
 	PMCDBG(CPU,BND,2, "restore-cpu curcpu=%d restore=%d",
 	    curthread->td_oncpu, pb->pb_cpu);
-	mtx_lock_spin(&sched_lock);
+	thread_lock(curthread);
 	if (pb->pb_bound)
 		sched_bind(curthread, pb->pb_cpu);
 	else
 		sched_unbind(curthread);
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(curthread);
 	PMCDBG(CPU,BND,2, "%s", "restore-cpu done");
 }
 
@@ -623,9 +631,9 @@
 	    "disabled CPU %d", __LINE__, cpu));
 
 	PMCDBG(CPU,SEL,2, "select-cpu cpu=%d", cpu);
-	mtx_lock_spin(&sched_lock);
+	thread_lock(curthread);
 	sched_bind(curthread, cpu);
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(curthread);
 
 	KASSERT(curthread->td_oncpu == cpu,
 	    ("[pmc,%d] CPU not bound [cpu=%d, curr=%d]", __LINE__,
@@ -637,7 +645,7 @@
 /*
  * Force a context switch.
  *
- * We do this by tsleep'ing for 1 tick -- invoking mi_switch() is not
+ * We do this by pause'ing for 1 tick -- invoking mi_switch() is not
  * guaranteed to force a context switch.
  */
 
@@ -645,7 +653,7 @@
 pmc_force_context_switch(void)
 {
 
-	(void) tsleep((void *) pmc_force_context_switch, 0, "pmcctx", 1);
+	pause("pmcctx", 1);
 }
 
 /*
@@ -750,7 +758,7 @@
 	PMCDBG(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p",
 	    pm, ri, pp);
 
-#if	DEBUG
+#ifdef	DEBUG
 	LIST_FOREACH(pt, &pm->pm_targets, pt_next)
 	    if (pt->pt_process == pp)
 		    KASSERT(0, ("[pmc,%d] pp %p already in pmc %p targets",
@@ -1404,19 +1412,138 @@
 }
 
 /*
+ * Log a KLD operation.
+ */
+
+static void
+pmc_process_kld_load(struct pmckern_map_in *pkm)
+{
+	struct pmc_owner *po;
+
+	sx_assert(&pmc_sx, SX_LOCKED);
+
+	/*
+	 * Notify owners of system sampling PMCs about KLD operations.
+	 */
+
+	LIST_FOREACH(po, &pmc_ss_owners, po_ssnext)
+	    if (po->po_flags & PMC_PO_OWNS_LOGFILE)
+	    	pmclog_process_map_in(po, (pid_t) -1, pkm->pm_address,
+		    (char *) pkm->pm_file);
+
+	/*
+	 * TODO: Notify owners of (all) process-sampling PMCs too.
+	 */
+
+	return;
+}
+
+static void
+pmc_process_kld_unload(struct pmckern_map_out *pkm)
+{
+	struct pmc_owner *po;
+
+	sx_assert(&pmc_sx, SX_LOCKED);
+
+	LIST_FOREACH(po, &pmc_ss_owners, po_ssnext)
+	    if (po->po_flags & PMC_PO_OWNS_LOGFILE)
+		pmclog_process_map_out(po, (pid_t) -1,
+		    pkm->pm_address, pkm->pm_address + pkm->pm_size);
+		    
+	/*
+	 * TODO: Notify owners of process-sampling PMCs.
+	 */
+}
+
+/*
+ * A mapping change for a process.
+ */
+
+static void
+pmc_process_mmap(struct thread *td, struct pmckern_map_in *pkm)
+{
+	int ri;
+	pid_t pid;
+	char *fullpath, *freepath;
+	const struct pmc *pm;
+	struct pmc_owner *po;
+	const struct pmc_process *pp;
+
+	freepath = fullpath = NULL;
+	pmc_getfilename((struct vnode *) pkm->pm_file, &fullpath, &freepath);
+
+	pid = td->td_proc->p_pid;
+
+	/* Inform owners of all system-wide sampling PMCs. */
+	LIST_FOREACH(po, &pmc_ss_owners, po_ssnext)
+	    if (po->po_flags & PMC_PO_OWNS_LOGFILE)
+		pmclog_process_map_in(po, pid, pkm->pm_address, fullpath);
+
+	if ((pp = pmc_find_process_descriptor(td->td_proc, 0)) == NULL)
+		goto done;
+
+	/*
+	 * Inform sampling PMC owners tracking this process.
+	 */
+	for (ri = 0; ri < md->pmd_npmc; ri++)
+		if ((pm = pp->pp_pmcs[ri].pp_pmc) != NULL &&
+		    PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+			pmclog_process_map_in(pm->pm_owner,
+			    pid, pkm->pm_address, fullpath);
+
+  done:
+	if (freepath)
+		FREE(freepath, M_TEMP);
+}
+
+
+/*
+ * Log an munmap request.
+ */
+
+static void
+pmc_process_munmap(struct thread *td, struct pmckern_map_out *pkm)
+{
+	int ri;
+	pid_t pid;
+	struct pmc_owner *po;
+	const struct pmc *pm;
+	const struct pmc_process *pp;
+
+	pid = td->td_proc->p_pid;
+
+	LIST_FOREACH(po, &pmc_ss_owners, po_ssnext)
+	    if (po->po_flags & PMC_PO_OWNS_LOGFILE)
+		pmclog_process_map_out(po, pid, pkm->pm_address,
+		    pkm->pm_address + pkm->pm_size);
+
+	if ((pp = pmc_find_process_descriptor(td->td_proc, 0)) == NULL)
+		return;
+
+	for (ri = 0; ri < md->pmd_npmc; ri++)
+		if ((pm = pp->pp_pmcs[ri].pp_pmc) != NULL &&
+		    PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+			pmclog_process_map_out(pm->pm_owner, pid,
+			    pkm->pm_address, pkm->pm_address + pkm->pm_size);
+}
+
+/*
  * The 'hook' invoked from the kernel proper
  */
 
 
-#if	DEBUG
+#ifdef	DEBUG
 const char *pmc_hooknames[] = {
+	/* these strings correspond to PMC_FN_* in <sys/pmckern.h> */
 	"",
-	"EXIT",
 	"EXEC",
-	"FORK",
 	"CSW-IN",
 	"CSW-OUT",
-	"SAMPLE"
+	"SAMPLE",
+	"KLDLOAD",
+	"KLDUNLOAD",
+	"MMAP",
+	"MUNMAP"
 };
 #endif
 
@@ -1578,8 +1705,29 @@
 		pmc_process_samples(PCPU_GET(cpuid));
 		break;
 
+
+	case PMC_FN_KLD_LOAD:
+		sx_assert(&pmc_sx, SX_LOCKED);
+		pmc_process_kld_load((struct pmckern_map_in *) arg);
+		break;
+
+	case PMC_FN_KLD_UNLOAD:
+		sx_assert(&pmc_sx, SX_LOCKED);
+		pmc_process_kld_unload((struct pmckern_map_out *) arg);
+		break;
+
+	case PMC_FN_MMAP:
+		sx_assert(&pmc_sx, SX_LOCKED);
+		pmc_process_mmap(td, (struct pmckern_map_in *) arg);
+		break;
+
+	case PMC_FN_MUNMAP:
+		sx_assert(&pmc_sx, SX_LOCKED);
+		pmc_process_munmap(td, (struct pmckern_map_out *) arg);
+		break;
+
 	default:
-#if DEBUG
+#ifdef	DEBUG
 		KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function));
 #endif
 		break;
@@ -1615,7 +1763,7 @@
 	LIST_INSERT_HEAD(poh, po, po_next); /* insert into hash table */
 
 	TAILQ_INIT(&po->po_logbuffers);
-	mtx_init(&po->po_mtx, "pmc-owner-mtx", "pmc", MTX_SPIN);
+	mtx_init(&po->po_mtx, "pmc-owner-mtx", "pmc-per-proc", MTX_SPIN);
 
 	PMCDBG(OWN,ALL,1, "allocate-owner proc=%p (%d, %s) pmc-owner=%p",
 	    p, p->p_pid, p->p_comm, po);
@@ -1761,7 +1909,7 @@
 {
 	(void) pm;
 
-#if	DEBUG
+#ifdef	DEBUG
 	KASSERT(pm->pm_state == PMC_STATE_DELETED ||
 	    pm->pm_state == PMC_STATE_FREE,
 	    ("[pmc,%d] destroying non-deleted PMC", __LINE__));
@@ -1778,7 +1926,7 @@
 static void
 pmc_wait_for_pmc_idle(struct pmc *pm)
 {
-#if	DEBUG
+#ifdef	DEBUG
 	volatile int maxloop;
 
 	maxloop = 100 * mp_ncpus;
@@ -1789,7 +1937,7 @@
 	 * comes down to zero.
 	 */
 	while (atomic_load_acq_32(&pm->pm_runcount) > 0) {
-#if	DEBUG
+#ifdef	DEBUG
 		maxloop--;
 		KASSERT(maxloop > 0,
 		    ("[pmc,%d] (ri%d, rc%d) waiting too long for "
@@ -2230,6 +2378,8 @@
 		po->po_sscount++;
 	}
 
+	/* TODO: dump system wide process mappings to the log? */
+
 	/*
 	 * Move to the CPU associated with this
 	 * PMC, and start the hardware.
@@ -2339,7 +2489,7 @@
 }
 
 
-#if	DEBUG
+#ifdef	DEBUG
 static const char *pmc_op_to_name[] = {
 #undef	__PMC_OP
 #define	__PMC_OP(N, D)	#N ,
@@ -2401,10 +2551,11 @@
 
 	case PMC_OP_CONFIGURELOG:
 	{
+		struct proc *p;
 		struct pmc *pm;
 		struct pmc_owner *po;
+		struct pmckern_map_in *km, *kmbase;
 		struct pmc_op_configurelog cl;
-		struct proc *p;
 
 		sx_assert(&pmc_sx, SX_XLOCKED);
 
@@ -2439,6 +2590,21 @@
 			}
 		} else
 			error = EINVAL;
+
+		if (error)
+			break;
+
+		/*
+		 * Log the current set of kernel modules.
+		 */
+		kmbase = linker_hwpmc_list_objects();
+		for (km = kmbase; km->pm_file != NULL; km++) {
+			PMCDBG(LOG,REG,1,"%s %p", (char *) km->pm_file,
+			    (void *) km->pm_address);
+			pmclog_process_map_in(po, (pid_t) -1, km->pm_address,
+			    km->pm_file);
+		}
+		FREE(kmbase, M_LINKER);
 	}
 	break;
 
@@ -2624,10 +2790,9 @@
 		KASSERT(td == curthread,
 		    ("[pmc,%d] td != curthread", __LINE__));
 
-		if (suser(td) || jailed(td->td_ucred)) {
-			error =  EPERM;
+		error = priv_check(td, PRIV_PMC_MANAGE);
+		if (error)
 			break;
-		}
 
 		if ((error = copyin(arg, &pma, sizeof(pma))) != 0)
 			break;
@@ -2760,11 +2925,16 @@
 		 */
 
 		if (PMC_IS_SYSTEM_MODE(mode)) {
-			if (jailed(curthread->td_ucred))
-				error = EPERM;
-			else if (suser(curthread) &&
-			    (pmc_unprivileged_syspmcs == 0))
+			if (jailed(curthread->td_ucred)) {
 				error = EPERM;
+				break;
+			}
+			if (!pmc_unprivileged_syspmcs) {
+				error = priv_check(curthread,
+				    PRIV_PMC_SYSTEM);
+				if (error)
+					break;
+			}
 		}
 
 		if (error)
@@ -3283,11 +3453,11 @@
 
 		pprw = (struct pmc_op_pmcrw *) arg;
 
-#if	DEBUG
+#ifdef	DEBUG
 		if (prw.pm_flags & PMC_F_NEWVALUE)
 			PMCDBG(PMC,OPS,2, "rw id=%d new %jx -> old %jx",
 			    ri, prw.pm_value, oldvalue);
-		else
+		else if (prw.pm_flags & PMC_F_OLDVALUE)
 			PMCDBG(PMC,OPS,2, "rw id=%d -> old %jx", ri, oldvalue);
 #endif
 
@@ -3922,7 +4092,7 @@
 	md = NULL;
 	error = 0;
 
-#if	DEBUG
+#ifdef	DEBUG
 	/* parse debug flags first */
 	if (TUNABLE_STR_FETCH(PMC_SYSCTL_NAME_PREFIX "debugflags",
 		pmc_debugstr, sizeof(pmc_debugstr)))
@@ -4021,13 +4191,15 @@
 
 	pmc_processhash = hashinit(pmc_hashsize, M_PMC,
 	    &pmc_processhashmask);
-	mtx_init(&pmc_processhash_mtx, "pmc-process-hash", "pmc", MTX_SPIN);
+	mtx_init(&pmc_processhash_mtx, "pmc-process-hash", "pmc-leaf",
+	    MTX_SPIN);
 
 	LIST_INIT(&pmc_ss_owners);
 	pmc_ss_count = 0;
 
 	/* allocate a pool of spin mutexes */
-	pmc_mtxpool = mtx_pool_create("pmc", pmc_mtxpool_size, MTX_SPIN);
+	pmc_mtxpool = mtx_pool_create("pmc-leaf", pmc_mtxpool_size,
+	    MTX_SPIN);
 
 	PMCDBG(MOD,INI,1, "pmc_ownerhash=%p, mask=0x%lx "
 	    "targethash=%p mask=0x%lx", pmc_ownerhash, pmc_ownerhashmask,
@@ -4072,7 +4244,7 @@
 	struct pmc_ownerhash *ph;
 	struct pmc_owner *po, *tmp;
 	struct pmc_binding pb;
-#if	DEBUG
+#ifdef	DEBUG
 	struct pmc_processhash *prh;
 #endif
 
@@ -4122,7 +4294,7 @@
 
 	mtx_destroy(&pmc_processhash_mtx);
 	if (pmc_processhash) {
-#if	DEBUG
+#ifdef	DEBUG
 		struct pmc_process *pp;
 
 		PMCDBG(MOD,INI,3, "%s", "destroy process hash");
Index: hwpmc_amd.c
===================================================================
RCS file: /home/cvs/src/sys/dev/hwpmc/hwpmc_amd.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/dev/hwpmc/hwpmc_amd.c -L sys/dev/hwpmc/hwpmc_amd.c -u -r1.1.1.1 -r1.2
--- sys/dev/hwpmc/hwpmc_amd.c
+++ sys/dev/hwpmc/hwpmc_amd.c
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_amd.c,v 1.9.2.1 2005/09/15 15:48:16 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_amd.c,v 1.13 2005/12/05 11:58:32 ru Exp $");
 
 /* Support for the AMD K7 and later processors */
 
@@ -43,7 +43,7 @@
 #include <machine/pmc_mdep.h>
 #include <machine/specialreg.h>
 
-#if	DEBUG
+#ifdef	DEBUG
 enum pmc_class	amd_pmc_class;
 #endif
 
@@ -291,7 +291,7 @@
 		return 0;
 	}
 
-#if	DEBUG
+#ifdef	DEBUG
 	KASSERT(pd->pm_descr.pd_class == amd_pmc_class,
 	    ("[amd,%d] unknown PMC class (%d)", __LINE__,
 		pd->pm_descr.pd_class));
@@ -338,7 +338,7 @@
 	if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
 		return 0;
 
-#if	DEBUG
+#ifdef	DEBUG
 	KASSERT(pd->pm_descr.pd_class == amd_pmc_class,
 	    ("[amd,%d] unknown PMC class (%d)", __LINE__,
 		pd->pm_descr.pd_class));
@@ -474,7 +474,7 @@
 		return 0;
 	}
 
-#if	DEBUG
+#ifdef	DEBUG
 	KASSERT(pd->pd_class == amd_pmc_class,
 	    ("[amd,%d] Unknown PMC class (%d)", __LINE__, pd->pd_class));
 #endif
@@ -536,7 +536,7 @@
 static int
 amd_release_pmc(int cpu, int ri, struct pmc *pmc)
 {
-#if	DEBUG
+#ifdef	DEBUG
 	const struct amd_descr *pd;
 #endif
 	struct pmc_hw *phw;
@@ -553,7 +553,7 @@
 	KASSERT(phw->phw_pmc == NULL,
 	    ("[amd,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
 
-#if 	DEBUG
+#ifdef	DEBUG
 	pd = &amd_pmcdesc[ri];
 	if (pd->pm_descr.pd_class == amd_pmc_class)
 		KASSERT(AMD_PMC_IS_STOPPED(pd->pm_evsel),
@@ -593,7 +593,7 @@
 	if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
 		return 0;	/* TSCs are always running */
 
-#if	DEBUG
+#ifdef	DEBUG
 	KASSERT(pd->pm_descr.pd_class == amd_pmc_class,
 	    ("[amd,%d] unknown PMC class (%d)", __LINE__,
 		pd->pm_descr.pd_class));
@@ -641,7 +641,7 @@
 	if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
 		return 0;
 
-#if	DEBUG
+#ifdef	DEBUG
 	KASSERT(pd->pm_descr.pd_class == amd_pmc_class,
 	    ("[amd,%d] unknown PMC class (%d)", __LINE__,
 		pd->pm_descr.pd_class));
@@ -890,7 +890,7 @@
 	if ((pcs = pmc_pcpu[cpu]) == NULL)
 		return 0;
 
-#if	DEBUG
+#ifdef	DEBUG
 	/* check the TSC */
 	KASSERT(pcs->pc_hwpmcs[0]->phw_pmc == NULL,
 	    ("[amd,%d] CPU%d,PMC0 still in use", __LINE__, cpu));
@@ -948,7 +948,7 @@
 		return NULL;
 	}
 
-#if	DEBUG
+#ifdef	DEBUG
 	amd_pmc_class = class;
 #endif
 
Index: hwpmc_ppro.c
===================================================================
RCS file: /home/cvs/src/sys/dev/hwpmc/hwpmc_ppro.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/dev/hwpmc/hwpmc_ppro.c -L sys/dev/hwpmc/hwpmc_ppro.c -u -r1.1.1.1 -r1.2
--- sys/dev/hwpmc/hwpmc_ppro.c
+++ sys/dev/hwpmc/hwpmc_ppro.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_ppro.c,v 1.8.2.1 2005/07/29 03:01:40 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_ppro.c,v 1.9 2005/07/14 15:09:14 jkoshy Exp $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
Index: hwpmc_x86.c
===================================================================
RCS file: /home/cvs/src/sys/dev/hwpmc/hwpmc_x86.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/dev/hwpmc/hwpmc_x86.c -L sys/dev/hwpmc/hwpmc_x86.c -u -r1.1.1.1 -r1.2
--- sys/dev/hwpmc/hwpmc_x86.c
+++ sys/dev/hwpmc/hwpmc_x86.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_x86.c,v 1.2.2.1 2005/08/26 19:49:32 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_x86.c,v 1.5.2.1 2007/12/03 10:50:58 jkoshy Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -91,7 +91,7 @@
 #if	defined(__i386__) || defined(__amd64__)
 	case 0xF00:		/* P4 */
 		model = ((cpu_id & 0xF0000) >> 12) | ((cpu_id & 0xF0) >> 4);
-		if (model >= 0 && model <= 4) /* known models */
+		if (model >= 0 && model <= 6) /* known models */
 			cputype = PMC_CPU_INTEL_PIV;
 		break;
 	}
Index: hwpmc_piv.c
===================================================================
RCS file: /home/cvs/src/sys/dev/hwpmc/hwpmc_piv.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/dev/hwpmc/hwpmc_piv.c -L sys/dev/hwpmc/hwpmc_piv.c -u -r1.1.1.1 -r1.2
--- sys/dev/hwpmc/hwpmc_piv.c
+++ sys/dev/hwpmc/hwpmc_piv.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_piv.c,v 1.9 2005/07/09 17:29:36 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_piv.c,v 1.14 2007/04/19 08:02:51 jkoshy Exp $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
@@ -99,27 +99,28 @@
  *
  * HTT Detection
  *
- * Not all HTT capable systems will have HTT enabled since users may
- * have turned HTT support off using the appropriate sysctls
- * (machdep.hlt_logical_cpus or machdep.logical_cpus_mask).  We detect
- * the presence of HTT by remembering if 'p4_init()' was called for a
- * logical CPU.  Note that hwpmc(4) cannot deal with a change in HTT
- * status once it is loaded.
+ * Not all HTT capable systems will have HTT enabled.  We detect the
+ * presence of HTT by detecting if 'p4_init()' was called for a secondary
+ * CPU in a HTT pair.
+ *
+ * Note that hwpmc(4) cannot currently deal with a change in HTT status once
+ * loaded.
  *
  * Handling HTT READ / WRITE / START / STOP
  *
- * PMC resources are shared across multiple logical CPUs.  In each
- * physical CPU's state we keep track of a 'runcount' which reflects
- * the number of PMC-using processes that have been scheduled on the
- * logical CPUs of this physical CPU.  Process-mode PMC operations
- * will actually 'start' or 'stop' hardware only if these are the
- * first or last processes respectively to use the hardware.  PMC
- * values written by a 'write' operation are saved and are transferred
- * to hardware at PMC 'start' time if the runcount is 0.  If the
- * runcount is greater than 0 at the time of a 'start' operation, we
- * keep track of the actual hardware value at the time of the 'start'
- * operation and use this to adjust the final readings at PMC 'stop'
- * or 'read' time.
+ * PMC resources are shared across the CPUs in an HTT pair.  We
+ * designate the lower numbered CPU in a HTT pair as the 'primary'
+ * CPU.  In each primary CPU's state we keep track of a 'runcount'
+ * which reflects the number of PMC-using processes that have been
+ * scheduled on its secondary CPU.  Process-mode PMC operations will
+ * actually 'start' or 'stop' hardware only if these are the first or
+ * last processes respectively to use the hardware.  PMC values
+ * written by a 'write' operation are saved and are transferred to
+ * hardware at PMC 'start' time if the runcount is 0.  If the runcount
+ * is greater than 0 at the time of a 'start' operation, we keep track
+ * of the actual hardware value at the time of the 'start' operation
+ * and use this to adjust the final readings at PMC 'stop' or 'read'
+ * time.
  *
  * Execution sequences:
  *
@@ -147,6 +148,11 @@
  * the two logical processors in the package.  We keep track of config
  * and de-config operations using the CFGFLAGS fields of the per-physical
  * cpu state.
+ *
+ * Handling TSCs
+ *
+ * TSCs are architectural state and each CPU in a HTT pair has its own
+ * TSC register.
  */
 
 #define	P4_PMCS()				\
@@ -418,8 +424,6 @@
 
 /* HTT support */
 #define	P4_NHTT					2 /* logical processors/chip */
-#define	P4_HTT_CPU_INDEX_0			0
-#define	P4_HTT_CPU_INDEX_1			1
 
 static int p4_system_has_htt;
 
@@ -487,7 +491,7 @@
 #define	P4_PCPU_GET_CFGFLAGS(PC,RI)	(P4_PCPU_GET_FLAGS(PC,RI,0xF0) >> 4)
 #define	P4_PCPU_SET_CFGFLAGS(PC,RI,C)	P4_PCPU_SET_FLAGS(PC,RI,0xF0,((C) <<4))
 
-#define	P4_CPU_TO_FLAG(C)		(pmc_cpu_is_logical(cpu) ? 0x2 : 0x1)
+#define	P4_CPU_TO_FLAG(C)		(P4_CPU_IS_HTT_SECONDARY(cpu) ? 0x2 : 0x1)
 
 #define	P4_PCPU_GET_INTRFLAG(PC,I)	((PC)->pc_intrflag & (1 << (I)))
 #define	P4_PCPU_SET_INTRFLAG(PC,I,V)	do {		\
@@ -541,14 +545,16 @@
 
 #define	P4_ESCR_UNMARK_ROW_THREAD(E) do {				 \
 	atomic_add_int(&p4_escrdisp[(E)], -1);				 \
-	KASSERT(p4_escrdisp[(E)] >= 0, ("[p4,%d] row disposition error",\
+	KASSERT(p4_escrdisp[(E)] >= 0, ("[p4,%d] row disposition error", \
 		    __LINE__));						 \
 } while (0)
 
 #define	P4_PMC_IS_STOPPED(cccr)	((rdmsr(cccr) & P4_CCCR_ENABLE) == 0)
 
-#define	P4_TO_PHYSICAL_CPU(cpu) (pmc_cpu_is_logical(cpu) ?		\
-    ((cpu) & ~1) : (cpu))
+#define	P4_CPU_IS_HTT_SECONDARY(cpu)					\
+	(p4_system_has_htt ? ((cpu) & 1) : 0)
+#define	P4_TO_HTT_PRIMARY(cpu) 						\
+	(p4_system_has_htt ? ((cpu) & ~1) : (cpu))
 
 #define	P4_CCCR_Tx_MASK	(~(P4_CCCR_OVF_PMI_T0|P4_CCCR_OVF_PMI_T1|	\
 			     P4_CCCR_ENABLE|P4_CCCR_OVF))
@@ -592,13 +598,22 @@
 	    pmc_cpu_is_logical(cpu) != 0);
 
 	/*
-	 * A 'logical' CPU shares its per-cpu state with its physical
-	 * CPU.  The physical CPU would have been initialized prior to
-	 * the initialization for this cpu.
+	 * The two CPUs in an HT pair share their per-cpu state.
+	 *
+	 * For HT capable CPUs, we assume that the two logical
+	 * processors in the HT pair get two consecutive CPU ids
+	 * starting with an even id #.
+	 *
+	 * The primary CPU (the even numbered CPU of the pair) would
+	 * have been initialized prior to the initialization for the
+	 * secondary.
 	 */
 
-	if (pmc_cpu_is_logical(cpu)) {
-		phycpu = P4_TO_PHYSICAL_CPU(cpu);
+	if (pmc_cpu_is_logical(cpu) && (cpu & 1)) {
+
+		p4_system_has_htt = 1;
+
+		phycpu = P4_TO_HTT_PRIMARY(cpu);
 		pcs = (struct p4_cpu *) pmc_pcpu[phycpu];
 		PMCDBG(MDP,INI,1, "p4-init cpu=%d phycpu=%d pcs=%p",
 		    cpu, phycpu, pcs);
@@ -608,8 +623,6 @@
 		if (pcs == NULL) /* decline to init */
 			return ENXIO;
 
-		p4_system_has_htt = 1;
-
 		MALLOC(plcs, struct p4_logicalcpu *,
 		    sizeof(struct p4_logicalcpu), M_PMC, M_WAITOK|M_ZERO);
 
@@ -649,7 +662,7 @@
 		*pescr++ = P4_INVALID_PMC_INDEX;
 	pmc_pcpu[cpu] = (struct pmc_cpu *) pcs;
 
-	mtx_init(&pcs->pc_mtx, "p4-pcpu", "pmc", MTX_SPIN);
+	mtx_init(&pcs->pc_mtx, "p4-pcpu", "pmc-leaf", MTX_SPIN);
 
 	return 0;
 }
@@ -661,6 +674,7 @@
 static int
 p4_cleanup(int cpu)
 {
+	int i;
 	struct p4_cpu *pcs;
 
 	PMCDBG(MDP,INI,0, "p4-cleanup cpu=%d", cpu);
@@ -668,11 +682,16 @@
 	if ((pcs = (struct p4_cpu *) pmc_pcpu[cpu]) == NULL)
 		return 0;
 
+	/* Turn off all PMCs on this CPU */
+	for (i = 0; i < P4_NPMCS - 1; i++)
+		wrmsr(P4_CCCR_MSR_FIRST + i,
+		    rdmsr(P4_CCCR_MSR_FIRST + i) & ~P4_CCCR_ENABLE);
+
 	/*
 	 * If the CPU is physical we need to teardown the
 	 * full MD state.
 	 */
-	if (!pmc_cpu_is_logical(cpu))
+	if (!P4_CPU_IS_HTT_SECONDARY(cpu))
 		mtx_destroy(&pcs->pc_mtx);
 
 	FREE(pcs, M_PMC);
@@ -744,7 +763,7 @@
 
 
 	if (ri == 0) {	/* TSC */
-#if	DEBUG
+#ifdef	DEBUG
 		pc  = (struct p4_cpu *) pmc_pcpu[cpu];
 		phw = pc->pc_hwpmcs[ri];
 		pm  = phw->phw_pmc;
@@ -762,7 +781,7 @@
 		return 0;
 	}
 
-	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 	phw = pc->pc_hwpmcs[ri];
 	pd  = &p4_pmcdesc[ri];
 	pm  = phw->phw_pmc;
@@ -827,7 +846,7 @@
 	 * timekeeping and other system functions.
 	 */
 	if (ri == 0) {
-#if	DEBUG
+#ifdef	DEBUG
 		pc  = (struct p4_cpu *) pmc_pcpu[cpu];
 		phw = pc->pc_hwpmcs[ri];
 		pm  = phw->phw_pmc;
@@ -841,7 +860,7 @@
 	}
 
 	/* Shared PMCs */
-	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 	phw = pc->pc_hwpmcs[ri];
 	pm  = phw->phw_pmc;
 	pd  = &p4_pmcdesc[ri];
@@ -908,7 +927,7 @@
 
 	/* Shared PMCs */
 
-	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 	phw = pc->pc_hwpmcs[ri];
 
 	KASSERT(pm == NULL || phw->phw_pmc == NULL ||
@@ -966,7 +985,7 @@
 	struct pmc_hw *phw;
 	int cfgflags;
 
-	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 	phw = pc->pc_hwpmcs[ri];
 
 	mtx_lock_spin(&pc->pc_mtx);
@@ -1091,7 +1110,7 @@
 	    p4_system_has_htt)
 		return EINVAL;
 
-	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 
 	found   = 0;
 
@@ -1242,7 +1261,7 @@
 	PMCDBG(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr);
 
 	if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
-		pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+		pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 		phw = pc->pc_hwpmcs[ri];
 
 		KASSERT(phw->phw_pmc == NULL,
@@ -1278,7 +1297,7 @@
 	KASSERT(ri >= 0 && ri < P4_NPMCS,
 	    ("[p4,%d] illegal row-index %d", __LINE__, ri));
 
-	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 	phw = pc->pc_hwpmcs[ri];
 	pm  = phw->phw_pmc;
 	pd  = &p4_pmcdesc[ri];
@@ -1307,7 +1326,7 @@
 	cccrvalue &= ~P4_CCCR_OVF_PMI_T0;
 	escrvalue &= ~(P4_ESCR_T0_OS|P4_ESCR_T0_USR);
 
-	if (pmc_cpu_is_logical(cpu)) { /* shift T0 bits to T1 position */
+	if (P4_CPU_IS_HTT_SECONDARY(cpu)) { /* shift T0 bits to T1 position */
 		cccrtbits <<= 1;
 		escrtbits >>= 2;
 	}
@@ -1435,7 +1454,7 @@
 	if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
 		return 0;
 
-	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc  = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 	phw = pc->pc_hwpmcs[ri];
 
 	KASSERT(phw != NULL,
@@ -1468,7 +1487,7 @@
 	/* bits to mask */
 	cccrtbits = P4_CCCR_OVF_PMI_T0;
 	escrtbits = P4_ESCR_T0_OS | P4_ESCR_T0_USR;
-	if (pmc_cpu_is_logical(cpu)) {
+	if (P4_CPU_IS_HTT_SECONDARY(cpu)) {
 		cccrtbits <<= 1;
 		escrtbits >>= 2;
 	}
@@ -1531,8 +1550,9 @@
 /*
  * Handle an interrupt.
  *
- * The hardware sets the CCCR_OVF whenever a counter overflow occurs, so the handler
- * examines all the 18 CCCR registers, processing the counters that have overflowed.
+ * The hardware sets the CCCR_OVF whenever a counter overflow occurs,
+ * so the handler examines all the 18 CCCR registers, processing the
+ * counters that have overflowed.
  *
  * On HTT machines, the CCCR register is shared and will interrupt
  * both logical processors if so configured.  Thus multiple logical
@@ -1553,13 +1573,13 @@
 
 	PMCDBG(MDP,INT, 1, "cpu=%d eip=%p um=%d", cpu, (void *) eip, usermode);
 
-	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)];
+	pc = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)];
 
-	ovf_mask = pmc_cpu_is_logical(cpu) ?
+	ovf_mask = P4_CPU_IS_HTT_SECONDARY(cpu) ?
 	    P4_CCCR_OVF_PMI_T1 : P4_CCCR_OVF_PMI_T0;
 	ovf_mask |= P4_CCCR_OVF;
 	if (p4_system_has_htt)
-		ovf_partner = pmc_cpu_is_logical(cpu) ? P4_CCCR_OVF_PMI_T0 :
+		ovf_partner = P4_CPU_IS_HTT_SECONDARY(cpu) ? P4_CCCR_OVF_PMI_T0 :
 		    P4_CCCR_OVF_PMI_T1;
 	else
 		ovf_partner = 0;
@@ -1701,7 +1721,7 @@
 
 	PMCDBG(MDP,OPS,1,"p4-describe cpu=%d ri=%d", cpu, ri);
 
-	if (pmc_cpu_is_logical(cpu))
+	if (P4_CPU_IS_HTT_SECONDARY(cpu))
 		return EINVAL;
 
 	phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
Index: hwpmc_logging.c
===================================================================
RCS file: /home/cvs/src/sys/dev/hwpmc/hwpmc_logging.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/hwpmc/hwpmc_logging.c -L sys/dev/hwpmc/hwpmc_logging.c -u -r1.2 -r1.3
--- sys/dev/hwpmc/hwpmc_logging.c
+++ sys/dev/hwpmc/hwpmc_logging.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2005-2006 Joseph Koshy
+ * Copyright (c) 2005 Joseph Koshy
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_logging.c,v 1.3.2.1 2006/03/22 10:25:36 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_logging.c,v 1.7 2007/04/19 08:02:51 jkoshy Exp $");
 
 #include <sys/param.h>
 #include <sys/file.h>
@@ -137,10 +137,11 @@
 
 CTASSERT(sizeof(struct pmclog_closelog) == 3*4);
 CTASSERT(sizeof(struct pmclog_dropnotify) == 3*4);
-CTASSERT(sizeof(struct pmclog_mappingchange) == PATH_MAX +
-    5*4 + 2*sizeof(uintfptr_t));
-CTASSERT(offsetof(struct pmclog_mappingchange,pl_pathname) ==
-    5*4 + 2*sizeof(uintfptr_t));
+CTASSERT(sizeof(struct pmclog_map_in) == PATH_MAX +
+    4*4 + sizeof(uintfptr_t));
+CTASSERT(offsetof(struct pmclog_map_in,pl_pathname) ==
+    4*4 + sizeof(uintfptr_t));
+CTASSERT(sizeof(struct pmclog_map_out) == 4*4 + 2*sizeof(uintfptr_t));
 CTASSERT(sizeof(struct pmclog_pcsample) == 6*4 + sizeof(uintfptr_t));
 CTASSERT(sizeof(struct pmclog_pmcallocate) == 6*4);
 CTASSERT(sizeof(struct pmclog_pmcattach) == 5*4 + PATH_MAX);
@@ -203,7 +204,7 @@
 
 	PMCDBG(LOG,GTB,1, "po=%p plb=%p", po, plb);
 
-#if	DEBUG
+#ifdef	DEBUG
 	if (plb)
 		KASSERT(plb->plb_ptr == plb->plb_base &&
 		    plb->plb_base < plb->plb_fence,
@@ -728,24 +729,36 @@
 }
 
 void
-pmclog_process_mappingchange(struct pmc_owner *po, pid_t pid, int type,
-    uintfptr_t start, uintfptr_t end, char *path)
+pmclog_process_map_in(struct pmc_owner *po, pid_t pid, uintfptr_t start,
+    const char *path)
 {
 	int pathlen, recordlen;
 
+	KASSERT(path != NULL, ("[pmclog,%d] map-in, null path", __LINE__));
+
 	pathlen = strlen(path) + 1;	/* #bytes for path name */
-	recordlen = offsetof(struct pmclog_mappingchange, pl_pathname) +
+	recordlen = offsetof(struct pmclog_map_in, pl_pathname) +
 	    pathlen;
 
-	PMCLOG_RESERVE(po,MAPPINGCHANGE,recordlen);
-	PMCLOG_EMIT32(type);
-	PMCLOG_EMITADDR(start);
-	PMCLOG_EMITADDR(end);
+	PMCLOG_RESERVE(po, MAP_IN, recordlen);
 	PMCLOG_EMIT32(pid);
+	PMCLOG_EMITADDR(start);
 	PMCLOG_EMITSTRING(path,pathlen);
 	PMCLOG_DESPATCH(po);
 }
 
+void
+pmclog_process_map_out(struct pmc_owner *po, pid_t pid, uintfptr_t start,
+    uintfptr_t end)
+{
+	KASSERT(start <= end, ("[pmclog,%d] start > end", __LINE__));
+
+	PMCLOG_RESERVE(po, MAP_OUT, sizeof(struct pmclog_map_out));
+	PMCLOG_EMIT32(pid);
+	PMCLOG_EMITADDR(start);
+	PMCLOG_EMITADDR(end);
+	PMCLOG_DESPATCH(po);
+}
 
 void
 pmclog_process_pcsample(struct pmc *pm, struct pmc_sample *ps)
@@ -960,8 +973,9 @@
 		PMCLOG_INIT_BUFFER_DESCRIPTOR(plb);
 		TAILQ_INSERT_HEAD(&pmc_bufferlist, plb, plb_next);
 	}
-	mtx_init(&pmc_bufferlist_mtx, "pmc-buffer-list", "pmc", MTX_SPIN);
-	mtx_init(&pmc_kthread_mtx, "pmc-kthread", "pmc", MTX_DEF);
+	mtx_init(&pmc_bufferlist_mtx, "pmc-buffer-list", "pmc-leaf",
+	    MTX_SPIN);
+	mtx_init(&pmc_kthread_mtx, "pmc-kthread", "pmc-sleep", MTX_DEF);
 }
 
 /*


More information about the Midnightbsd-cvs mailing list