aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/perf_event_intel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event_intel.c')
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c78
1 files changed, 73 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index f31a1655d1ff..0fa4f242f050 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -190,9 +190,9 @@ static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
190 EVENT_EXTRA_END 190 EVENT_EXTRA_END
191}; 191};
192 192
193EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3"); 193EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
194EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3"); 194EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
195EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2"); 195EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
196 196
197struct attribute *nhm_events_attrs[] = { 197struct attribute *nhm_events_attrs[] = {
198 EVENT_PTR(mem_ld_nhm), 198 EVENT_PTR(mem_ld_nhm),
@@ -1184,6 +1184,11 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
1184 wrmsrl(hwc->config_base, ctrl_val); 1184 wrmsrl(hwc->config_base, ctrl_val);
1185} 1185}
1186 1186
1187static inline bool event_is_checkpointed(struct perf_event *event)
1188{
1189 return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0;
1190}
1191
1187static void intel_pmu_disable_event(struct perf_event *event) 1192static void intel_pmu_disable_event(struct perf_event *event)
1188{ 1193{
1189 struct hw_perf_event *hwc = &event->hw; 1194 struct hw_perf_event *hwc = &event->hw;
@@ -1197,6 +1202,7 @@ static void intel_pmu_disable_event(struct perf_event *event)
1197 1202
1198 cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx); 1203 cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
1199 cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx); 1204 cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
1205 cpuc->intel_cp_status &= ~(1ull << hwc->idx);
1200 1206
1201 /* 1207 /*
1202 * must disable before any actual event 1208 * must disable before any actual event
@@ -1271,6 +1277,9 @@ static void intel_pmu_enable_event(struct perf_event *event)
1271 if (event->attr.exclude_guest) 1277 if (event->attr.exclude_guest)
1272 cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx); 1278 cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
1273 1279
1280 if (unlikely(event_is_checkpointed(event)))
1281 cpuc->intel_cp_status |= (1ull << hwc->idx);
1282
1274 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 1283 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
1275 intel_pmu_enable_fixed(hwc); 1284 intel_pmu_enable_fixed(hwc);
1276 return; 1285 return;
@@ -1289,6 +1298,17 @@ static void intel_pmu_enable_event(struct perf_event *event)
1289int intel_pmu_save_and_restart(struct perf_event *event) 1298int intel_pmu_save_and_restart(struct perf_event *event)
1290{ 1299{
1291 x86_perf_event_update(event); 1300 x86_perf_event_update(event);
1301 /*
1302 * For a checkpointed counter always reset back to 0. This
1303 * avoids a situation where the counter overflows, aborts the
1304 * transaction and is then set back to shortly before the
1305 * overflow, and overflows and aborts again.
1306 */
1307 if (unlikely(event_is_checkpointed(event))) {
1308 /* No race with NMIs because the counter should not be armed */
1309 wrmsrl(event->hw.event_base, 0);
1310 local64_set(&event->hw.prev_count, 0);
1311 }
1292 return x86_perf_event_set_period(event); 1312 return x86_perf_event_set_period(event);
1293} 1313}
1294 1314
@@ -1372,6 +1392,13 @@ again:
1372 x86_pmu.drain_pebs(regs); 1392 x86_pmu.drain_pebs(regs);
1373 } 1393 }
1374 1394
1395 /*
1396 * Checkpointed counters can lead to 'spurious' PMIs because the
1397 * rollback caused by the PMI will have cleared the overflow status
1398 * bit. Therefore always force probe these counters.
1399 */
1400 status |= cpuc->intel_cp_status;
1401
1375 for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { 1402 for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
1376 struct perf_event *event = cpuc->events[bit]; 1403 struct perf_event *event = cpuc->events[bit];
1377 1404
@@ -1837,6 +1864,20 @@ static int hsw_hw_config(struct perf_event *event)
1837 event->attr.precise_ip > 0)) 1864 event->attr.precise_ip > 0))
1838 return -EOPNOTSUPP; 1865 return -EOPNOTSUPP;
1839 1866
1867 if (event_is_checkpointed(event)) {
1868 /*
1869 * Sampling of checkpointed events can cause situations where
1870 * the CPU constantly aborts because of a overflow, which is
1871 * then checkpointed back and ignored. Forbid checkpointing
1872 * for sampling.
1873 *
1874 * But still allow a long sampling period, so that perf stat
1875 * from KVM works.
1876 */
1877 if (event->attr.sample_period > 0 &&
1878 event->attr.sample_period < 0x7fffffff)
1879 return -EOPNOTSUPP;
1880 }
1840 return 0; 1881 return 0;
1841} 1882}
1842 1883
@@ -2182,10 +2223,36 @@ static __init void intel_nehalem_quirk(void)
2182 } 2223 }
2183} 2224}
2184 2225
2185EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3"); 2226EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3");
2186EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82") 2227EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82")
2228
2229/* Haswell special events */
2230EVENT_ATTR_STR(tx-start, tx_start, "event=0xc9,umask=0x1");
2231EVENT_ATTR_STR(tx-commit, tx_commit, "event=0xc9,umask=0x2");
2232EVENT_ATTR_STR(tx-abort, tx_abort, "event=0xc9,umask=0x4");
2233EVENT_ATTR_STR(tx-capacity, tx_capacity, "event=0x54,umask=0x2");
2234EVENT_ATTR_STR(tx-conflict, tx_conflict, "event=0x54,umask=0x1");
2235EVENT_ATTR_STR(el-start, el_start, "event=0xc8,umask=0x1");
2236EVENT_ATTR_STR(el-commit, el_commit, "event=0xc8,umask=0x2");
2237EVENT_ATTR_STR(el-abort, el_abort, "event=0xc8,umask=0x4");
2238EVENT_ATTR_STR(el-capacity, el_capacity, "event=0x54,umask=0x2");
2239EVENT_ATTR_STR(el-conflict, el_conflict, "event=0x54,umask=0x1");
2240EVENT_ATTR_STR(cycles-t, cycles_t, "event=0x3c,in_tx=1");
2241EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1");
2187 2242
2188static struct attribute *hsw_events_attrs[] = { 2243static struct attribute *hsw_events_attrs[] = {
2244 EVENT_PTR(tx_start),
2245 EVENT_PTR(tx_commit),
2246 EVENT_PTR(tx_abort),
2247 EVENT_PTR(tx_capacity),
2248 EVENT_PTR(tx_conflict),
2249 EVENT_PTR(el_start),
2250 EVENT_PTR(el_commit),
2251 EVENT_PTR(el_abort),
2252 EVENT_PTR(el_capacity),
2253 EVENT_PTR(el_conflict),
2254 EVENT_PTR(cycles_t),
2255 EVENT_PTR(cycles_ct),
2189 EVENT_PTR(mem_ld_hsw), 2256 EVENT_PTR(mem_ld_hsw),
2190 EVENT_PTR(mem_st_hsw), 2257 EVENT_PTR(mem_st_hsw),
2191 NULL 2258 NULL
@@ -2452,6 +2519,7 @@ __init int intel_pmu_init(void)
2452 x86_pmu.hw_config = hsw_hw_config; 2519 x86_pmu.hw_config = hsw_hw_config;
2453 x86_pmu.get_event_constraints = hsw_get_event_constraints; 2520 x86_pmu.get_event_constraints = hsw_get_event_constraints;
2454 x86_pmu.cpu_events = hsw_events_attrs; 2521 x86_pmu.cpu_events = hsw_events_attrs;
2522 x86_pmu.lbr_double_abort = true;
2455 pr_cont("Haswell events, "); 2523 pr_cont("Haswell events, ");
2456 break; 2524 break;
2457 2525