aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/hwpmc
diff options
context:
space:
mode:
authorJoseph Koshy <jkoshy@FreeBSD.org>2005-04-28 08:13:19 +0000
committerJoseph Koshy <jkoshy@FreeBSD.org>2005-04-28 08:13:19 +0000
commit6b8c8cd85fae1f4947956b06ec59b4f808951f29 (patch)
tree6d64ad42ff8aec2fef5909520668bd5172f0949c /sys/dev/hwpmc
parent47cc56ab555921e611324f7c620bf5115e02b7e4 (diff)
Notes
Diffstat (limited to 'sys/dev/hwpmc')
-rw-r--r--sys/dev/hwpmc/hwpmc_amd.c27
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c31
-rw-r--r--sys/dev/hwpmc/hwpmc_piv.c28
-rw-r--r--sys/dev/hwpmc/hwpmc_ppro.c13
4 files changed, 78 insertions, 21 deletions
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index a78943a125a9e..158dc0bcd3c8a 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -443,6 +443,8 @@ amd_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
+ PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+
KASSERT(cpu >= 0 && cpu < mp_ncpus,
("[amd,%d] illegal CPU value %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < AMD_NPMCS,
@@ -451,7 +453,8 @@ amd_config_pmc(int cpu, int ri, struct pmc *pm)
phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
KASSERT(pm == NULL || phw->phw_pmc == NULL,
- ("[amd,%d] hwpmc not unconfigured before re-config", __LINE__));
+ ("[amd,%d] pm=%p phw->pm=%p hwpmc not unconfigured",
+ __LINE__, pm, phw->phw_pmc));
phw->phw_pmc = pm;
return 0;
@@ -463,12 +466,17 @@ amd_config_pmc(int cpu, int ri, struct pmc *pm)
*/
static int
-amd_switch_in(struct pmc_cpu *pc)
+amd_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
- /* enable the RDPMC instruction */
- load_cr4(rcr4() | CR4_PCE);
+ PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
+ (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
+
+ /* enable the RDPMC instruction if needed */
+ if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS)
+ load_cr4(rcr4() | CR4_PCE);
+
return 0;
}
@@ -478,12 +486,17 @@ amd_switch_in(struct pmc_cpu *pc)
*/
static int
-amd_switch_out(struct pmc_cpu *pc)
+amd_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
+ (void) pp; /* can be NULL */
- /* disallow RDPMC instruction */
+ PMCDBG(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ?
+ (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) == 1 : 0);
+
+ /* always turn off the RDPMC instruction */
load_cr4(rcr4() & ~CR4_PCE);
+
return 0;
}
@@ -818,7 +831,7 @@ amd_get_msr(int ri, uint32_t *msr)
KASSERT(ri >= 0 && ri < AMD_NPMCS,
("[amd,%d] ri %d out of range", __LINE__, ri));
- *msr = amd_pmcdesc[ri].pm_perfctr;
+ *msr = amd_pmcdesc[ri].pm_perfctr - AMD_PMC_PERFCTR_0;
return 0;
}
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 3f5cbd779e0f0..00cf9fa72d980 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -739,8 +739,13 @@ pmc_link_target_process(struct pmc *pm, struct pmc_process *pp)
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;
+
pp->pp_refcnt++;
+ PMCDBG(PRC,TLK,2, "enable-msr %d",
+ (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
}
/*
@@ -774,6 +779,9 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp)
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;
+
pp->pp_refcnt--;
/* Remove the target process from the PMC structure */
@@ -784,7 +792,8 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp)
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", ptgt);
+ 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);
@@ -1159,10 +1168,10 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
"process-exit proc=%p pmc-process=%p", p, pp);
/*
- * This process could the target of some PMCs.
- * Such PMCs will thus be running on currently
- * executing CPU at this point in the code
- * since we've disallowed context switches.
+ * The exiting process could the target of
+ * some PMCs which will be running on
+ * currently executing CPU.
+ *
* We need to turn these PMCs off like we
* would do at context switch OUT time.
*/
@@ -1219,6 +1228,14 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
atomic_subtract_rel_32(&pm->pm_runcount,1);
(void) md->pmd_config_pmc(cpu, ri, NULL);
}
+
+ /*
+ * Inform the MD layer of this pseudo "context switch
+ * out"
+ */
+
+ (void) md->pmd_switch_out(pmc_pcpu[cpu], pp);
+
critical_exit(); /* ok to be pre-empted now */
/*
@@ -1475,7 +1492,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
* switch-in actions.
*/
- (void) (*md->pmd_switch_in)(pc);
+ (void) (*md->pmd_switch_in)(pc, pp);
critical_exit();
@@ -1614,7 +1631,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg)
* switch out functions.
*/
- (void) (*md->pmd_switch_out)(pc);
+ (void) (*md->pmd_switch_out)(pc, pp);
critical_exit();
diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c
index de2ad7040e9a3..67be02626aefa 100644
--- a/sys/dev/hwpmc/hwpmc_piv.c
+++ b/sys/dev/hwpmc/hwpmc_piv.c
@@ -578,11 +578,19 @@ p4_cleanup(int cpu)
*/
static int
-p4_switch_in(struct pmc_cpu *pc)
+p4_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
+
+ PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
+ (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
+
/* enable the RDPMC instruction */
- load_cr4(rcr4() | CR4_PCE);
+ if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS)
+ load_cr4(rcr4() | CR4_PCE);
+
+ PMCDBG(MDP,SWI,2, "cr4=0x%x", rcr4());
+
return 0;
}
@@ -591,11 +599,18 @@ p4_switch_in(struct pmc_cpu *pc)
*/
static int
-p4_switch_out(struct pmc_cpu *pc)
+p4_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
- /* disallow RDPMC instruction */
+ (void) pp; /* can be null */
+
+ PMCDBG(MDP,SWO,1, "pc=%p pp=%p", pc, pp);
+
+ /* always disallow the RDPMC instruction */
load_cr4(rcr4() & ~CR4_PCE);
+
+ PMCDBG(MDP,SWO,2, "cr4=0x%x", rcr4());
+
return 0;
}
@@ -1419,7 +1434,10 @@ p4_get_msr(int ri, uint32_t *msr)
KASSERT(ri >= 0 && ri < P4_NPMCS,
("[p4,%d] ri %d out of range", __LINE__, ri));
- *msr = p4_pmcdesc[ri].pm_pmc_msr;
+ *msr = p4_pmcdesc[ri].pm_pmc_msr - P4_PERFCTR_MSR_FIRST;
+
+ PMCDBG(MDP,OPS, 1, "ri=%d getmsr=0x%x", ri, *msr);
+
return 0;
}
diff --git a/sys/dev/hwpmc/hwpmc_ppro.c b/sys/dev/hwpmc/hwpmc_ppro.c
index c08c5091c5b2a..1bd19be6391e3 100644
--- a/sys/dev/hwpmc/hwpmc_ppro.c
+++ b/sys/dev/hwpmc/hwpmc_ppro.c
@@ -332,16 +332,25 @@ p6_cleanup(int cpu)
}
static int
-p6_switch_in(struct pmc_cpu *pc)
+p6_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
+
+ /* allow the RDPMC instruction if needed */
+ if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS)
+ load_cr4(rcr4() | CR4_PCE);
return 0;
}
static int
-p6_switch_out(struct pmc_cpu *pc)
+p6_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
{
(void) pc;
+ (void) pp; /* can be NULL */
+
+ /* always turn off the RDPMC instruction */
+ load_cr4(rcr4() & ~CR4_PCE);
+
return 0;
}