PERFORCE change 76346 for review

Sam Leffler sam at FreeBSD.org
Sun May 1 15:12:58 PDT 2005


http://perforce.freebsd.org/chv.cgi?CH=76346

Change 76346 by sam at sam_ebb on 2005/05/01 22:12:29

	IFC @ 76340

Affected files ...

.. //depot/projects/wifi/sys/conf/options.pc98#5 integrate
.. //depot/projects/wifi/sys/dev/ata/ata-chipset.c#11 integrate
.. //depot/projects/wifi/sys/dev/ata/ata-dma.c#6 integrate
.. //depot/projects/wifi/sys/dev/ata/ata-lowlevel.c#11 integrate
.. //depot/projects/wifi/sys/dev/ata/ata-pci.c#7 integrate
.. //depot/projects/wifi/sys/dev/ata/ata-raid.h#6 integrate
.. //depot/projects/wifi/sys/dev/hwpmc/hwpmc_amd.c#2 integrate
.. //depot/projects/wifi/sys/dev/hwpmc/hwpmc_intel.c#2 integrate
.. //depot/projects/wifi/sys/dev/hwpmc/hwpmc_mod.c#2 integrate
.. //depot/projects/wifi/sys/dev/hwpmc/hwpmc_piv.c#2 integrate
.. //depot/projects/wifi/sys/dev/hwpmc/hwpmc_ppro.c#2 integrate
.. //depot/projects/wifi/sys/fs/devfs/devfs_vnops.c#21 integrate
.. //depot/projects/wifi/sys/geom/geom_pc98_enc.c#2 integrate
.. //depot/projects/wifi/sys/i386/include/pmc_mdep.h#4 integrate
.. //depot/projects/wifi/sys/kern/kern_exec.c#12 integrate
.. //depot/projects/wifi/sys/kern/subr_taskqueue.c#3 integrate
.. //depot/projects/wifi/sys/kern/vfs_cluster.c#10 integrate
.. //depot/projects/wifi/sys/kern/vfs_default.c#17 integrate
.. //depot/projects/wifi/sys/kern/vfs_mount.c#20 integrate
.. //depot/projects/wifi/sys/kern/vfs_subr.c#24 integrate
.. //depot/projects/wifi/sys/netinet/tcp_usrreq.c#11 integrate
.. //depot/projects/wifi/sys/pc98/conf/NOTES#10 integrate
.. //depot/projects/wifi/sys/powerpc/powermac/ata_kauai.c#8 integrate
.. //depot/projects/wifi/sys/powerpc/powermac/ata_macio.c#8 integrate
.. //depot/projects/wifi/sys/sys/diskpc98.h#3 integrate
.. //depot/projects/wifi/sys/sys/pmc.h#4 integrate
.. //depot/projects/wifi/sys/sys/taskqueue.h#3 integrate

Differences ...

==== //depot/projects/wifi/sys/conf/options.pc98#5 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/options.pc98,v 1.183 2005/04/15 14:24:49 nyan Exp $
+# $FreeBSD: src/sys/conf/options.pc98,v 1.184 2005/05/01 03:59:25 nyan Exp $
 # Options specific to the pc98 platform kernels
 
 AUTO_EOI_1		opt_auto_eoi.h
@@ -102,3 +102,6 @@
 DEV_APIC		opt_apic.h
 DEV_MECIA		opt_mecia.h
 DEV_NPX			opt_npx.h
+
+# Debugging
+KDB_STOP_NMI		opt_global.h

