Page MenuHomeFreeBSD

D15088.id42983.diff
No OneTemporary

D15088.id42983.diff

Index: lib/libpmc/libpmc.c
===================================================================
--- lib/libpmc/libpmc.c
+++ lib/libpmc/libpmc.c
@@ -76,6 +76,10 @@
static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif
+#if defined(__amd64__)
+static int pt_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
+#endif
#if defined(__arm__)
#if defined(__XSCALE__)
static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
@@ -87,6 +91,8 @@
#if defined(__aarch64__)
static int arm64_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
+static int coresight_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
#endif
#if defined(__mips__)
static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec,
@@ -239,6 +245,12 @@
__PMC_EV_ALIAS_SKYLAKE_XEON()
};
+static const struct pmc_event_descr kabylake_event_table[] =
+{
+ /* Kabylake events are similar to Skylake */
+ __PMC_EV_ALIAS_SKYLAKE()
+};
+
static const struct pmc_event_descr ivybridge_event_table[] =
{
__PMC_EV_ALIAS_IVYBRIDGE()
@@ -336,6 +348,7 @@
PMC_MDEP_TABLE(broadwell_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
PMC_MDEP_TABLE(skylake, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
PMC_MDEP_TABLE(skylake_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(kabylake, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP, PMC_CLASS_PT);
PMC_MDEP_TABLE(ivybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
PMC_MDEP_TABLE(ivybridge_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
@@ -350,8 +363,8 @@
PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE);
PMC_MDEP_TABLE(cortex_a8, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
PMC_MDEP_TABLE(cortex_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
-PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
-PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
+PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8, PMC_CLASS_CORESIGHT);
+PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8, PMC_CLASS_CORESIGHT);
PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K);
PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
@@ -365,6 +378,16 @@
__PMC_EV_TSC()
};
+static const struct pmc_event_descr pt_event_table[] =
+{
+ __PMC_EV_PT()
+};
+
+static const struct pmc_event_descr coresight_event_table[] =
+{
+ __PMC_EV_CORESIGHT()
+};
+
#undef PMC_CLASS_TABLE_DESC
#define PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR) \
static const struct pmc_class_descr NAME##_class_table_descr = \
@@ -392,6 +415,7 @@
PMC_CLASS_TABLE_DESC(broadwell_xeon, IAP, broadwell_xeon, iap);
PMC_CLASS_TABLE_DESC(skylake, IAP, skylake, iap);
PMC_CLASS_TABLE_DESC(skylake_xeon, IAP, skylake_xeon, iap);
+PMC_CLASS_TABLE_DESC(kabylake, IAP, kabylake, iap);
PMC_CLASS_TABLE_DESC(ivybridge, IAP, ivybridge, iap);
PMC_CLASS_TABLE_DESC(ivybridge_xeon, IAP, ivybridge_xeon, iap);
PMC_CLASS_TABLE_DESC(sandybridge, IAP, sandybridge, iap);
@@ -419,6 +443,9 @@
#if defined(__i386__) || defined(__amd64__)
PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
#endif
+#if defined(__amd64__)
+PMC_CLASS_TABLE_DESC(pt, PT, pt, pt);
+#endif
#if defined(__arm__)
#if defined(__XSCALE__)
PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
@@ -429,6 +456,7 @@
#if defined(__aarch64__)
PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
+PMC_CLASS_TABLE_DESC(coresight, CORESIGHT, coresight, coresight);
#endif
#if defined(__mips__)
PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
@@ -732,6 +760,8 @@
#define skylake_aliases_without_iaf core2_aliases_without_iaf
#define skylake_xeon_aliases core2_aliases
#define skylake_xeon_aliases_without_iaf core2_aliases_without_iaf
+#define kabylake_aliases core2_aliases
+#define kabylake_aliases_without_iaf core2_aliases_without_iaf
#define ivybridge_aliases core2_aliases
#define ivybridge_aliases_without_iaf core2_aliases_without_iaf
#define ivybridge_xeon_aliases core2_aliases
@@ -1049,7 +1079,8 @@
return (-1);
} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_SKYLAKE ||
- cpu_info.pm_cputype == PMC_CPU_INTEL_SKYLAKE_XEON) {
+ cpu_info.pm_cputype == PMC_CPU_INTEL_SKYLAKE_XEON ||
+ cpu_info.pm_cputype == PMC_CPU_INTEL_KABYLAKE) {
if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) {
n = pmc_parse_mask(iap_rsp_mask_skylake, p, &rsp);
} else
@@ -2495,6 +2526,84 @@
}
#endif
+#if defined(__amd64__)
+
+#define INTEL_PT_KW_BRANCHES "branches"
+#define INTEL_PT_KW_TSC "tsc"
+#define INTEL_PT_KW_MTC "mtc"
+#define INTEL_PT_KW_DISRETC "disretc"
+#define INTEL_PT_KW_ADDRA "addra"
+#define INTEL_PT_KW_ADDRB "addrb"
+
+static int
+pt_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ struct pmc_md_pt_op_pmcallocate *pm_pt;
+ uint64_t addr;
+ uint32_t addrn;
+ char *p, *q, *e;
+
+ if (pe != PMC_EV_PT_PT)
+ return (-1);
+
+ pm_pt = (struct pmc_md_pt_op_pmcallocate *)&pmc_config->pm_md.pm_pt;
+
+ addrn = 0;
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+ if (KWMATCH(p, INTEL_PT_KW_BRANCHES)) {
+ pm_pt->flags |= INTEL_PT_FLAG_BRANCHES;
+ }
+
+ if (KWMATCH(p, INTEL_PT_KW_TSC)) {
+ pm_pt->flags |= INTEL_PT_FLAG_TSC;
+ }
+
+ if (KWMATCH(p, INTEL_PT_KW_MTC)) {
+ pm_pt->flags |= INTEL_PT_FLAG_MTC;
+ }
+
+ if (KWMATCH(p, INTEL_PT_KW_DISRETC)) {
+ pm_pt->flags |= INTEL_PT_FLAG_DISRETC;
+ }
+
+ if (KWPREFIXMATCH(p, INTEL_PT_KW_ADDRA "=")) {
+ q = strchr(p, '=');
+ if (*++q == '\0') /* skip '=' */
+ return (-1);
+
+ addr = strtoul(q, &e, 0);
+ if (e == q || *e != '\0')
+ return (-1);
+ pm_pt->ranges[addrn * 2] = addr;
+ }
+
+ if (KWPREFIXMATCH(p, INTEL_PT_KW_ADDRB "=")) {
+ q = strchr(p, '=');
+ if (*++q == '\0') /* skip '=' */
+ return (-1);
+
+ addr = strtoul(q, &e, 0);
+ if (e == q || *e != '\0')
+ return (-1);
+ pm_pt->ranges[addrn * 2 + 1] = addr;
+
+ if (pm_pt->ranges[addrn * 2 + 1] < pm_pt->ranges[addrn * 2])
+ return (-1);
+ addrn += 1;
+ if (addrn > PT_NADDR)
+ return (-1);
+ }
+ };
+
+ pm_pt->nranges = addrn;
+
+ pmc_config->pm_caps |= PMC_CAP_READ;
+
+ return (0);
+}
+#endif
+
static struct pmc_event_alias generic_aliases[] = {
EV_ALIAS("instructions", "SOFT-CLOCK.HARD"),
EV_ALIAS(NULL, NULL)
@@ -2583,6 +2692,61 @@
return (0);
}
+
+#define ARM_CORESIGHT_KW_ADDRA "addra"
+#define ARM_CORESIGHT_KW_ADDRB "addrb"
+
+static int
+coresight_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ struct pmc_md_coresight_op_pmcallocate *pm_coresight;
+ uint64_t addr;
+ uint32_t addrn;
+ char *p, *q, *e;
+
+ if (pe != PMC_EV_CORESIGHT_CORESIGHT)
+ return (-1);
+
+ pm_coresight = (struct pmc_md_coresight_op_pmcallocate *)&pmc_config->pm_md.pm_coresight;
+
+ addrn = 0;
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+ if (KWPREFIXMATCH(p, ARM_CORESIGHT_KW_ADDRA "=")) {
+ q = strchr(p, '=');
+ if (*++q == '\0') /* skip '=' */
+ return (-1);
+
+ addr = strtoul(q, &e, 0);
+ if (e == q || *e != '\0')
+ return (-1);
+ pm_coresight->ranges[addrn * 2] = addr;
+ }
+
+ if (KWPREFIXMATCH(p, ARM_CORESIGHT_KW_ADDRB "=")) {
+ q = strchr(p, '=');
+ if (*++q == '\0') /* skip '=' */
+ return (-1);
+
+ addr = strtoul(q, &e, 0);
+ if (e == q || *e != '\0')
+ return (-1);
+ pm_coresight->ranges[addrn * 2 + 1] = addr;
+
+ if (pm_coresight->ranges[addrn * 2 + 1] < pm_coresight->ranges[addrn * 2])
+ return (-1);
+ addrn += 1;
+ if (addrn > CORESIGHT_NADDR)
+ return (-1);
+ }
+ };
+
+ pm_coresight->nranges = addrn;
+
+ pmc_config->pm_caps |= PMC_CAP_READ;
+
+ return (0);
+}
#endif
#if defined(__mips__)
@@ -2780,7 +2944,8 @@
retval = -1;
if (mode != PMC_MODE_SS && mode != PMC_MODE_TS &&
- mode != PMC_MODE_SC && mode != PMC_MODE_TC) {
+ mode != PMC_MODE_SC && mode != PMC_MODE_TC &&
+ mode != PMC_MODE_ST && mode != PMC_MODE_TT) {
errno = EINVAL;
goto out;
}
@@ -2903,6 +3068,7 @@
int
pmc_cpuinfo(const struct pmc_cpuinfo **pci)
{
+
if (pmc_syscall == -1) {
errno = ENXIO;
return (-1);
@@ -3023,6 +3189,10 @@
ev = skylake_xeon_event_table;
count = PMC_EVENT_TABLE_SIZE(skylake_xeon);
break;
+ case PMC_CPU_INTEL_KABYLAKE:
+ ev = kabylake_event_table;
+ count = PMC_EVENT_TABLE_SIZE(kabylake);
+ break;
case PMC_CPU_INTEL_IVYBRIDGE:
ev = ivybridge_event_table;
count = PMC_EVENT_TABLE_SIZE(ivybridge);
@@ -3086,6 +3256,10 @@
ev = tsc_event_table;
count = PMC_EVENT_TABLE_SIZE(tsc);
break;
+ case PMC_CLASS_PT:
+ ev = pt_event_table;
+ count = PMC_EVENT_TABLE_SIZE(pt);
+ break;
case PMC_CLASS_K7:
ev = k7_event_table;
count = PMC_EVENT_TABLE_SIZE(k7);
@@ -3136,6 +3310,10 @@
break;
}
break;
+ case PMC_CLASS_CORESIGHT:
+ ev = coresight_event_table;
+ count = PMC_EVENT_TABLE_SIZE(coresight);
+ break;
case PMC_CLASS_MIPS24K:
ev = mips24k_event_table;
count = PMC_EVENT_TABLE_SIZE(mips24k);
@@ -3184,12 +3362,14 @@
int
pmc_flush_logfile(void)
{
+
return (PMC_CALL(FLUSHLOG,0));
}
int
pmc_close_logfile(void)
{
+
return (PMC_CALL(CLOSELOG,0));
}
@@ -3406,6 +3586,12 @@
case PMC_CPU_INTEL_SKYLAKE_XEON:
PMC_MDEP_INIT_INTEL_V2(skylake_xeon);
break;
+ case PMC_CPU_INTEL_KABYLAKE:
+#if defined(__amd64__)
+ pmc_class_table[n++] = &pt_class_table_descr;
+#endif
+ PMC_MDEP_INIT_INTEL_V2(kabylake);
+ break;
case PMC_CPU_INTEL_IVYBRIDGE:
PMC_MDEP_INIT_INTEL_V2(ivybridge);
break;
@@ -3455,11 +3641,13 @@
#if defined(__aarch64__)
case PMC_CPU_ARMV8_CORTEX_A53:
PMC_MDEP_INIT(cortex_a53);
- pmc_class_table[n] = &cortex_a53_class_table_descr;
+ pmc_class_table[n++] = &cortex_a53_class_table_descr;
+ pmc_class_table[n++] = &coresight_class_table_descr;
break;
case PMC_CPU_ARMV8_CORTEX_A57:
PMC_MDEP_INIT(cortex_a57);
- pmc_class_table[n] = &cortex_a57_class_table_descr;
+ pmc_class_table[n++] = &cortex_a57_class_table_descr;
+ pmc_class_table[n++] = &coresight_class_table_descr;
break;
#endif
#if defined(__mips__)
@@ -3623,6 +3811,11 @@
evfence = skylake_xeon_event_table +
PMC_EVENT_TABLE_SIZE(skylake_xeon);
break;
+ case PMC_CPU_INTEL_KABYLAKE:
+ ev = kabylake_event_table;
+ evfence = kabylake_event_table +
+ PMC_EVENT_TABLE_SIZE(kabylake);
+ break;
case PMC_CPU_INTEL_IVYBRIDGE:
ev = ivybridge_event_table;
evfence = ivybridge_event_table + PMC_EVENT_TABLE_SIZE(ivybridge);
@@ -3715,6 +3908,9 @@
default: /* Unknown CPU type. */
break;
}
+ } else if (pe == PMC_EV_CORESIGHT_CORESIGHT) {
+ ev = coresight_event_table;
+ evfence = coresight_event_table + PMC_EVENT_TABLE_SIZE(coresight);
} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
ev = mips24k_event_table;
evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);
@@ -3736,6 +3932,9 @@
} else if (pe == PMC_EV_TSC_TSC) {
ev = tsc_event_table;
evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
+ } else if (pe == PMC_EV_PT_PT) {
+ ev = pt_event_table;
+ evfence = pt_event_table + PMC_EVENT_TABLE_SIZE(pt);
} else if ((int)pe >= PMC_EV_SOFT_FIRST && (int)pe <= PMC_EV_SOFT_LAST) {
ev = soft_event_table;
evfence = soft_event_table + soft_event_info.pm_nevent;
@@ -3852,6 +4051,68 @@
return (0);
}
+int
+pmc_proc_unsuspend(pmc_id_t pmc, pid_t pid)
+{
+ struct pmc_op_proc_unsuspend u;
+
+ u.pm_pmcid = pmc;
+ u.pm_pid = pid;
+
+ return (PMC_CALL(THREAD_UNSUSPEND, &u));
+}
+
+int
+pmc_read_trace(uint32_t cpu, pmc_id_t pmc,
+ pmc_value_t *cycle, pmc_value_t *offset)
+{
+ struct pmc_op_trace_read pmc_trace_read;
+
+ pmc_trace_read.pm_pmcid = pmc;
+ pmc_trace_read.pm_cpu = cpu;
+ pmc_trace_read.pm_cycle = 0;
+ pmc_trace_read.pm_offset = 0;
+
+ if (PMC_CALL(TRACE_READ, &pmc_trace_read) < 0)
+ return (-1);
+
+ *cycle = pmc_trace_read.pm_cycle;
+ *offset = pmc_trace_read.pm_offset;
+
+ return (0);
+}
+
+int
+pmc_trace_config(uint32_t cpu, pmc_id_t pmc,
+ uint64_t *ranges, uint32_t nranges)
+{
+ struct pmc_op_trace_config trc;
+
+ trc.pm_pmcid = pmc;
+ trc.pm_cpu = cpu;
+ trc.nranges = nranges;
+
+ if (nranges > PMC_FILTER_MAX_IP_RANGES)
+ return (-1);
+
+ memcpy(&trc.ranges, ranges, sizeof(uint64_t) * 2 * nranges);
+
+ if (PMC_CALL(TRACE_CONFIG, &trc) < 0)
+ return (-1);
+
+ return (0);
+}
+
+int
+pmc_log_kmap(pmc_id_t pmc)
+{
+ struct pmc_op_simple pmc_log_km;
+
+ pmc_log_km.pm_pmcid = pmc;
+
+ return (PMC_CALL(LOG_KERNEL_MAP, &pmc_log_km));
+}
+
int
pmc_release(pmc_id_t pmc)
{
Index: lib/libpmc/pmc.h
===================================================================
--- lib/libpmc/pmc.h
+++ lib/libpmc/pmc.h
@@ -77,6 +77,7 @@
int pmc_allocate(const char *_ctrspec, enum pmc_mode _mode, uint32_t _flags,
int _cpu, pmc_id_t *_pmcid);
int pmc_attach(pmc_id_t _pmcid, pid_t _pid);
+int pmc_proc_unsuspend(pmc_id_t pmc, pid_t pid);
int pmc_capabilities(pmc_id_t _pmc, uint32_t *_caps);
int pmc_configure_logfile(int _fd);
int pmc_flush_logfile(void);
@@ -88,7 +89,10 @@
int pmc_get_msr(pmc_id_t _pmc, uint32_t *_msr);
int pmc_init(void);
int pmc_read(pmc_id_t _pmc, pmc_value_t *_value);
+int pmc_read_trace(uint32_t cpu, pmc_id_t pmc, pmc_value_t *cycle, pmc_value_t *offset);
+int pmc_trace_config(uint32_t cpu, pmc_id_t pmc, uint64_t *ranges, uint32_t nranges);
int pmc_release(pmc_id_t _pmc);
+int pmc_log_kmap(pmc_id_t pmc);
int pmc_rw(pmc_id_t _pmc, pmc_value_t _newvalue, pmc_value_t *_oldvalue);
int pmc_set(pmc_id_t _pmc, pmc_value_t _value);
int pmc_start(pmc_id_t _pmc);
Index: sys/dev/hwpmc/pmc_events.h
===================================================================
--- sys/dev/hwpmc/pmc_events.h
+++ sys/dev/hwpmc/pmc_events.h
@@ -4843,6 +4843,20 @@
#define PMC_EV_TSC_FIRST PMC_EV_TSC_TSC
#define PMC_EV_TSC_LAST PMC_EV_TSC_TSC
+/* Intel PT */
+#define __PMC_EV_PT() \
+ __PMC_EV(PT, PT)
+
+#define PMC_EV_PT_FIRST PMC_EV_PT_PT
+#define PMC_EV_PT_LAST PMC_EV_PT_PT
+
+/* ARM CORESIGHT */
+#define __PMC_EV_CORESIGHT() \
+ __PMC_EV(CORESIGHT, CORESIGHT)
+
+#define PMC_EV_CORESIGHT_FIRST PMC_EV_CORESIGHT_CORESIGHT
+#define PMC_EV_CORESIGHT_LAST PMC_EV_CORESIGHT_CORESIGHT
+
/*
* Software events are dynamically defined.
*/
@@ -7141,6 +7155,7 @@
* START #EVENTS DESCRIPTION
* 0 0x1000 Reserved
* 0x1000 0x0001 TSC
+ * 0x1100 0x0001 PT
* 0x2000 0x0080 AMD K7 events
* 0x2080 0x0100 AMD K8 events
* 0x10000 0x0080 INTEL architectural fixed-function events
@@ -7157,11 +7172,14 @@
* 0x13300 0x00FF Freescale e500 events
* 0x14000 0x0100 ARMv7 events
* 0x14100 0x0100 ARMv8 events
+ * 0x14200 0x0001 ARM Coresight
* 0x20000 0x1000 Software events
*/
#define __PMC_EVENTS() \
__PMC_EV_BLOCK(TSC, 0x01000) \
__PMC_EV_TSC() \
+ __PMC_EV_BLOCK(PT, 0x1100) \
+ __PMC_EV_PT() \
__PMC_EV_BLOCK(K7, 0x2000) \
__PMC_EV_K7() \
__PMC_EV_BLOCK(K8, 0x2080) \
@@ -7197,7 +7215,9 @@
__PMC_EV_BLOCK(ARMV7, 0x14000) \
__PMC_EV_ARMV7() \
__PMC_EV_BLOCK(ARMV8, 0x14100) \
- __PMC_EV_ARMV8()
+ __PMC_EV_ARMV8() \
+ __PMC_EV_BLOCK(CORESIGHT, 0x14200) \
+ __PMC_EV_CORESIGHT()
#define PMC_EVENT_FIRST PMC_EV_TSC_TSC
#define PMC_EVENT_LAST PMC_EV_SOFT_LAST

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 7, 7:02 PM (14 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28458001
Default Alt Text
D15088.id42983.diff (15 KB)

Event Timeline