Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf/x86/intel: Add simple Haswell PMU support

Similar to SandyBridge, but has a few new events and two
new counter bits.

There are some new counter flags that need to be prevented
from being set on fixed counters, and allowed to be set
for generic counters.

Also we add support for the counter 2 constraint to handle
all raw events.

(Contains fixes from Stephane Eranian.)

Reviewed-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Cc: Andi Kleen <ak@linux.jf.intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: http://lkml.kernel.org/r/1371515812-9646-3-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andi Kleen and committed by
Ingo Molnar
3a632cb2 130768b8

+91 -2
+3
arch/x86/include/asm/perf_event.h
··· 29 29 #define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23) 30 30 #define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL 31 31 32 + #define HSW_IN_TX (1ULL << 32) 33 + #define HSW_IN_TX_CHECKPOINTED (1ULL << 33) 34 + 32 35 #define AMD64_EVENTSEL_INT_CORE_ENABLE (1ULL << 36) 33 36 #define AMD64_EVENTSEL_GUESTONLY (1ULL << 40) 34 37 #define AMD64_EVENTSEL_HOSTONLY (1ULL << 41)
+4 -1
arch/x86/kernel/cpu/perf_event.h
··· 227 227 * - inv 228 228 * - edge 229 229 * - cnt-mask 230 + * - in_tx 231 + * - in_tx_checkpointed 230 232 * The other filters are supported by fixed counters. 231 233 * The any-thread option is supported starting with v3. 232 234 */ 235 + #define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED) 233 236 #define FIXED_EVENT_CONSTRAINT(c, n) \ 234 - EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK) 237 + EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS) 235 238 236 239 /* 237 240 * Constraint on the Event code + UMask
+84 -1
arch/x86/kernel/cpu/perf_event_intel.c
··· 13 13 #include <linux/slab.h> 14 14 #include <linux/export.h> 15 15 16 + #include <asm/cpufeature.h> 16 17 #include <asm/hardirq.h> 17 18 #include <asm/apic.h> 18 19 ··· 189 188 EVENT_PTR(mem_ld_snb), 190 189 EVENT_PTR(mem_st_snb), 191 190 NULL, 191 + }; 192 + 193 + static struct event_constraint intel_hsw_event_constraints[] = { 194 + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 195 + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 196 + FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ 197 + INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.* */ 198 + INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ 199 + INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ 200 + /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */ 201 + INTEL_EVENT_CONSTRAINT(0x08a3, 0x4), 202 + /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */ 203 + INTEL_EVENT_CONSTRAINT(0x0ca3, 0x4), 204 + /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */ 205 + INTEL_EVENT_CONSTRAINT(0x04a3, 0xf), 206 + EVENT_CONSTRAINT_END 192 207 }; 193 208 194 209 static u64 intel_pmu_event_map(int hw_event) ··· 1667 1650 } 1668 1651 } 1669 1652 1653 + static int hsw_hw_config(struct perf_event *event) 1654 + { 1655 + int ret = intel_pmu_hw_config(event); 1656 + 1657 + if (ret) 1658 + return ret; 1659 + if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE)) 1660 + return 0; 1661 + event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED); 1662 + 1663 + /* 1664 + * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with 1665 + * PEBS or in ANY thread mode. Since the results are non-sensical forbid 1666 + * this combination. 1667 + */ 1668 + if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) && 1669 + ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) || 1670 + event->attr.precise_ip > 0)) 1671 + return -EOPNOTSUPP; 1672 + 1673 + return 0; 1674 + } 1675 + 1676 + static struct event_constraint counter2_constraint = 1677 + EVENT_CONSTRAINT(0, 0x4, 0); 1678 + 1679 + static struct event_constraint * 1680 + hsw_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) 1681 + { 1682 + struct event_constraint *c = intel_get_event_constraints(cpuc, event); 1683 + 1684 + /* Handle special quirk on in_tx_checkpointed only in counter 2 */ 1685 + if (event->hw.config & HSW_IN_TX_CHECKPOINTED) { 1686 + if (c->idxmsk64 & (1U << 2)) 1687 + return &counter2_constraint; 1688 + return &emptyconstraint; 1689 + } 1690 + 1691 + return c; 1692 + } 1693 + 1670 1694 PMU_FORMAT_ATTR(event, "config:0-7" ); 1671 1695 PMU_FORMAT_ATTR(umask, "config:8-15" ); 1672 1696 PMU_FORMAT_ATTR(edge, "config:18" ); ··· 1715 1657 PMU_FORMAT_ATTR(any, "config:21" ); /* v3 + */ 1716 1658 PMU_FORMAT_ATTR(inv, "config:23" ); 1717 1659 PMU_FORMAT_ATTR(cmask, "config:24-31" ); 1660 + PMU_FORMAT_ATTR(in_tx, "config:32"); 1661 + PMU_FORMAT_ATTR(in_tx_cp, "config:33"); 1718 1662 1719 1663 static struct attribute *intel_arch_formats_attr[] = { 1720 1664 &format_attr_event.attr, ··· 1871 1811 &format_attr_any.attr, 1872 1812 &format_attr_inv.attr, 1873 1813 &format_attr_cmask.attr, 1814 + &format_attr_in_tx.attr, 1815 + &format_attr_in_tx_cp.attr, 1874 1816 1875 1817 &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ 1876 1818 &format_attr_ldlat.attr, /* PEBS load latency */ ··· 2255 2193 break; 2256 2194 2257 2195 2196 + case 60: /* Haswell Client */ 2197 + case 70: 2198 + case 71: 2199 + case 63: 2200 + memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); 2201 + memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); 2202 + 2203 + intel_pmu_lbr_init_snb(); 2204 + 2205 + x86_pmu.event_constraints = intel_hsw_event_constraints; 2206 + 2207 + x86_pmu.extra_regs = intel_snb_extra_regs; 2208 + /* all extra regs are per-cpu when HT is on */ 2209 + x86_pmu.er_flags |= ERF_HAS_RSP_1; 2210 + x86_pmu.er_flags |= ERF_NO_HT_SHARING; 2211 + 2212 + x86_pmu.hw_config = hsw_hw_config; 2213 + x86_pmu.get_event_constraints = hsw_get_event_constraints; 2214 + pr_cont("Haswell events, "); 2215 + break; 2216 + 2258 2217 default: 2259 2218 switch (x86_pmu.version) { 2260 2219 case 1: ··· 2314 2231 * counter, so do not extend mask to generic counters 2315 2232 */ 2316 2233 for_each_event_constraint(c, x86_pmu.event_constraints) { 2317 - if (c->cmask != X86_RAW_EVENT_MASK 2234 + if (c->cmask != FIXED_EVENT_FLAGS 2318 2235 || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) { 2319 2236 continue; 2320 2237 }