==== //depot/projects/wifi/sys/dev/ata/ata-chipset.c#11 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-chipset.c,v 1.114 2005/04/30 16:22:06 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-chipset.c,v 1.115 2005/05/01 12:24:45 sos Exp $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -2004,7 +2004,7 @@
 static int
 ata_promise_mio_dmastart(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
 
     ch->flags |= ATA_DMA_ACTIVE;
     return 0;
@@ -2013,7 +2013,7 @@
 static int
 ata_promise_mio_dmastop(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
 
     ch->flags &= ~ATA_DMA_ACTIVE;
     /* get status XXX SOS */
@@ -2428,8 +2428,8 @@
 static int
 ata_promise_new_dmastart(device_t dev)
 {
-    struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
 
     if (ch->flags & ATA_48BIT_ACTIVE) {
 	ATA_OUTB(ctlr->r_res1, 0x11,
@@ -2451,8 +2451,8 @@
 static int
 ata_promise_new_dmastop(device_t dev)
 {
-    struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
     int error;
 
     if (ch->flags & ATA_48BIT_ACTIVE) {

==== //depot/projects/wifi/sys/dev/ata/ata-dma.c#6 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-dma.c,v 1.135 2005/04/30 16:22:07 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-dma.c,v 1.136 2005/05/01 12:24:45 sos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -218,7 +218,7 @@
 static int
 ata_dmaload(device_t dev, caddr_t data, int32_t count, int dir)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
     struct ata_dmasetprd_args cba;
 
     if (ch->dma->flags & ATA_DMA_LOADED) {
@@ -259,7 +259,7 @@
 int
 ata_dmaunload(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
     bus_dmamap_sync(ch->dma->sg_tag, ch->dma->sg_map, BUS_DMASYNC_POSTWRITE);
 
     bus_dmamap_sync(ch->dma->data_tag, ch->dma->data_map,

==== //depot/projects/wifi/sys/dev/ata/ata-lowlevel.c#11 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-lowlevel.c,v 1.64 2005/04/30 16:22:07 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-lowlevel.c,v 1.65 2005/05/01 12:24:45 sos Exp $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -129,7 +129,7 @@
     /* ATA DMA data transfer commands */
     case ATA_R_DMA:
 	/* check sanity, setup SG list and DMA engine */
-	if (ch->dma->load(request->dev, request->data, request->bytecount,
+	if (ch->dma->load(ch->dev, request->data, request->bytecount,
 			  request->flags & ATA_R_READ)) {
 	    device_printf(request->dev, "setting up DMA failed\n");
 	    request->result = EIO;
@@ -147,7 +147,7 @@
 	}
 
 	/* start DMA engine */
-	if (ch->dma->start(request->dev)) {
+	if (ch->dma->start(ch->dev)) {
 	    device_printf(request->dev, "error starting DMA\n");
 	    request->result = EIO;
 	    goto begin_finished;
@@ -218,7 +218,7 @@
 	}
 
 	/* check sanity, setup SG list and DMA engine */
-	if (ch->dma->load(request->dev, request->data, request->bytecount,
+	if (ch->dma->load(ch->dev, request->data, request->bytecount,
 			  request->flags & ATA_R_READ)) {
 	    device_printf(request->dev, "setting up DMA failed\n");
 	    request->result = EIO;
@@ -261,7 +261,7 @@
 			   ATA_PROTO_ATAPI_12 ? 6 : 8);
 
 	/* start DMA engine */
-	if (ch->dma->start(request->dev)) {
+	if (ch->dma->start(ch->dev)) {
 	    request->result = EIO;
 	    goto begin_finished;
 	}
@@ -272,7 +272,7 @@
 
 begin_finished:
     if (ch->dma && ch->dma->flags & ATA_DMA_LOADED)
-	ch->dma->unload(request->dev);
+	ch->dma->unload(ch->dev);
     return ATA_OP_FINISHED;
 
 begin_continue:
@@ -390,7 +390,7 @@
 
 	/* stop DMA engine and get status */
 	if (ch->dma->stop)
-	    request->dmastat = ch->dma->stop(request->dev);
+	    request->dmastat = ch->dma->stop(ch->dev);
 
 	/* did we get error or data */
 	if (request->status & ATA_S_ERROR)
@@ -401,7 +401,7 @@
 	    request->donecount = request->bytecount;
 
 	/* release SG list etc */
-	ch->dma->unload(request->dev);
+	ch->dma->unload(ch->dev);
 
 	/* done with HW */
 	goto end_finished;
@@ -502,7 +502,7 @@
 
 	/* stop the engine and get engine status */
 	if (ch->dma->stop)
-	    request->dmastat = ch->dma->stop(request->dev);
+	    request->dmastat = ch->dma->stop(ch->dev);
 
 	/* did we get error or data */
 	if (request->status & (ATA_S_ERROR | ATA_S_DWF))
@@ -513,7 +513,7 @@
 	    request->donecount = request->bytecount;
  
 	/* release SG list etc */
-	ch->dma->unload(request->dev);
+	ch->dma->unload(ch->dev);
 
 	/* done with HW */
 	goto end_finished;

==== //depot/projects/wifi/sys/dev/ata/ata-pci.c#7 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-pci.c,v 1.101 2005/04/30 16:22:07 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-pci.c,v 1.102 2005/05/01 12:24:45 sos Exp $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -419,7 +419,7 @@
 static int
 ata_pci_dmastart(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
 
     ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) | 
 		 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
@@ -435,7 +435,7 @@
 static int
 ata_pci_dmastop(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
     int error;
 
     ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, 

==== //depot/projects/wifi/sys/dev/ata/ata-raid.h#6 (text+ko) ====

@@ -25,7 +25,7 @@
  * (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: src/sys/dev/ata/ata-raid.h,v 1.32 2005/04/30 16:22:07 sos Exp $
+ * $FreeBSD: src/sys/dev/ata/ata-raid.h,v 1.33 2005/05/01 08:45:12 sos Exp $
  */
 
 /* misc defines */
@@ -522,7 +522,7 @@
 
 /* Promise FastTrak Metadata */
 #define PR_LBA(dev) \
-	(((struct ad_softc *)device_get_ivars(dev))->total_secs - 63)
+	(((((struct ad_softc *)device_get_ivars(dev))->total_secs / (((struct ad_softc *)device_get_ivars(dev))->heads * ((struct ad_softc *)device_get_ivars(dev))->sectors)) * ((struct ad_softc *)device_get_ivars(dev))->heads * ((struct ad_softc *)device_get_ivars(dev))->sectors) - ((struct ad_softc *)device_get_ivars(dev))->sectors)
 
 struct promise_raid_conf {
     char                promise_id[24];

==== //depot/projects/wifi/sys/dev/hwpmc/hwpmc_amd.c#2 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_amd.c,v 1.4 2005/04/28 08:13:18 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_amd.c,v 1.5 2005/05/01 14:11:48 jkoshy Exp $");
 
 /* Support for the AMD K7 and later processors */
 
@@ -360,7 +360,7 @@
 	    ("[amd,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__,
 		cpu, ri));
 
-	mode = pm->pm_mode;
+	mode = PMC_TO_MODE(pm);
 
 	PMCDBG(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class);
 
@@ -413,7 +413,7 @@
 	    ("[amd,%d] PMC not owned (cpu%d,pmc%d)", __LINE__,
 		cpu, ri));
 
-	mode = pm->pm_mode;
+	mode = PMC_TO_MODE(pm);
 
 	if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
 		return 0;
@@ -461,6 +461,18 @@
 }
 
 /*
+ * Retrieve a configured PMC pointer from hardware state.
+ */
+
+static int
+amd_get_config(int cpu, int ri, struct pmc **ppm)
+{
+	*ppm = pmc_pcpu[cpu]->pc_hwpmcs[ri]->phw_pmc;
+
+	return 0;
+}
+
+/*
  * Machine dependent actions taken during the context switch in of a
  * thread.
  */
@@ -471,10 +483,10 @@
 	(void) pc;
 
 	PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
-	    (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
+	    (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0);
 
 	/* enable the RDPMC instruction if needed */
-	if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS)
+	if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS)
 		load_cr4(rcr4() | CR4_PCE);
 
 	return 0;
@@ -492,7 +504,7 @@
 	(void) pp;		/* can be NULL */
 
 	PMCDBG(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ?
-	    (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) == 1 : 0);
+	    (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) == 1 : 0);
 
 	/* always turn off the RDPMC instruction */
 	load_cr4(rcr4() & ~CR4_PCE);
@@ -523,7 +535,7 @@
 	pd = &amd_pmcdesc[ri].pm_descr;
 
 	/* check class match */
-	if (pd->pd_class != pm->pm_class)
+	if (pd->pd_class != a->pm_class)
 		return EINVAL;
 
 	caps = pm->pm_caps;
@@ -765,7 +777,7 @@
 			continue;
 		}
 
-		mode = pm->pm_mode;
+		mode = PMC_TO_MODE(pm);
 		if (PMC_IS_SAMPLING_MODE(mode) &&
 		    AMD_PMC_HAS_OVERFLOWED(perfctr)) {
 			atomic_add_int(&pmc_stats.pm_intr_processed, 1);
@@ -803,8 +815,6 @@
 		return error;
 
 	pi->pm_class = pd->pm_descr.pd_class;
-	pi->pm_caps  = pd->pm_descr.pd_caps;
-	pi->pm_width = pd->pm_descr.pd_width;
 
 	if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
 		pi->pm_enabled = TRUE;
@@ -982,8 +992,17 @@
 
 	/* this processor has two classes of usable PMCs */
 	pmc_mdep->pmd_nclass       = 2;
-	pmc_mdep->pmd_classes[0]   = PMC_CLASS_TSC;
-	pmc_mdep->pmd_classes[1]   = AMD_PMC_CLASS;
+
+	/* TSC */
+	pmc_mdep->pmd_classes[0].pm_class   = PMC_CLASS_TSC;
+	pmc_mdep->pmd_classes[0].pm_caps    = PMC_CAP_READ;
+	pmc_mdep->pmd_classes[0].pm_width   = 64;
+
+	/* AMD K7/K8 PMCs */
+	pmc_mdep->pmd_classes[1].pm_class   = AMD_PMC_CLASS;
+	pmc_mdep->pmd_classes[1].pm_caps    = AMD_PMC_CAPS;
+	pmc_mdep->pmd_classes[1].pm_width   = 48;
+
 	pmc_mdep->pmd_nclasspmcs[0] = 1;
 	pmc_mdep->pmd_nclasspmcs[1] = (AMD_NPMCS-1);
 
@@ -994,6 +1013,7 @@
 	pmc_mdep->pmd_read_pmc 	   = amd_read_pmc;
 	pmc_mdep->pmd_write_pmc    = amd_write_pmc;
 	pmc_mdep->pmd_config_pmc   = amd_config_pmc;
+	pmc_mdep->pmd_get_config   = amd_get_config;
 	pmc_mdep->pmd_allocate_pmc = amd_allocate_pmc;
 	pmc_mdep->pmd_release_pmc  = amd_release_pmc;
 	pmc_mdep->pmd_start_pmc    = amd_start_pmc;

==== //depot/projects/wifi/sys/dev/hwpmc/hwpmc_intel.c#2 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_intel.c,v 1.3 2005/04/27 05:51:13 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_intel.c,v 1.4 2005/05/01 14:11:48 jkoshy Exp $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
@@ -92,7 +92,9 @@
 
 	pmc_mdep->pmd_cputype 	    = cputype;
 	pmc_mdep->pmd_nclass	    = 2;
-	pmc_mdep->pmd_classes[0]    = PMC_CLASS_TSC;
+	pmc_mdep->pmd_classes[0].pm_class    = PMC_CLASS_TSC;
+	pmc_mdep->pmd_classes[0].pm_caps     = PMC_CAP_READ;
+	pmc_mdep->pmd_classes[0].pm_width    = 64;
 	pmc_mdep->pmd_nclasspmcs[0] = 1;
 
 	error = 0;

==== //depot/projects/wifi/sys/dev/hwpmc/hwpmc_mod.c#2 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_mod.c,v 1.6 2005/04/28 08:13:18 jkoshy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/hwpmc/hwpmc_mod.c,v 1.7 2005/05/01 14:11:48 jkoshy Exp $");
 
 #include <sys/param.h>
 #include <sys/eventhandler.h>
@@ -151,12 +151,14 @@
 static struct pmc *pmc_find_pmc_descriptor_in_process(struct pmc_owner *po,
     pmc_id_t pmc);
 static void	pmc_release_pmc_descriptor(struct pmc *pmc);
-static int	pmc_can_allocate_rowindex(struct proc *p, unsigned int ri);
+static int	pmc_can_allocate_rowindex(struct proc *p, unsigned int ri,
+    int cpu);
 static struct pmc_process *pmc_find_process_descriptor(struct proc *p,
     uint32_t mode);
 static void	pmc_remove_process_descriptor(struct pmc_process *pp);
 static struct pmc_owner *pmc_find_owner_descriptor(struct proc *p);
 static int	pmc_find_pmc(pmc_id_t pmcid, struct pmc **pm);
+static void	pmc_force_context_switch(void);
 static void	pmc_remove_owner(struct pmc_owner *po);
 static void	pmc_maybe_remove_owner(struct pmc_owner *po);
 static void	pmc_unlink_target_process(struct pmc *pmc,
@@ -364,6 +366,7 @@
 		CMP_SET_FLAG_MIN("cfg", CFG);
 		CMP_SET_FLAG_MIN("sta", STA);
 		CMP_SET_FLAG_MIN("sto", STO);
+		CMP_SET_FLAG_MIN("int", INT);
 		CMP_SET_FLAG_MIN("bnd", BND);
 		CMP_SET_FLAG_MIN("sel", SEL);
 		else	/* unrecognized keyword */
@@ -573,6 +576,27 @@
 }
 
 /*
+ * Force a context switch.
+ *
+ * We do this by tsleep'ing for 1 tick -- invoking mi_switch() is not
+ * guaranteed to force a context switch.
+ */
+
+static void
+pmc_force_context_switch(void)
+{
+	u_char	curpri;
+
+	mtx_lock_spin(&sched_lock);
+	curpri = curthread->td_priority;
+	mtx_unlock_spin(&sched_lock);
+
+	(void) tsleep((void *) pmc_force_context_switch, curpri,
+	    "pmcctx", 1);
+
+}
+
+/*
  * Update the per-pmc histogram
  */
 
@@ -671,7 +695,7 @@
 	 * XXX rework needed.
 	 */
 
-	if (po->po_flags & PMC_FLAG_OWNS_LOGFILE)
+	if (po->po_flags & PMC_PO_OWNS_LOGFILE)
 		pmc_configure_log(po, -1);
 
 }
@@ -693,7 +717,7 @@
 	 */
 
 	if (LIST_EMPTY(&po->po_pmcs) &&
-	    ((po->po_flags & PMC_FLAG_OWNS_LOGFILE) == 0)) {
+	    ((po->po_flags & PMC_PO_OWNS_LOGFILE) == 0)) {
 		pmc_remove_owner(po);
 		FREE(po, M_PMC);
 	}
@@ -718,7 +742,7 @@
 	    ("[pmc,%d] Illegal reference count %d for process record %p",
 		__LINE__, pp->pp_refcnt, (void *) pp));
 
-	ri = pm->pm_rowindex;
+	ri = PMC_TO_ROWINDEX(pm);
 
 	PMCDBG(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p",
 	    pm, ri, pp);
@@ -740,12 +764,10 @@
 	atomic_store_rel_ptr(&pp->pp_pmcs[ri].pp_pmc, pm);
 
 	if (pm->pm_owner->po_owner == pp->pp_proc)
-		pp->pp_flags |= PMC_FLAG_ENABLE_MSR_ACCESS;
+		pm->pm_flags |= PMC_F_ATTACHED_TO_OWNER;
 
 	pp->pp_refcnt++;
 
-	PMCDBG(PRC,TLK,2, "enable-msr %d",
-	    (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
 }
 
 /*
@@ -767,7 +789,7 @@
 	    ("[pmc,%d] Illegal ref count %d on process record %p",
 		__LINE__, pp->pp_refcnt, (void *) pp));
 
-	ri = pm->pm_rowindex;
+	ri = PMC_TO_ROWINDEX(pm);
 
 	PMCDBG(PRC,TUL,1, "unlink-target pmc=%p ri=%d pmc-process=%p",
 	    pm, ri, pp);
@@ -779,8 +801,11 @@
 	pp->pp_pmcs[ri].pp_pmc = NULL;
 	pp->pp_pmcs[ri].pp_pmcval = (pmc_value_t) 0;
 
-	if (pm->pm_owner->po_owner == pp->pp_proc)
-		pp->pp_flags &= ~PMC_FLAG_ENABLE_MSR_ACCESS;
+	/* Remove owner-specific flags */
+	if (pm->pm_owner->po_owner == pp->pp_proc) {
+		pp->pp_flags &= ~PMC_PP_ENABLE_MSR_ACCESS;
+		pm->pm_flags &= ~PMC_F_ATTACHED_TO_OWNER;
+	}
 
 	pp->pp_refcnt--;
 
@@ -792,9 +817,6 @@
 	KASSERT(ptgt != NULL, ("[pmc,%d] process %p (pp: %p) not found "
 		    "in pmc %p", __LINE__, pp->pp_proc, pp, pm));
 
-	PMCDBG(PRC,TUL,4, "unlink ptgt=%p, enable-msr=%d", ptgt,
-	    (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
-
 	LIST_REMOVE(ptgt, pt_next);
 	FREE(ptgt, M_PMC);
 }
@@ -897,7 +919,7 @@
 	sx_assert(&pmc_sx, SX_XLOCKED);
 
 	PMCDBG(PRC,ATT,2, "attach-one pm=%p ri=%d proc=%p (%d, %s)", pm,
-	    pm->pm_rowindex, p, p->p_pid, p->p_comm);
+	    PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
 
 	/*
 	 * Locate the process descriptor corresponding to process 'p',
@@ -910,7 +932,7 @@
 	 * process descriptor and PMC.
 	 */
 
-	ri = pm->pm_rowindex;
+	ri = PMC_TO_ROWINDEX(pm);
 
 	if ((pp = pmc_find_process_descriptor(p, PMC_FLAG_ALLOCATE)) == NULL)
 		return ENOMEM;
@@ -944,7 +966,16 @@
 	sx_assert(&pmc_sx, SX_XLOCKED);
 
 	PMCDBG(PRC,ATT,1, "attach pm=%p ri=%d proc=%p (%d, %s)", pm,
-	    pm->pm_rowindex, p, p->p_pid, p->p_comm);
+	    PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
+
+
+	/*
+	 * If this PMC successfully allowed a GETMSR operation
+	 * in the past, disallow further ATTACHes.
+	 */
+
+	if ((pm->pm_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0)
+		return EPERM;
 
 	if ((pm->pm_flags & PMC_F_DESCENDANTS) == 0)
 		return pmc_attach_one_process(p, pm);
@@ -999,11 +1030,11 @@
 	KASSERT(pm != NULL,
 	    ("[pmc,%d] null pm pointer", __LINE__));
 
+	ri = PMC_TO_ROWINDEX(pm);
+
 	PMCDBG(PRC,ATT,2, "detach-one pm=%p ri=%d proc=%p (%d, %s) flags=0x%x",
-	    pm, pm->pm_rowindex, p, p->p_pid, p->p_comm, flags);
+	    pm, ri, p, p->p_pid, p->p_comm, flags);
 
-	ri = pm->pm_rowindex;
-
 	if ((pp = pmc_find_process_descriptor(p, 0)) == NULL)
 		return ESRCH;
 
@@ -1049,7 +1080,7 @@
 	sx_assert(&pmc_sx, SX_XLOCKED);
 
 	PMCDBG(PRC,ATT,1, "detach pm=%p ri=%d proc=%p (%d, %s)", pm,
-	    pm->pm_rowindex, p, p->p_pid, p->p_comm);
+	    PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
 
 	if ((pm->pm_flags & PMC_F_DESCENDANTS) == 0)
 		return pmc_detach_one_process(p, pm, PMC_FLAG_REMOVE);
@@ -1131,7 +1162,6 @@
 		int cpu;
 		unsigned int ri;
 		struct pmc *pm;
-		struct pmc_hw *phw;
 		struct pmc_process *pp;
 		struct pmc_owner *po;
 		struct proc *p;
@@ -1183,22 +1213,22 @@
 				 * state similar to the CSW_OUT code.
 				 */
 
-				phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
-				pm  = phw->phw_pmc;
+				pm = NULL;
+				(void) (*md->pmd_get_config)(cpu, ri, &pm);
 
 				PMCDBG(PRC,EXT,2, "ri=%d pm=%p", ri, pm);
 
 				if (pm == NULL ||
-				    !PMC_IS_VIRTUAL_MODE(pm->pm_mode))
+				    !PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)))
 					continue;
 
 				PMCDBG(PRC,EXT,2, "ppmcs[%d]=%p pm=%p "
 				    "state=%d", ri, pp->pp_pmcs[ri].pp_pmc,
 				    pm, pm->pm_state);
 
-				KASSERT(pm->pm_rowindex == ri,
+				KASSERT(PMC_TO_ROWINDEX(pm) == ri,
 				    ("[pmc,%d] ri mismatch pmc(%d) ri(%d)",
-					__LINE__, pm->pm_rowindex, ri));
+					__LINE__, PMC_TO_ROWINDEX(pm), ri));
 
 				KASSERT(pm == pp->pp_pmcs[ri].pp_pmc,
 				    ("[pmc,%d] pm %p != pp_pmcs[%d] %p",
@@ -1222,10 +1252,11 @@
 					mtx_pool_unlock_spin(pmc_mtxpool, pm);
 				}
 
+				atomic_subtract_rel_32(&pm->pm_runcount,1);
+
 				KASSERT((int) pm->pm_runcount >= 0,
 				    ("[pmc,%d] runcount is %d", __LINE__, ri));
 
-				atomic_subtract_rel_32(&pm->pm_runcount,1);
 				(void) md->pmd_config_pmc(cpu, ri, NULL);
 			}
 
@@ -1254,6 +1285,7 @@
 
 			FREE(pp, M_PMC);
 
+
 		} else
 			critical_exit(); /* pp == NULL */
 
@@ -1445,13 +1477,13 @@
 			if ((pm = pp->pp_pmcs[ri].pp_pmc) == NULL)
 				continue;
 
-			KASSERT(PMC_IS_VIRTUAL_MODE(pm->pm_mode),
+			KASSERT(PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)),
 			    ("[pmc,%d] Target PMC in non-virtual mode (%d)",
-				__LINE__, pm->pm_mode));
+				__LINE__, PMC_TO_MODE(pm)));
 
-			KASSERT(pm->pm_rowindex == ri,
+			KASSERT(PMC_TO_ROWINDEX(pm) == ri,
 			    ("[pmc,%d] Row index mismatch pmc %d != ri %d",
-				__LINE__, pm->pm_rowindex, ri));
+				__LINE__, PMC_TO_ROWINDEX(pm), ri));
 
 			/*
 			 * Only PMCs that are marked as 'RUNNING' need
@@ -1510,7 +1542,6 @@
 		struct pmc *pm;
 		struct proc *p;
 		struct pmc_cpu *pc;
-		struct pmc_hw *phw;
 		struct pmc_process *pp;
 		pmc_value_t newvalue, tmp;
 
@@ -1560,18 +1591,18 @@
 
 		for (ri = 0; ri < md->pmd_npmc; ri++) {
 
-			phw = pc->pc_hwpmcs[ri];
-			pm  = phw->phw_pmc;
+			pm = NULL;
+			(void) (*md->pmd_get_config)(cpu, ri, &pm);
 
 			if (pm == NULL)	/* nothing at this row index */
 				continue;
 
-			if (!PMC_IS_VIRTUAL_MODE(pm->pm_mode))
+			if (!PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)))
 				continue; /* not a process virtual PMC */
 
-			KASSERT(pm->pm_rowindex == ri,
+			KASSERT(PMC_TO_ROWINDEX(pm) == ri,
 			    ("[pmc,%d] ri mismatch pmc(%d) ri(%d)",
-				__LINE__, pm->pm_rowindex, ri));
+				__LINE__, PMC_TO_ROWINDEX(pm), ri));
 
 			/* Stop hardware */
 			md->pmd_stop_pmc(cpu, ri);
@@ -1838,7 +1869,7 @@
 	volatile int maxloop;
 #endif
 	u_int ri, cpu;
-	u_char curpri;
+	enum pmc_mode mode;
 	struct pmc_hw *phw;
 	struct pmc_process *pp;
 	struct pmc_target *ptgt, *tmp;
@@ -1848,16 +1879,17 @@
 
 	KASSERT(pm, ("[pmc,%d] null pmc", __LINE__));
 
-	ri = pm->pm_rowindex;
+	ri   = PMC_TO_ROWINDEX(pm);
+	mode = PMC_TO_MODE(pm);
 
 	PMCDBG(PMC,REL,1, "release-pmc pmc=%p ri=%d mode=%d", pm, ri,
-	    pm->pm_mode);
+	    mode);
 
 	/*
 	 * First, we take the PMC off hardware.
 	 */
 	cpu = 0;
-	if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) {
+	if (PMC_IS_SYSTEM_MODE(mode)) {
 
 		/*
 		 * A system mode PMC runs on a specific CPU.  Switch
@@ -1866,7 +1898,7 @@
 
 		pmc_save_cpu_binding(&pb);
 
-		cpu = pm->pm_gv.pm_cpu;
+		cpu = PMC_TO_CPU(pm);
 
 		if (pm->pm_state == PMC_STATE_RUNNING) {
 
@@ -1895,7 +1927,7 @@
 
 		pmc_restore_cpu_binding(&pb);
 
-	} else if (PMC_IS_VIRTUAL_MODE(pm->pm_mode)) {
+	} else if (PMC_IS_VIRTUAL_MODE(mode)) {
 
 		/*
 		 * A virtual PMC could be running on multiple CPUs at
@@ -1924,17 +1956,11 @@
 			maxloop--;
 			KASSERT(maxloop > 0,
 			    ("[pmc,%d] (ri%d, rc%d) waiting too long for "
-				"pmc to be free", __LINE__, pm->pm_rowindex,
-				pm->pm_runcount));
+				"pmc to be free", __LINE__,
+				PMC_TO_ROWINDEX(pm), pm->pm_runcount));
 #endif
 
-			mtx_lock_spin(&sched_lock);
-			curpri = curthread->td_priority;
-			mtx_unlock_spin(&sched_lock);
-
-			(void) tsleep((void *) pmc_release_pmc_descriptor,
-			    curpri, "pmcrel", 1);
-
+			pmc_force_context_switch();
 		}
 
 		/*
@@ -1977,7 +2003,7 @@
 	 * Update row disposition
 	 */
 
-	if (PMC_IS_SYSTEM_MODE(pm->pm_mode))
+	if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm)))
 		PMC_UNMARK_ROW_STANDALONE(ri);
 	else
 		PMC_UNMARK_ROW_THREAD(ri);
