summaryrefslogtreecommitdiffstats
path: root/sys/sys/pmc.h
diff options
context:
space:
mode:
authorfabient <fabient@FreeBSD.org>2012-03-28 20:58:30 +0000
committerfabient <fabient@FreeBSD.org>2012-03-28 20:58:30 +0000
commit5edfb77dd3a164bb9d2d40c6604faa6c9f3dce15 (patch)
treefadff08d26576c3d5c1cef9d47abd784602b237a /sys/sys/pmc.h
parent9a7982e5a0267c0421856f3a43a1ae75880058f3 (diff)
downloadFreeBSD-src-5edfb77dd3a164bb9d2d40c6604faa6c9f3dce15.zip
FreeBSD-src-5edfb77dd3a164bb9d2d40c6604faa6c9f3dce15.tar.gz
Add software PMC support.
New kernel events can be added at various location for sampling or counting. This will for example allow easy system profiling whatever the processor is with known tools like pmcstat(8). Simultaneous usage of software PMC and hardware PMC is possible, for example looking at the lock acquire failure, page fault while sampling on instructions. Sponsored by: NETASQ MFC after: 1 month
Diffstat (limited to 'sys/sys/pmc.h')
-rw-r--r--sys/sys/pmc.h66
1 files changed, 45 insertions, 21 deletions
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index 49454ec..7c67b9b 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -39,8 +39,8 @@
#include <machine/profile.h>
#define PMC_MODULE_NAME "hwpmc"
-#define PMC_NAME_MAX 16 /* HW counter name size */
-#define PMC_CLASS_MAX 6 /* max #classes of PMCs per-system */
+#define PMC_NAME_MAX 64 /* HW counter name size */
+#define PMC_CLASS_MAX 8 /* max #classes of PMCs per-system */
/*
* Kernel<->userland API version number [MMmmpppp]
@@ -83,14 +83,15 @@
__PMC_CPU(INTEL_CORE, 0x87, "Intel Core Solo/Duo") \
__PMC_CPU(INTEL_CORE2, 0x88, "Intel Core2") \
__PMC_CPU(INTEL_CORE2EXTREME, 0x89, "Intel Core2 Extreme") \
- __PMC_CPU(INTEL_ATOM, 0x8A, "Intel Atom") \
- __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7") \
- __PMC_CPU(INTEL_WESTMERE, 0x8C, "Intel Westmere") \
- __PMC_CPU(INTEL_SANDYBRIDGE, 0x8D, "Intel Sandy Bridge") \
- __PMC_CPU(INTEL_XSCALE, 0x100, "Intel XScale") \
- __PMC_CPU(MIPS_24K, 0x200, "MIPS 24K") \
- __PMC_CPU(MIPS_OCTEON, 0x201, "Cavium Octeon") \
- __PMC_CPU(PPC_7450, 0x300, "PowerPC MPC7450")
+ __PMC_CPU(INTEL_ATOM, 0x8A, "Intel Atom") \
+ __PMC_CPU(INTEL_COREI7, 0x8B, "Intel Core i7") \
+ __PMC_CPU(INTEL_WESTMERE, 0x8C, "Intel Westmere") \
+ __PMC_CPU(INTEL_SANDYBRIDGE, 0x8D, "Intel Sandy Bridge") \
+ __PMC_CPU(INTEL_XSCALE, 0x100, "Intel XScale") \
+ __PMC_CPU(MIPS_24K, 0x200, "MIPS 24K") \
+ __PMC_CPU(MIPS_OCTEON, 0x201, "Cavium Octeon") \
+ __PMC_CPU(PPC_7450, 0x300, "PowerPC MPC7450") \
+ __PMC_CPU(GENERIC, 0x400, "Generic")
enum pmc_cputype {
#undef __PMC_CPU
@@ -99,7 +100,7 @@ enum pmc_cputype {
};
#define PMC_CPU_FIRST PMC_CPU_AMD_K7
-#define PMC_CPU_LAST PMC_CPU_PPC_7450
+#define PMC_CPU_LAST PMC_CPU_GENERIC
/*
* Classes of PMCs
@@ -119,7 +120,8 @@ enum pmc_cputype {
__PMC_CLASS(XSCALE) /* Intel XScale counters */ \
__PMC_CLASS(MIPS24K) /* MIPS 24K */ \
__PMC_CLASS(OCTEON) /* Cavium Octeon */ \
- __PMC_CLASS(PPC7450) /* Motorola MPC7450 class */
+ __PMC_CLASS(PPC7450) /* Motorola MPC7450 class */ \
+ __PMC_CLASS(SOFT) /* Software events */
enum pmc_class {
#undef __PMC_CLASS
@@ -128,7 +130,7 @@ enum pmc_class {
};
#define PMC_CLASS_FIRST PMC_CLASS_TSC
-#define PMC_CLASS_LAST PMC_CLASS_PPC7450
+#define PMC_CLASS_LAST PMC_CLASS_SOFT
/*
* A PMC can be in the following states:
@@ -308,7 +310,8 @@ enum pmc_event {
__PMC_OP(PMCSTART, "Start a PMC") \
__PMC_OP(PMCSTOP, "Stop a PMC") \
__PMC_OP(WRITELOG, "Write a cookie to the log file") \
- __PMC_OP(CLOSELOG, "Close log file")
+ __PMC_OP(CLOSELOG, "Close log file") \
+ __PMC_OP(GETDYNEVENTINFO, "Get dynamic events list")
enum pmc_ops {
@@ -338,6 +341,7 @@ enum pmc_ops {
#define PMC_F_ATTACH_DONE 0x00040000 /*attached at least once */
#define PMC_CALLCHAIN_DEPTH_MAX 32
+
#define PMC_CC_F_USERSPACE 0x01 /*userspace callchain*/
/*
@@ -486,6 +490,7 @@ struct pmc_op_getpmcinfo {
* Retrieve system CPU information.
*/
+
struct pmc_classinfo {
enum pmc_class pm_class; /* class id */
uint32_t pm_caps; /* counter capabilities */
@@ -562,6 +567,23 @@ struct pmc_op_getmsr {
pmc_id_t pm_pmcid; /* allocated pmc id */
};
+/*
+ * OP GETDYNEVENTINFO
+ *
+ * Retrieve a PMC dynamic class events list.
+ */
+
+struct pmc_dyn_event_descr {
+ char pm_ev_name[PMC_NAME_MAX];
+ enum pmc_event pm_ev_code;
+};
+
+struct pmc_op_getdyneventinfo {
+ enum pmc_class pm_class;
+ unsigned int pm_nevent;
+ struct pmc_dyn_event_descr pm_events[PMC_EV_DYN_COUNT];
+};
+
#ifdef _KERNEL
#include <sys/malloc.h>
@@ -572,8 +594,8 @@ struct pmc_op_getmsr {
#define PMC_HASH_SIZE 16
#define PMC_MTXPOOL_SIZE 32
#define PMC_LOG_BUFFER_SIZE 4
-#define PMC_NLOGBUFFERS 16
-#define PMC_NSAMPLES 32
+#define PMC_NLOGBUFFERS 64
+#define PMC_NSAMPLES 512
#define PMC_CALLCHAIN_DEPTH 8
#define PMC_SYSCTL_NAME_PREFIX "kern." PMC_MODULE_NAME "."
@@ -829,8 +851,8 @@ struct pmc_sample {
uintptr_t *ps_pc; /* (const) callchain start */
};
-#define PMC_SAMPLE_FREE ((uint16_t) 0)
-#define PMC_SAMPLE_INUSE ((uint16_t) 0xFFFF)
+#define PMC_SAMPLE_FREE ((uint16_t) 0)
+#define PMC_SAMPLE_INUSE ((uint16_t) 0xFFFF)
struct pmc_samplebuffer {
struct pmc_sample * volatile ps_read; /* read pointer */
@@ -850,7 +872,7 @@ struct pmc_samplebuffer {
struct pmc_cpu {
uint32_t pc_state; /* physical cpu number + flags */
- struct pmc_samplebuffer *pc_sb; /* space for samples */
+ struct pmc_samplebuffer *pc_sb[2]; /* space for samples */
struct pmc_hw *pc_hwpmcs[]; /* 'npmc' pointers */
};
@@ -958,7 +980,7 @@ extern struct pmc_cpu **pmc_pcpu;
/* driver statistics */
extern struct pmc_op_getdriverstats pmc_stats;
-#if defined(DEBUG) && DEBUG
+#if defined(DEBUG)
/* debug flags, major flag groups */
struct pmc_debugflags {
@@ -1061,11 +1083,13 @@ MALLOC_DECLARE(M_PMC);
struct pmc_mdep *pmc_md_initialize(void); /* MD init function */
void pmc_md_finalize(struct pmc_mdep *_md); /* MD fini function */
int pmc_getrowdisp(int _ri);
-int pmc_process_interrupt(int _cpu, struct pmc *_pm,
+int pmc_process_interrupt(int _cpu, int _soft, struct pmc *_pm,
struct trapframe *_tf, int _inuserspace);
int pmc_save_kernel_callchain(uintptr_t *_cc, int _maxsamples,
struct trapframe *_tf);
int pmc_save_user_callchain(uintptr_t *_cc, int _maxsamples,
struct trapframe *_tf);
+struct pmc_mdep *pmc_mdep_alloc(int nclasses);
+void pmc_mdep_free(struct pmc_mdep *md);
#endif /* _KERNEL */
#endif /* _SYS_PMC_H_ */
OpenPOWER on IntegriCloud