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