aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2018-09-06 09:57:48 -0400
committerIngo Molnar <mingo@kernel.org>2018-10-16 11:29:07 -0400
commitd4ae552982de39417d17f823df1f06b1cbc3686c (patch)
treebe9ce80570d669eee28ee4d9ed7ba7216f2a2192
parentf703fd374ef8fb06e46713b326d255e20d6278ad (diff)
perf/x86/intel: Export mem events only if there's PEBS support
Memory events depends on PEBS support and access to LDLAT MSR, but we display them in /sys/devices/cpu/events even if the CPU does not provide those, like for KVM guests. That brings the false assumption that those events should be available, while they fail event to open. Separating the mem-* events attributes and merging them with cpu_events only if there's PEBS support detected. We could also check if LDLAT MSR is available, but the PEBS check seems to cover the need now. Suggested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Link: http://lkml.kernel.org/r/20180906135748.GC9577@krava Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/events/core.c8
-rw-r--r--arch/x86/events/intel/core.c69
2 files changed, 56 insertions, 21 deletions
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 06b708494898..de32741d041a 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1652,9 +1652,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
1652 struct attribute **new; 1652 struct attribute **new;
1653 int j, i; 1653 int j, i;
1654 1654
1655 for (j = 0; a[j]; j++) 1655 for (j = 0; a && a[j]; j++)
1656 ; 1656 ;
1657 for (i = 0; b[i]; i++) 1657 for (i = 0; b && b[i]; i++)
1658 j++; 1658 j++;
1659 j++; 1659 j++;
1660 1660
@@ -1663,9 +1663,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
1663 return NULL; 1663 return NULL;
1664 1664
1665 j = 0; 1665 j = 0;
1666 for (i = 0; a[i]; i++) 1666 for (i = 0; a && a[i]; i++)
1667 new[j++] = a[i]; 1667 new[j++] = a[i];
1668 for (i = 0; b[i]; i++) 1668 for (i = 0; b && b[i]; i++)
1669 new[j++] = b[i]; 1669 new[j++] = b[i];
1670 new[j] = NULL; 1670 new[j] = NULL;
1671 1671
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index ab01ef9ddd77..0fb8659b20d8 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -242,7 +242,7 @@ EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
242EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3"); 242EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
243EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2"); 243EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
244 244
245static struct attribute *nhm_events_attrs[] = { 245static struct attribute *nhm_mem_events_attrs[] = {
246 EVENT_PTR(mem_ld_nhm), 246 EVENT_PTR(mem_ld_nhm),
247 NULL, 247 NULL,
248}; 248};
@@ -278,8 +278,6 @@ EVENT_ATTR_STR_HT(topdown-recovery-bubbles.scale, td_recovery_bubbles_scale,
278 "4", "2"); 278 "4", "2");
279 279
280static struct attribute *snb_events_attrs[] = { 280static struct attribute *snb_events_attrs[] = {
281 EVENT_PTR(mem_ld_snb),
282 EVENT_PTR(mem_st_snb),
283 EVENT_PTR(td_slots_issued), 281 EVENT_PTR(td_slots_issued),
284 EVENT_PTR(td_slots_retired), 282 EVENT_PTR(td_slots_retired),
285 EVENT_PTR(td_fetch_bubbles), 283 EVENT_PTR(td_fetch_bubbles),
@@ -290,6 +288,12 @@ static struct attribute *snb_events_attrs[] = {
290 NULL, 288 NULL,
291}; 289};
292 290
291static struct attribute *snb_mem_events_attrs[] = {
292 EVENT_PTR(mem_ld_snb),
293 EVENT_PTR(mem_st_snb),
294 NULL,
295};
296
293static struct event_constraint intel_hsw_event_constraints[] = { 297static struct event_constraint intel_hsw_event_constraints[] = {
294 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 298 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
295 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 299 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -3912,8 +3916,6 @@ EVENT_ATTR_STR(cycles-t, cycles_t, "event=0x3c,in_tx=1");
3912EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1"); 3916EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1");
3913 3917
3914static struct attribute *hsw_events_attrs[] = { 3918static struct attribute *hsw_events_attrs[] = {
3915 EVENT_PTR(mem_ld_hsw),
3916 EVENT_PTR(mem_st_hsw),
3917 EVENT_PTR(td_slots_issued), 3919 EVENT_PTR(td_slots_issued),
3918 EVENT_PTR(td_slots_retired), 3920 EVENT_PTR(td_slots_retired),
3919 EVENT_PTR(td_fetch_bubbles), 3921 EVENT_PTR(td_fetch_bubbles),
@@ -3924,6 +3926,12 @@ static struct attribute *hsw_events_attrs[] = {
3924 NULL 3926 NULL
3925}; 3927};
3926 3928
3929static struct attribute *hsw_mem_events_attrs[] = {
3930 EVENT_PTR(mem_ld_hsw),
3931 EVENT_PTR(mem_st_hsw),
3932 NULL,
3933};
3934
3927static struct attribute *hsw_tsx_events_attrs[] = { 3935static struct attribute *hsw_tsx_events_attrs[] = {
3928 EVENT_PTR(tx_start), 3936 EVENT_PTR(tx_start),
3929 EVENT_PTR(tx_commit), 3937 EVENT_PTR(tx_commit),
@@ -3940,13 +3948,6 @@ static struct attribute *hsw_tsx_events_attrs[] = {
3940 NULL 3948 NULL
3941}; 3949};
3942 3950
3943static __init struct attribute **get_hsw_events_attrs(void)
3944{
3945 return boot_cpu_has(X86_FEATURE_RTM) ?
3946 merge_attr(hsw_events_attrs, hsw_tsx_events_attrs) :
3947 hsw_events_attrs;
3948}
3949
3950static ssize_t freeze_on_smi_show(struct device *cdev, 3951static ssize_t freeze_on_smi_show(struct device *cdev,
3951 struct device_attribute *attr, 3952 struct device_attribute *attr,
3952 char *buf) 3953 char *buf)
@@ -4023,9 +4024,32 @@ static struct attribute *intel_pmu_attrs[] = {
4023 NULL, 4024 NULL,
4024}; 4025};
4025 4026
4027static __init struct attribute **
4028get_events_attrs(struct attribute **base,
4029 struct attribute **mem,
4030 struct attribute **tsx)
4031{
4032 struct attribute **attrs = base;
4033 struct attribute **old;
4034
4035 if (mem && x86_pmu.pebs)
4036 attrs = merge_attr(attrs, mem);
4037
4038 if (tsx && boot_cpu_has(X86_FEATURE_RTM)) {
4039 old = attrs;
4040 attrs = merge_attr(attrs, tsx);
4041 if (old != base)
4042 kfree(old);
4043 }
4044
4045 return attrs;
4046}
4047
4026__init int intel_pmu_init(void) 4048__init int intel_pmu_init(void)
4027{ 4049{
4028 struct attribute **extra_attr = NULL; 4050 struct attribute **extra_attr = NULL;
4051 struct attribute **mem_attr = NULL;
4052 struct attribute **tsx_attr = NULL;
4029 struct attribute **to_free = NULL; 4053 struct attribute **to_free = NULL;
4030 union cpuid10_edx edx; 4054 union cpuid10_edx edx;
4031 union cpuid10_eax eax; 4055 union cpuid10_eax eax;
@@ -4137,7 +4161,7 @@ __init int intel_pmu_init(void)
4137 x86_pmu.enable_all = intel_pmu_nhm_enable_all; 4161 x86_pmu.enable_all = intel_pmu_nhm_enable_all;
4138 x86_pmu.extra_regs = intel_nehalem_extra_regs; 4162 x86_pmu.extra_regs = intel_nehalem_extra_regs;
4139 4163
4140 x86_pmu.cpu_events = nhm_events_attrs; 4164 mem_attr = nhm_mem_events_attrs;
4141 4165
4142 /* UOPS_ISSUED.STALLED_CYCLES */ 4166 /* UOPS_ISSUED.STALLED_CYCLES */
4143 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 4167 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
@@ -4266,7 +4290,7 @@ __init int intel_pmu_init(void)
4266 x86_pmu.extra_regs = intel_westmere_extra_regs; 4290 x86_pmu.extra_regs = intel_westmere_extra_regs;
4267 x86_pmu.flags |= PMU_FL_HAS_RSP_1; 4291 x86_pmu.flags |= PMU_FL_HAS_RSP_1;
4268 4292
4269 x86_pmu.cpu_events = nhm_events_attrs; 4293 mem_attr = nhm_mem_events_attrs;
4270 4294
4271 /* UOPS_ISSUED.STALLED_CYCLES */ 4295 /* UOPS_ISSUED.STALLED_CYCLES */
4272 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 4296 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
@@ -4306,6 +4330,7 @@ __init int intel_pmu_init(void)
4306 x86_pmu.flags |= PMU_FL_NO_HT_SHARING; 4330 x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
4307 4331
4308 x86_pmu.cpu_events = snb_events_attrs; 4332 x86_pmu.cpu_events = snb_events_attrs;
4333 mem_attr = snb_mem_events_attrs;
4309 4334
4310 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ 4335 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
4311 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 4336 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
@@ -4346,6 +4371,7 @@ __init int intel_pmu_init(void)
4346 x86_pmu.flags |= PMU_FL_NO_HT_SHARING; 4371 x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
4347 4372
4348 x86_pmu.cpu_events = snb_events_attrs; 4373 x86_pmu.cpu_events = snb_events_attrs;
4374 mem_attr = snb_mem_events_attrs;
4349 4375
4350 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ 4376 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
4351 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 4377 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
@@ -4380,10 +4406,12 @@ __init int intel_pmu_init(void)
4380 4406
4381 x86_pmu.hw_config = hsw_hw_config; 4407 x86_pmu.hw_config = hsw_hw_config;
4382 x86_pmu.get_event_constraints = hsw_get_event_constraints; 4408 x86_pmu.get_event_constraints = hsw_get_event_constraints;
4383 x86_pmu.cpu_events = get_hsw_events_attrs(); 4409 x86_pmu.cpu_events = hsw_events_attrs;
4384 x86_pmu.lbr_double_abort = true; 4410 x86_pmu.lbr_double_abort = true;
4385 extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? 4411 extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
4386 hsw_format_attr : nhm_format_attr; 4412 hsw_format_attr : nhm_format_attr;
4413 mem_attr = hsw_mem_events_attrs;
4414 tsx_attr = hsw_tsx_events_attrs;
4387 pr_cont("Haswell events, "); 4415 pr_cont("Haswell events, ");
4388 name = "haswell"; 4416 name = "haswell";
4389 break; 4417 break;
@@ -4419,10 +4447,12 @@ __init int intel_pmu_init(void)
4419 4447
4420 x86_pmu.hw_config = hsw_hw_config; 4448 x86_pmu.hw_config = hsw_hw_config;
4421 x86_pmu.get_event_constraints = hsw_get_event_constraints; 4449 x86_pmu.get_event_constraints = hsw_get_event_constraints;
4422 x86_pmu.cpu_events = get_hsw_events_attrs(); 4450 x86_pmu.cpu_events = hsw_events_attrs;
4423 x86_pmu.limit_period = bdw_limit_period; 4451 x86_pmu.limit_period = bdw_limit_period;
4424 extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? 4452 extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
4425 hsw_format_attr : nhm_format_attr; 4453 hsw_format_attr : nhm_format_attr;
4454 mem_attr = hsw_mem_events_attrs;
4455 tsx_attr = hsw_tsx_events_attrs;
4426 pr_cont("Broadwell events, "); 4456 pr_cont("Broadwell events, ");
4427 name = "broadwell"; 4457 name = "broadwell";
4428 break; 4458 break;
@@ -4478,7 +4508,9 @@ __init int intel_pmu_init(void)
4478 hsw_format_attr : nhm_format_attr; 4508 hsw_format_attr : nhm_format_attr;
4479 extra_attr = merge_attr(extra_attr, skl_format_attr); 4509 extra_attr = merge_attr(extra_attr, skl_format_attr);
4480 to_free = extra_attr; 4510 to_free = extra_attr;
4481 x86_pmu.cpu_events = get_hsw_events_attrs(); 4511 x86_pmu.cpu_events = hsw_events_attrs;
4512 mem_attr = hsw_mem_events_attrs;
4513 tsx_attr = hsw_tsx_events_attrs;
4482 intel_pmu_pebs_data_source_skl( 4514 intel_pmu_pebs_data_source_skl(
4483 boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); 4515 boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X);
4484 pr_cont("Skylake events, "); 4516 pr_cont("Skylake events, ");
@@ -4511,6 +4543,9 @@ __init int intel_pmu_init(void)
4511 WARN_ON(!x86_pmu.format_attrs); 4543 WARN_ON(!x86_pmu.format_attrs);
4512 } 4544 }
4513 4545
4546 x86_pmu.cpu_events = get_events_attrs(x86_pmu.cpu_events,
4547 mem_attr, tsx_attr);
4548
4514 if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { 4549 if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) {
4515 WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", 4550 WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
4516 x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC); 4551 x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);