perf/x86/intel: Export mem events only if there's PEBs support
Subsystems (2)
Jiri Olsa
reviewerRFC 1/1 perf/x86/intel: Export mem events only if there's PEBs support
hi,
we had some reports that we show mem* events on KVM servers where they are not available, this patch hides them if there's no PEBs available
currently on those servers we fail to open mem* events, because we can't access LDLAT msr
however that's not so easy/straight forward to check, so I thought we could use check on PEBs instead, which needs to be there for mem events as well and seems to be enough to check
thoughts? thanks,
jirka
---
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.
--- arch/x86/events/core.c | 8 +++--- arch/x86/events/intel/core.c | 54 ++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 18 deletions(-)
arch/x86/events/core.c +4 -4
@@ -1631,9 +1631,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)struct attribute **new;int j, i; -for (j =0 ; a[j]; j++) +for (j =0 ; a && a[j]; j++) ; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) j++; j++;
@@ -1642,9 +1642,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)return NULL ; j =0 ; -for (i =0 ; a[i]; i++) +for (i =0 ; a && a[i]; i++) new[j++] = a[i]; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) new[j++] = b[i]; new[j] =NULL ;
arch/x86/events/intel/core.c +40 -14
152 lines not on this page · raw message
Signature · 1 line
2.17.1
Quoted 8 lines · Jiri Olsa
hi,
we had some reports that we show mem* events on KVM servers where they are not available, this patch hides them if there's no PEBs availablecurrently on those servers we fail to open mem* events, because we can't access LDLAT msr
Quoted 7 lines
however that's not so easy/straight forward to check, so I thought we could use check on PEBs instead, which needs to be there for mem events as well and seems to be enough to check
thoughts? thanks,
jirka
-Andi
PATCH 1/1 perf/x86/intel: Export mem events only if there's PEBs support
In reply to Jiri OlsaMemory 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.
--- arch/x86/events/core.c | 8 +++--- arch/x86/events/intel/core.c | 54 ++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 18 deletions(-)
arch/x86/events/core.c +4 -4
@@ -1631,9 +1631,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)struct attribute **new;int j, i; -for (j =0 ; a[j]; j++) +for (j =0 ; a && a[j]; j++) ; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) j++; j++;
@@ -1642,9 +1642,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)return NULL ; j =0 ; -for (i =0 ; a[i]; i++) +for (i =0 ; a && a[i]; i++) new[j++] = a[i]; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) new[j++] = b[i]; new[j] =NULL ;
arch/x86/events/intel/core.c +40 -14
152 lines not on this page · raw message
Signature · 1 line
2.17.1
Peter Zijlstra
maintainerQuoted 17 lines · Jiri Olsa
arch/x86/events/intel/core.c +8
-0+static __init struct attribute **get_hsw_events_attrs (bool *alloc) { +if (boot_cpu_has (X86_FEATURE_RTM )) { + *alloc = true; +return merge_attr (hsw_events_attrs, hsw_tsx_events_attrs); + } +return hsw_events_attrs; }@@ -4357,6 +4374,15 @@ __init int intel_pmu_init(void)WARN_ON (!x86_pmu.format_attrs); } +if (x86_pmu.pebs && mem_attr) { +struct attribute **attr = x86_pmu.cpu_events;
arch/x86/events/intel/core.c __init int intel_pmu_init(void) · line 4388
Quoted 10 lines
arch/x86/events/intel/core.c +7
-0+ + x86_pmu.cpu_events =merge_attr (x86_pmu.cpu_events, mem_attr); + +if (alloc_events) +kfree (attr); + } +if (x86_pmu.num_counters >INTEL_PMC_MAX_GENERIC ) {WARN (1 ,KERN_ERR "hw perf events %d > max(%d), clipping!" , x86_pmu.num_counters,INTEL_PMC_MAX_GENERIC );
static __init struct attribute **
get_events_attrs(struct attribute **base,
struct attribute **mem,
struct attribute **tsx)
{
struct attribute **attrs = base;
struct attribute **old;
if (mem) {
old = attrs;
attrs = merge_attrs(attrs, mem);
if (old != base)
kfree(old);
}
if (tsx && boot_cpu_has(X86_FEATURE_RTM)) {
old = attrs;
attrs = merge_attrs(attrs, tsx);
if (old != base)
kfree(old);
}
return attrs;
}Would that not help to concentrate things a little more?
Quoted 55 lines · Peter Zijlstra
Quoted 17 lines · Jiri Olsa
arch/x86/events/intel/core.c +8
-0+static __init struct attribute **get_hsw_events_attrs (bool *alloc) { +if (boot_cpu_has (X86_FEATURE_RTM )) { + *alloc = true; +return merge_attr (hsw_events_attrs, hsw_tsx_events_attrs); + } +return hsw_events_attrs; }@@ -4357,6 +4374,15 @@ __init int intel_pmu_init(void)WARN_ON (!x86_pmu.format_attrs); } +if (x86_pmu.pebs && mem_attr) { +struct attribute **attr = x86_pmu.cpu_events;arch/x86/events/intel/core.c __init int intel_pmu_init(void) · line 4388
Quoted 10 lines
arch/x86/events/intel/core.c +7
-0+ + x86_pmu.cpu_events =merge_attr (x86_pmu.cpu_events, mem_attr); + +if (alloc_events) +kfree (attr); + } +if (x86_pmu.num_counters >INTEL_PMC_MAX_GENERIC ) {WARN (1 ,KERN_ERR "hw perf events %d > max(%d), clipping!" , x86_pmu.num_counters,INTEL_PMC_MAX_GENERIC );static
__initstruct attribute **
get_events_attrs(struct attribute **base,
struct attribute **mem,
struct attribute **tsx){ struct attribute **attrs = base; struct attribute **old; if (mem) { old = attrs; attrs = merge_attrs(attrs, mem); if (old != base) kfree(old); } if (tsx && boot_cpu_has(X86_FEATURE_RTM)) { old = attrs; attrs = merge_attrs(attrs, tsx); if (old != base) kfree(old); } return attrs; }
Quoted 1 line
Would that not help to concentrate things a little more?
looks like it would ;-) will check and repost
thanks,
jirka
Quoted 53 lines · Jiri Olsa
Quoted 52 lines · Peter Zijlstra
Quoted 17 lines · Jiri Olsa
(quoted diff) +8
-0+static __init struct attribute **get_hsw_events_attrs(bool *alloc) { + if (boot_cpu_has(X86_FEATURE_RTM)) { + *alloc = true; + return merge_attr(hsw_events_attrs, hsw_tsx_events_attrs); + } + return hsw_events_attrs; }@@ -4357,6 +4374,15 @@ __init int intel_pmu_init(void) WARN_ON(!x86_pmu.format_attrs); } + if (x86_pmu.pebs && mem_attr) { + struct attribute **attr = x86_pmu.cpu_events;Review __init int intel_pmu_init(void) · line 4388
Quoted 10 lines
(quoted diff) +7
-0+ + x86_pmu.cpu_events = merge_attr(x86_pmu.cpu_events, mem_attr); + + if (alloc_events) + kfree(attr); + } + if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);static
__initstruct attribute **
get_events_attrs(struct attribute **base,
struct attribute **mem,
struct attribute **tsx){ struct attribute **attrs = base; struct attribute **old; if (mem) { old = attrs; attrs = merge_attrs(attrs, mem); if (old != base) kfree(old); } if (tsx && boot_cpu_has(X86_FEATURE_RTM)) { old = attrs; attrs = merge_attrs(attrs, tsx); if (old != base) kfree(old); }
Quoted 6 lines
Quoted 4 lines
return attrs; }Would that not help to concentrate things a little more?
looks like it would ;-) will check and repost
new version attached.. Michael tested on several machines, but I couldn't find haswell with working tsx, to test that those events are displayed
thanks,
jirka
---
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.
--- arch/x86/events/core.c | 8 ++--- arch/x86/events/intel/core.c | 69 +++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 21 deletions(-)
arch/x86/events/core.c +4 -4
@@ -1631,9 +1631,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)struct attribute **new;int j, i; -for (j =0 ; a[j]; j++) +for (j =0 ; a && a[j]; j++) ; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) j++; j++;
@@ -1642,9 +1642,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)return NULL ; j =0 ; -for (i =0 ; a[i]; i++) +for (i =0 ; a && a[i]; i++) new[j++] = a[i]; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) new[j++] = b[i]; new[j] =NULL ;
arch/x86/events/intel/core.c +52 -17
168 lines not on this page · raw message
Signature · 1 line
2.17.1
On Thu, Sep 06, 2018 at 03:57:48PM +0200, Jiri Olsa wrote:
SNIP
Quoted 8 lines
Quoted 1 line
looks like it would ;-) will check and repost
new version attached.. Michael tested on several machines, but I couldn't find haswell with working tsx, to test that those events are displayed
thanks,
jirka
ping
jirka
Quoted 241 lines
---
Memory events depends on PEBs support and access to LDLAT msr, but we display them in/sys/devices/cpu/eventseven 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_eventsonly 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 <[email protected]>Signed-off-by Jiri Olsa <[email protected]>--- arch/x86/events/core.c | 8 ++--- arch/x86/events/intel/core.c | 69 +++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 21 deletions(-)arch/x86/events/core.c +4
-4@@ -1631,9 +1631,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)struct attribute **new;int j, i; -for (j =0 ; a[j]; j++) +for (j =0 ; a && a[j]; j++) ; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) j++; j++;@@ -1642,9 +1642,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)return NULL ; j =0 ; -for (i =0 ; a[i]; i++) +for (i =0 ; a && a[i]; i++) new[j++] = a[i]; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) new[j++] = b[i]; new[j] =NULL ;arch/x86/events/intel/core.c +52
-17@@ -242,7 +242,7 @@ EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");EVENT_ATTR_STR (mem-loads, mem_ld_snb,"event=0xcd,umask=0x1,ldlat=3" );EVENT_ATTR_STR (mem-stores, mem_st_snb,"event=0xcd,umask=0x2" ); -static struct attribute *nhm_events_attrs[] = { +static struct attribute *nhm_mem_events_attrs[] = {EVENT_PTR (mem_ld_nhm),NULL , };@@ -278,8 +278,6 @@ EVENT_ATTR_STR_HT(topdown-recovery-bubbles.scale, td_recovery_bubbles_scale, "4", "2");static struct attribute *snb_events_attrs[] = { -EVENT_PTR (mem_ld_snb), -EVENT_PTR (mem_st_snb),EVENT_PTR (td_slots_issued),EVENT_PTR (td_slots_retired),EVENT_PTR (td_fetch_bubbles),@@ -290,6 +288,12 @@ static struct attribute *snb_events_attrs[] = { NULL, }; +static struct attribute *snb_mem_events_attrs[] = { +EVENT_PTR (mem_ld_snb), +EVENT_PTR (mem_st_snb), +NULL , +}; +static struct event_constraint intel_hsw_event_constraints[] = {FIXED_EVENT_CONSTRAINT (0x00c0 ,0 ),/* INST_RETIRED.ANY */ FIXED_EVENT_CONSTRAINT (0x003c ,1 ),/* CPU_CLK_UNHALTED.CORE */ @@ -3764,8 +3768,6 @@ EVENT_ATTR_STR(cycles-t, cycles_t, "event=0x3c,in_tx=1");EVENT_ATTR_STR (cycles-ct, cycles_ct,"event=0x3c,in_tx=1,in_tx_cp=1" );static struct attribute *hsw_events_attrs[] = { -EVENT_PTR (mem_ld_hsw), -EVENT_PTR (mem_st_hsw),EVENT_PTR (td_slots_issued),EVENT_PTR (td_slots_retired),EVENT_PTR (td_fetch_bubbles),@@ -3776,6 +3778,12 @@ static struct attribute *hsw_events_attrs[] = {NULL }; +static struct attribute *hsw_mem_events_attrs[] = { +EVENT_PTR (mem_ld_hsw), +EVENT_PTR (mem_st_hsw), +NULL , +}; +static struct attribute *hsw_tsx_events_attrs[] = {EVENT_PTR (tx_start),EVENT_PTR (tx_commit),@@ -3792,13 +3800,6 @@ static struct attribute *hsw_tsx_events_attrs[] = { NULL }; -static __init struct attribute **get_hsw_events_attrs (void ) -{ -return boot_cpu_has (X86_FEATURE_RTM ) ? -merge_attr (hsw_events_attrs, hsw_tsx_events_attrs) : - hsw_events_attrs; -} -static ssize_t freeze_on_smi_show (struct device *cdev,struct device_attribute *attr,char *buf)@@ -3875,9 +3876,32 @@ static struct attribute *intel_pmu_attrs[] = { NULL, }; +static __init struct attribute ** +get_events_attrs (struct attribute **base, +struct attribute **mem, +struct attribute **tsx) +{ +struct attribute **attrs = base; +struct attribute **old; + +if (mem && x86_pmu.pebs) + attrs =merge_attr (attrs, mem); + +if (tsx &&boot_cpu_has (X86_FEATURE_RTM )) { + old = attrs; + attrs =merge_attr (attrs, tsx); +if (old != base) +kfree (old); + } + +return attrs; +} +__init int intel_pmu_init (void ) {struct attribute **extra_attr =NULL ; +struct attribute **mem_attr =NULL ; +struct attribute **tsx_attr =NULL ;struct attribute **to_free =NULL ;union cpuid10_edx edx;union cpuid10_eax eax;@@ -3986,7 +4010,7 @@ __init int intel_pmu_init(void) x86_pmu.enable_all = intel_pmu_nhm_enable_all; x86_pmu.extra_regs = intel_nehalem_extra_regs; - x86_pmu.cpu_events = nhm_events_attrs; + mem_attr = nhm_mem_events_attrs;/* UOPS_ISSUED.STALLED_CYCLES */ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =@@ -4112,7 +4136,7 @@ __init int intel_pmu_init(void) x86_pmu.extra_regs = intel_westmere_extra_regs; x86_pmu.flags |=PMU_FL_HAS_RSP_1 ; - x86_pmu.cpu_events = nhm_events_attrs; + mem_attr = nhm_mem_events_attrs;/* UOPS_ISSUED.STALLED_CYCLES */ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =@@ -4152,6 +4176,7 @@ __init int intel_pmu_init(void) x86_pmu.flags |=PMU_FL_NO_HT_SHARING ; x86_pmu.cpu_events = snb_events_attrs; + mem_attr = snb_mem_events_attrs;/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =@@ -4192,6 +4217,7 @@ __init int intel_pmu_init(void) x86_pmu.flags |=PMU_FL_NO_HT_SHARING ; x86_pmu.cpu_events = snb_events_attrs; + mem_attr = snb_mem_events_attrs;/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =@@ -4226,10 +4252,12 @@ __init int intel_pmu_init(void) x86_pmu.hw_config = hsw_hw_config; x86_pmu.get_event_constraints = hsw_get_event_constraints; - x86_pmu.cpu_events =get_hsw_events_attrs (); + x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.lbr_double_abort = true; extra_attr =boot_cpu_has (X86_FEATURE_RTM ) ? hsw_format_attr : nhm_format_attr; + mem_attr = hsw_mem_events_attrs; + tsx_attr = hsw_tsx_events_attrs;pr_cont ("Haswell events, " ); name ="haswell" ;break ;@@ -4265,10 +4293,12 @@ __init int intel_pmu_init(void) x86_pmu.hw_config = hsw_hw_config; x86_pmu.get_event_constraints = hsw_get_event_constraints; - x86_pmu.cpu_events =get_hsw_events_attrs (); + x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.limit_period = bdw_limit_period; extra_attr =boot_cpu_has (X86_FEATURE_RTM ) ? hsw_format_attr : nhm_format_attr; + mem_attr = hsw_mem_events_attrs; + tsx_attr = hsw_tsx_events_attrs;pr_cont ("Broadwell events, " ); name ="broadwell" ;break ;@@ -4324,7 +4354,9 @@ __init int intel_pmu_init(void) hsw_format_attr : nhm_format_attr; extra_attr =merge_attr (extra_attr, skl_format_attr); to_free = extra_attr; - x86_pmu.cpu_events =get_hsw_events_attrs (); + x86_pmu.cpu_events = hsw_events_attrs; + mem_attr = hsw_mem_events_attrs; + tsx_attr = hsw_tsx_events_attrs;intel_pmu_pebs_data_source_skl ( boot_cpu_data.x86_model ==INTEL_FAM6_SKYLAKE_X );pr_cont ("Skylake events, " );@@ -4357,6 +4389,9 @@ __init int intel_pmu_init(void)WARN_ON (!x86_pmu.format_attrs); } + x86_pmu.cpu_events =get_events_attrs (x86_pmu.cpu_events, + mem_attr, tsx_attr); +if (x86_pmu.num_counters >INTEL_PMC_MAX_GENERIC ) {WARN (1 ,KERN_ERR "hw perf events %d > max(%d), clipping!" , x86_pmu.num_counters,INTEL_PMC_MAX_GENERIC );Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf/x86/intel: Export mem events only if there's PEBS support
In reply to Jiri Olsaperf/x86/intel: Export mem events only if there's PEBS support
Commit-ID: d4ae552982de39417d17f823df1f06b1cbc3686c Gitweb: https://git.kernel.org/tip/d4ae552982de39417d17f823df1f06b1cbc3686c Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 6 Sep 2018 15:57:48 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 16 Oct 2018 17:29:07 +0200
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.
--- arch/x86/events/core.c | 8 ++--- arch/x86/events/intel/core.c | 69 +++++++++++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 21 deletions(-)
arch/x86/events/core.c +4 -4
@@ -1652,9 +1652,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)struct attribute **new;int j, i; -for (j =0 ; a[j]; j++) +for (j =0 ; a && a[j]; j++) ; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) j++; j++;
@@ -1663,9 +1663,9 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)return NULL ; j =0 ; -for (i =0 ; a[i]; i++) +for (i =0 ; a && a[i]; i++) new[j++] = a[i]; -for (i =0 ; b[i]; i++) +for (i =0 ; b && b[i]; i++) new[j++] = b[i]; new[j] =NULL ;
arch/x86/events/intel/core.c +52 -17
168 lines not on this page · raw message