summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkoshy <jkoshy@FreeBSD.org>2005-07-09 17:29:36 +0000
committerjkoshy <jkoshy@FreeBSD.org>2005-07-09 17:29:36 +0000
commit5347c3345e3e5d6903a225ccf0da3c83800f49ec (patch)
tree9f3f9763bb2a5ec73a7aafb28592beedb2767211
parenta9a2668bf2dea09c72c2e42e5d504e3230c15ce3 (diff)
downloadFreeBSD-src-5347c3345e3e5d6903a225ccf0da3c83800f49ec.zip
FreeBSD-src-5347c3345e3e5d6903a225ccf0da3c83800f49ec.tar.gz
sys/dev/hwpmc/hwpmc_{amd,piv,ppro}.c:
- Update driver interrupt statistics correctly. sys/sys/pmc.h, sys/dev/hwpmc/hwpmc_mod.c: - Fix a bug affecting debug printfs. - Move the 'stalled' flag from being in a bit in the 'pm_flags' field of a 'struct pmc' to a field of its own in the same structure. This flag is updated from the NMI handler and keeping it separate makes it easier to avoid races with other parts of the code. sys/dev/hwpmc/hwpmc_logging.c: - Do arithmetic with 'uintptr_t' types rather that casting to and from 'char *'. Approved by: re (scottl)
-rw-r--r--sys/dev/hwpmc/hwpmc_amd.c8
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c34
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c26
-rw-r--r--sys/dev/hwpmc/hwpmc_piv.c5
-rw-r--r--sys/dev/hwpmc/hwpmc_ppro.c5
-rw-r--r--sys/sys/pmc.h4
6 files changed, 46 insertions, 36 deletions
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index 306214c..6285f7f 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -679,7 +679,8 @@ amd_intr(int cpu, uintptr_t eip, int usermode)
KASSERT(cpu >= 0 && cpu < mp_ncpus,
("[amd,%d] out of range CPU %d", __LINE__, cpu));
- PMCDBG(MDP,INT,1, "cpu=%d eip=%p", cpu, (void *) eip);
+ PMCDBG(MDP,INT,1, "cpu=%d eip=%p um=%d", cpu, (void *) eip,
+ usermode);
retval = 0;
@@ -733,8 +734,9 @@ amd_intr(int cpu, uintptr_t eip, int usermode)
retval = 1; /* found an interrupting PMC */
}
- if (retval == 0)
- atomic_add_int(&pmc_stats.pm_intr_ignored, 1);
+ atomic_add_int(retval ? &pmc_stats.pm_intr_processed :
+ &pmc_stats.pm_intr_ignored, 1);
+
return retval;
}
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index bca14bd..8b6f376 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -97,6 +97,11 @@ static struct mtx pmc_kthread_mtx; /* sleep lock */
* Log file record constructors.
*/
+#define _PMCLOG_TO_HEADER(T,L) \
+ ((PMCLOG_HEADER_MAGIC << 24) | \
+ (PMCLOG_TYPE_ ## T << 16) | \
+ ((L) & 0xFFFF))
+
/* reserve LEN bytes of space and initialize the entry header */
#define _PMCLOG_RESERVE(PO,TYPE,LEN,ACTION) do { \
uint32_t *_le; \
@@ -104,9 +109,7 @@ static struct mtx pmc_kthread_mtx; /* sleep lock */
if ((_le = pmclog_reserve((PO), _len)) == NULL) { \
ACTION; \
} \
- *_le = (PMCLOG_HEADER_MAGIC << 24) | \
- (PMCLOG_TYPE_ ## TYPE << 16) | \
- (_len & 0xFFFF); \
+ *_le = _PMCLOG_TO_HEADER(TYPE,_len); \
_le += 3 /* skip over timestamp */
#define PMCLOG_RESERVE(P,T,L) _PMCLOG_RESERVE(P,T,L,return)
@@ -397,7 +400,7 @@ pmclog_release(struct pmc_owner *po)
static uint32_t *
pmclog_reserve(struct pmc_owner *po, int length)
{
- char *newptr, *oldptr;
+ uintptr_t newptr, oldptr;
uint32_t *lh;
struct timespec ts;
@@ -423,22 +426,25 @@ pmclog_reserve(struct pmc_owner *po, int length)
__LINE__, po, po->po_curbuf->plb_ptr, po->po_curbuf->plb_base,
po->po_curbuf->plb_fence));
- oldptr = po->po_curbuf->plb_ptr;
+ oldptr = (uintptr_t) po->po_curbuf->plb_ptr;
newptr = oldptr + length;
- KASSERT(oldptr != NULL,
+ KASSERT(oldptr != (uintptr_t) NULL,
("[pmc,%d] po=%p Null log buffer pointer", __LINE__, po));
/*
* If we have space in the current buffer, return a pointer to
* available space with the PO structure locked.
*/
- if (newptr <= po->po_curbuf->plb_fence) {
- po->po_curbuf->plb_ptr = newptr;
+ if (newptr <= (uintptr_t) po->po_curbuf->plb_fence) {
+ po->po_curbuf->plb_ptr = (char *) newptr;
goto done;
}
- /* otherwise, schedule the current buffer and get a fresh buffer */
+ /*
+ * Otherwise, schedule the current buffer for output and get a
+ * fresh buffer.
+ */
pmclog_schedule_io(po);
if (pmclog_get_buffer(po) != 0) {
@@ -458,12 +464,12 @@ pmclog_reserve(struct pmc_owner *po, int length)
__LINE__, po, po->po_curbuf->plb_ptr, po->po_curbuf->plb_base,
po->po_curbuf->plb_fence));
- oldptr = po->po_curbuf->plb_ptr;
+ oldptr = (uintptr_t) po->po_curbuf->plb_ptr;
done:
- lh = (uint32_t *) oldptr; lh++;
- /* fill in the timestamp */
- getnanotime(&ts);
+ lh = (uint32_t *) oldptr;
+ lh++; /* skip header */
+ getnanotime(&ts); /* fill in the timestamp */
*lh++ = ts.tv_sec & 0xFFFFFFFF;
*lh++ = ts.tv_nsec & 0xFFFFFFF;
return (uint32_t *) oldptr;
@@ -517,7 +523,7 @@ pmclog_stop_kthread(struct pmc_owner *po)
po->po_flags &= ~PMC_PO_OWNS_LOGFILE;
wakeup_one(po);
if (po->po_kthread)
- msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmcdcl", 0);
+ msleep(po->po_kthread, &pmc_kthread_mtx, PPAUSE, "pmckstp", 0);
}
/*
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 867722c..299746d 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -1324,7 +1324,7 @@ pmc_process_csw_out(struct thread *td)
__LINE__, PMC_TO_ROWINDEX(pm), ri));
/* Stop hardware if not already stopped */
- if ((pm->pm_flags & PMC_F_IS_STALLED) == 0)
+ if (pm->pm_stalled == 0)
md->pmd_stop_pmc(cpu, ri);
/* reduce this PMC's runcount */
@@ -1855,7 +1855,7 @@ pmc_release_pmc_descriptor(struct pmc *pm)
/* switch off non-stalled CPUs */
if (pm->pm_state == PMC_STATE_RUNNING &&
- (pm->pm_flags & PMC_F_IS_STALLED) == 0) {
+ pm->pm_stalled == 0) {
phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
@@ -3395,8 +3395,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
/*
- * Flush the per-owner log file and Write a user-entry to the
- * log file.
+ * Write a user supplied value to the log file.
*/
case PMC_OP_WRITELOG:
@@ -3474,8 +3473,8 @@ pmc_process_interrupt(int cpu, struct pmc *pm, uintfptr_t pc, int usermode)
ps = psb->ps_write;
if (ps->ps_pc) { /* in use, reader hasn't caught up */
+ pm->pm_stalled = 1;
atomic_add_int(&pmc_stats.pm_intr_bufferfull, 1);
- atomic_set_int(&pm->pm_flags, PMC_F_IS_STALLED);
PMCDBG(SAM,INT,1,"(spc) cpu=%d pm=%p pc=%jx um=%d wr=%d rd=%d",
cpu, pm, (uint64_t) pc, usermode,
(int) (psb->ps_write - psb->ps_samples),
@@ -3599,19 +3598,19 @@ pmc_process_samples(int cpu)
/*
* Restart any stalled sampling PMCs on this CPU.
*
- * If the NMI handler sets PMC_F_IS_STALLED on a PMC after the
- * check below, we'll end up processing the stalled PMC at the
- * next hardclock tick.
+ * If the NMI handler sets the pm_stalled field of a PMC after
+ * the check below, we'll end up processing the stalled PMC at
+ * the next hardclock tick.
*/
for (n = 0; n < md->pmd_npmc; n++) {
(void) (*md->pmd_get_config)(cpu,n,&pm);
if (pm == NULL || /* !cfg'ed */
pm->pm_state != PMC_STATE_RUNNING || /* !active */
!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)) || /* !sampling */
- (pm->pm_flags & PMC_F_IS_STALLED) == 0) /* !stalled */
+ pm->pm_stalled == 0) /* !stalled */
continue;
- pm->pm_flags &= ~PMC_F_IS_STALLED;
+ pm->pm_stalled = 0;
ri = PMC_TO_ROWINDEX(pm);
(*md->pmd_start_pmc)(cpu, ri);
}
@@ -3733,9 +3732,9 @@ pmc_process_exit(void *arg __unused, struct proc *p)
("[pmc,%d] bad runcount ri %d rc %d",
__LINE__, ri, pm->pm_runcount));
- /* Stopped the hardware only if it is actually on */
+ /* Stop hardware only if it is actually running */
if (pm->pm_state == PMC_STATE_RUNNING &&
- (pm->pm_flags & PMC_F_IS_STALLED) == 0) {
+ pm->pm_stalled == 0) {
md->pmd_read_pmc(cpu, ri, &newvalue);
tmp = newvalue -
PMC_PCPU_SAVED(cpu,ri);
@@ -3771,7 +3770,8 @@ pmc_process_exit(void *arg __unused, struct proc *p)
*/
for (ri = 0; ri < md->pmd_npmc; ri++)
if ((pm = pp->pp_pmcs[ri].pp_pmc) != NULL) {
- if (pm->pm_flags & PMC_F_NEEDS_LOGFILE)
+ if (pm->pm_flags & PMC_F_NEEDS_LOGFILE &&
+ PMC_IS_COUNTING_MODE(PMC_TO_MODE(pm)))
pmclog_process_procexit(pm, pp);
pmc_unlink_target_process(pm, pp);
}
diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c
index 0b14745..0b8ccd6 100644
--- a/sys/dev/hwpmc/hwpmc_piv.c
+++ b/sys/dev/hwpmc/hwpmc_piv.c
@@ -1674,8 +1674,9 @@ p4_intr(int cpu, uintptr_t eip, int usermode)
if (did_interrupt)
pmc_x86_lapic_enable_pmc_interrupt();
- else
- atomic_add_int(&pmc_stats.pm_intr_ignored, 1);
+
+ atomic_add_int(did_interrupt ? &pmc_stats.pm_intr_processed :
+ &pmc_stats.pm_intr_ignored, 1);
return did_interrupt;
}
diff --git a/sys/dev/hwpmc/hwpmc_ppro.c b/sys/dev/hwpmc/hwpmc_ppro.c
index 9c89c9e..bfb0fc4 100644
--- a/sys/dev/hwpmc/hwpmc_ppro.c
+++ b/sys/dev/hwpmc/hwpmc_ppro.c
@@ -762,8 +762,9 @@ p6_intr(int cpu, uintptr_t eip, int usermode)
*/
if (retval)
pmc_x86_lapic_enable_pmc_interrupt();
- else
- atomic_add_int(&pmc_stats.pm_intr_ignored, 1);
+
+ atomic_add_int(retval ? &pmc_stats.pm_intr_processed :
+ &pmc_stats.pm_intr_ignored, 1);
/* restart counters that can be restarted */
P6_SYNC_CTR_STATE(pc);
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index e872ffb..0195a8d 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -306,7 +306,6 @@ enum pmc_ops {
#define PMC_F_ATTACHED_TO_OWNER 0x00010000 /*attached to owner*/
#define PMC_F_NEEDS_LOGFILE 0x00020000 /*needs log file */
#define PMC_F_ATTACH_DONE 0x00040000 /*attached at least once */
-#define PMC_F_IS_STALLED 0x00080000 /*sampling is stalled*/
/*
* Cookies used to denote allocated PMCs, and the values of PMCs.
@@ -646,6 +645,7 @@ struct pmc {
pmc_value_t pm_initial; /* counting PMC modes */
} pm_sc;
+ uint32_t pm_stalled; /* true for stalled sampling PMCs */
uint32_t pm_caps; /* PMC capabilities */
enum pmc_event pm_event; /* event being measured */
uint32_t pm_flags; /* additional flags PMC_F_... */
@@ -915,7 +915,7 @@ extern struct pmc_debugflags pmc_debugflags;
#define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0 }
#define PMCDBG(M,N,L,F,...) do { \
- if (pmc_debugflags.pdb_ ## M & PMC_DEBUG_MIN_ ## N) \
+ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \
printf(#M ":" #N ":" #L ": " F "\n", __VA_ARGS__); \
} while (0)
OpenPOWER on IntegriCloud