@@ -2007,21 +2033,20 @@
 	if (pl == NULL)
 		return ENOMEM;
 
-	if ((po = pmc_find_owner_descriptor(p)) == NULL) {
+	if ((po = pmc_find_owner_descriptor(p)) == NULL)
 		if ((po = pmc_allocate_owner_descriptor(p)) == NULL) {
 			FREE(pl, M_PMC);
 			return ENOMEM;
 		}
-		po->po_flags |= PMC_FLAG_IS_OWNER; /* real owner */
-	}
 
-	if (pmc->pm_mode == PMC_MODE_TS) {
+	/* XXX is this too restrictive */
+	if (PMC_ID_TO_MODE(pmc->pm_id) == PMC_MODE_TS) {
 		/* can have only one TS mode PMC per process */
-		if (po->po_flags & PMC_FLAG_HAS_TS_PMC) {
+		if (po->po_flags & PMC_PO_HAS_TS_PMC) {
 			FREE(pl, M_PMC);
 			return EINVAL;
 		}
-		po->po_flags |= PMC_FLAG_HAS_TS_PMC;
+		po->po_flags |= PMC_PO_HAS_TS_PMC;
 	}
 
 	KASSERT(pmc->pm_owner == NULL,
@@ -2067,22 +2092,41 @@
  */
 
 static int
-pmc_can_allocate_rowindex(struct proc *p, unsigned int ri)
+pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, int cpu)
 {
+	enum pmc_mode mode;
+	struct pmc *pm;
 	struct pmc_list *pl;
 	struct pmc_owner *po;
 	struct pmc_process *pp;
 
-	PMCDBG(PMC,ALR,1, "can-allocate-rowindex proc=%p (%d, %s) ri=%d",
-	    p, p->p_pid, p->p_comm, ri);
+	PMCDBG(PMC,ALR,1, "can-allocate-rowindex proc=%p (%d, %s) ri=%d "
+	    "cpu=%d", p, p->p_pid, p->p_comm, ri, cpu);
 
-	/* we shouldn't have allocated a PMC at row index 'ri' */
+	/*
+	 * We shouldn't have already allocated a process-mode PMC at
+	 * row index 'ri'.
+	 *
+	 * We shouldn't have allocated a system-wide PMC on the same
+	 * CPU and same RI.
+	 */
 	if ((po = pmc_find_owner_descriptor(p)) != NULL)
-		LIST_FOREACH(pl, &po->po_pmcs, pl_next)
-		    if (pl->pl_pmc->pm_rowindex == ri)
-			    return EEXIST;
+		LIST_FOREACH(pl, &po->po_pmcs, pl_next) {
+		    pm   = pl->pl_pmc;
+		    if (PMC_TO_ROWINDEX(pm) == ri) {
+			    mode = PMC_TO_MODE(pm);
+			    if (PMC_IS_VIRTUAL_MODE(mode))
+				    return EEXIST;
+			    if (PMC_IS_SYSTEM_MODE(mode) &&
+				(int) PMC_TO_CPU(pm) == cpu)
+				    return EEXIST;
+		    }
+	        }
 
-	/* we shouldn't be the target of any PMC ourselves at this index */
+	/*
+	 * We also shouldn't be the target of any PMC at this index
+	 * since otherwise a PMC_ATTACH to ourselves will fail.
+	 */
 	if ((pp = pmc_find_process_descriptor(p, 0)) != NULL)
 		if (pp->pp_pmcs[ri].pp_pmc)
 			return EEXIST;
@@ -2139,7 +2183,7 @@
 }
 
 /*
- * Find a PMC descriptor with user handle 'pmc' for thread 'td'.
+ * Find a PMC descriptor with user handle 'pmcid' for thread 'td'.
  */
 
 static struct pmc *
@@ -2147,12 +2191,12 @@
 {
 	struct pmc_list	*pl;
 
-	KASSERT(pmcid < md->pmd_npmc,
-	    ("[pmc,%d] Illegal pmc index %d (max %d)", __LINE__, pmcid,
-		md->pmd_npmc));
+	KASSERT(PMC_ID_TO_ROWINDEX(pmcid) < md->pmd_npmc,
+	    ("[pmc,%d] Illegal pmc index %d (max %d)", __LINE__,
+		PMC_ID_TO_ROWINDEX(pmcid), md->pmd_npmc));
 
 	LIST_FOREACH(pl, &po->po_pmcs, pl_next)
-	    if (pl->pl_pmc->pm_rowindex == pmcid)
+	    if (pl->pl_pmc->pm_id == pmcid)
 		    return pl->pl_pmc;
 
 	return NULL;
@@ -2187,17 +2231,21 @@
 pmc_start(struct pmc *pm)
 {
 	int error, cpu, ri;
+	enum pmc_mode mode;
 	struct pmc_binding pb;
 
 	KASSERT(pm != NULL,
 	    ("[pmc,%d] null pm", __LINE__));
 
-	PMCDBG(PMC,OPS,1, "start pmc=%p mode=%d ri=%d", pm, pm->pm_mode,
-	    pm->pm_rowindex);
+	mode = PMC_TO_MODE(pm);
+	ri   = PMC_TO_ROWINDEX(pm);
+	error = 0;
+
+	PMCDBG(PMC,OPS,1, "start pmc=%p mode=%d ri=%d", pm, mode, ri);
 
 	pm->pm_state = PMC_STATE_RUNNING;
 
-	if (PMC_IS_VIRTUAL_MODE(pm->pm_mode)) {
+	if (PMC_IS_VIRTUAL_MODE(mode)) {
 
 		/*
 		 * If a PMCATTACH hadn't been done on this
@@ -2205,32 +2253,36 @@
 		 */
 
 		if (LIST_EMPTY(&pm->pm_targets))
-			return pmc_attach_process(pm->pm_owner->po_owner, pm);
+			error = pmc_attach_process(pm->pm_owner->po_owner, pm);
 
+		/*
+		 * If the PMC is attached to its owner, then force a context
+		 * switch to ensure that the MD state gets set correctly.
+		 */
+		if (error == 0 && (pm->pm_flags & PMC_F_ATTACHED_TO_OWNER))
+			pmc_force_context_switch();
 
 		/*
 		 * Nothing further to be done; thread context switch code
-		 * will start/stop the PMC as appropriate.
+		 * will start/stop the hardware as appropriate.
 		 */
 
-		return 0;
+		return error;
 
 	}
 
 	/*
-	 * A system-mode PMC.  Move to the CPU associated with this
+	 * A system-wide PMC.  Move to the CPU associated with this
 	 * PMC, and start the hardware.
 	 */
 
 	pmc_save_cpu_binding(&pb);
 
-	cpu = pm->pm_gv.pm_cpu;
+	cpu = PMC_TO_CPU(pm);
 
 	if (pmc_cpu_is_disabled(cpu))
 		return ENXIO;
 
-	ri  = pm->pm_rowindex;
-
 	pmc_select_cpu(cpu);
 
 	/*
@@ -2238,11 +2290,13 @@
 	 * so write out the initial value and start the PMC.
 	 */
 
+	critical_enter();
 	if ((error = md->pmd_write_pmc(cpu, ri,
-		 PMC_IS_SAMPLING_MODE(pm->pm_mode) ?
+		 PMC_IS_SAMPLING_MODE(mode) ?
 		 pm->pm_sc.pm_reloadcount :
 		 pm->pm_sc.pm_initial)) == 0)
 		error = md->pmd_start_pmc(cpu, ri);
+	critical_exit();
 
 	pmc_restore_cpu_binding(&pb);
 
@@ -2256,13 +2310,13 @@
 static int
 pmc_stop(struct pmc *pm)
 {

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list