perf: Adding sysfs group format attribute for pmu device
Subsystems (2)
Commit-ID: 641cc938815dfd09f8fa1ec72deb814f0938ac33 Gitweb: http://git.kernel.org/tip/641cc938815dfd09f8fa1ec72deb814f0938ac33 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 15 Mar 2012 20:09:14 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Fri, 16 Mar 2012 14:06:06 -0300
perf: Adding sysfs group format attribute for pmu device
Adding sysfs group 'format' attribute for pmu device that contains a syntax description on how to construct raw events.
The event configuration is described in following
struct pefr_event_attr attributes:
config
config1
config2
Each sysfs attribute within the format attribute group, describes mapping of name and bitfield definition within one of above attributes.
eg:
"/sys/...<dev>/format/event" contains "config:0-7" "/sys/...<dev>/format/umask" contains "config:8-15"
"/sys/...<dev>/format/usr" contains "config:16"
the attribute value syntax is:
line: config ':' bits config: 'config' | 'config1' | 'config2" bits: bits ',' bit_term | bit_term bit_term: VALUE '-' VALUE | VALUE
Adding format attribute definitions for x86 cpu pmus.
Acked-by Peter Zijlstra <[email protected]>
Signed-off-by Peter Zijlstra <[email protected]>
Signed-off-by Jiri Olsa <[email protected]>
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>
--- .../testing/sysfs-bus-event_source-devices-format | 14 ++++++++ arch/x86/kernel/cpu/perf_event.c | 7 ++++ arch/x86/kernel/cpu/perf_event.h | 1 + arch/x86/kernel/cpu/perf_event_amd.c | 18 ++++++++++ arch/x86/kernel/cpu/perf_event_intel.c | 36 ++++++++++++++++++++ arch/x86/kernel/cpu/perf_event_p6.c | 19 ++++++++++ include/linux/perf_event.h | 14 ++++++++ 7 files changed, 109 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-event_source-devices-format new file +14 -0
@@ -0,0 +1,14 @@ +Where: /sys/bus/event_source/devices/<dev>/format +Date: January 2012 +Kernel Version: 3.3 +Contact: Jiri Olsa <[email protected]> +Description: + Attribute group to describe the magic bits that go into + perf_event_attr::config[012] for a particular pmu. + Each attribute of this group defines the 'hardware' bitmask + we want to export, so that userspace can deal with sane + name/value pairs. + + Example: 'config1:1,6-10,44' + Defines contents of attribute that occupies bits 1,6-10,44 of + perf_event_attr::config1.
arch/x86/kernel/cpu/perf_event.c +7 -0
@@ -1314,6 +1314,11 @@ static void __init pmu_check_apic(void)pr_info ("no hardware sampling interrupt available.\n" ); } +static struct attribute_group x86_pmu_format_group = { + .name ="format" , + .attrs =NULL , +}; +static int __init init_hw_perf_events (void ) {struct x86_pmu_quirk *quirk;
@@ -1388,6 +1393,7 @@ static int __init init_hw_perf_events(void) } x86_pmu.attr_rdpmc =1 ;/* enable userspace RDPMC usage by default */ + x86_pmu_format_group.attrs = x86_pmu.format_attrs;pr_info ("... version: %d\n" , x86_pmu.version);pr_info ("... bit width: %d\n" , x86_pmu.cntval_bits);
@@ -1668,6 +1674,7 @@ static struct attribute_group x86_pmu_attr_group = {static const struct attribute_group *x86_pmu_attr_groups[] = { &x86_pmu_attr_group, + &x86_pmu_format_group,NULL , };
arch/x86/kernel/cpu/perf_event.h +1 -0
@@ -339,6 +339,7 @@ struct x86_pmu {* sysfs attrs */ int attr_rdpmc; +struct attribute **format_attrs;/* * CPU Hotplug hooks
arch/x86/kernel/cpu/perf_event_amd.c +18 -0
@@ -404,6 +404,21 @@ static void amd_pmu_cpu_dead(int cpu) } } +PMU_FORMAT_ATTR (event,"config:0-7,32-35" ); +PMU_FORMAT_ATTR (umask,"config:8-15" ); +PMU_FORMAT_ATTR (edge,"config:18" ); +PMU_FORMAT_ATTR (inv,"config:23" ); +PMU_FORMAT_ATTR (cmask,"config:24-31" ); + +static struct attribute *amd_format_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_cmask.attr, +NULL , +}; +static __initconst const struct x86_pmu amd_pmu = { .name ="AMD" , .handle_irq = x86_pmu_handle_irq,
@@ -426,6 +441,8 @@ static __initconst const struct x86_pmu amd_pmu = { .get_event_constraints = amd_get_event_constraints, .put_event_constraints = amd_put_event_constraints, + .format_attrs = amd_format_attr, + .cpu_prepare = amd_pmu_cpu_prepare, .cpu_starting = amd_pmu_cpu_starting, .cpu_dead = amd_pmu_cpu_dead,
@@ -596,6 +613,7 @@ static __initconst const struct x86_pmu amd_pmu_f15h = { .cpu_dead = amd_pmu_cpu_dead, #endif .cpu_starting = amd_pmu_cpu_starting, + .format_attrs = amd_format_attr, };__init int amd_pmu_init (void )
arch/x86/kernel/cpu/perf_event_intel.c +36 -0
@@ -1431,6 +1431,24 @@ static void core_pmu_enable_all(int added) } } +PMU_FORMAT_ATTR (event,"config:0-7" ); +PMU_FORMAT_ATTR (umask,"config:8-15" ); +PMU_FORMAT_ATTR (edge,"config:18" ); +PMU_FORMAT_ATTR (pc,"config:19" ); +PMU_FORMAT_ATTR (any,"config:21" );/* v3 + */ +PMU_FORMAT_ATTR (inv,"config:23" ); +PMU_FORMAT_ATTR (cmask,"config:24-31" ); + +static struct attribute *intel_arch_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_pc.attr, + &format_attr_inv.attr, + &format_attr_cmask.attr, +NULL , +}; +static __initconst const struct x86_pmu core_pmu = { .name ="core" , .handle_irq = x86_pmu_handle_irq,
@@ -1455,6 +1473,7 @@ static __initconst const struct x86_pmu core_pmu = { .put_event_constraints = intel_put_event_constraints, .event_constraints = intel_core_event_constraints, .guest_get_msrs = core_guest_get_msrs, + .format_attrs = intel_arch_formats_attr, };struct intel_shared_regs *allocate_shared_regs (int cpu)
@@ -1553,6 +1572,21 @@ static void intel_pmu_flush_branch_stack(void)intel_pmu_lbr_reset (); } +PMU_FORMAT_ATTR (offcore_rsp,"config1:0-63" ); + +static struct attribute *intel_arch3_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_pc.attr, + &format_attr_any.attr, + &format_attr_inv.attr, + &format_attr_cmask.attr, + + &format_attr_offcore_rsp.attr,/* XXX do NHM/WSM + SNB breakout */ +NULL , +}; +static __initconst const struct x86_pmu intel_pmu = { .name ="Intel" , .handle_irq = intel_pmu_handle_irq,
@@ -1576,6 +1610,8 @@ static __initconst const struct x86_pmu intel_pmu = { .get_event_constraints = intel_get_event_constraints, .put_event_constraints = intel_put_event_constraints, + .format_attrs = intel_arch3_formats_attr, + .cpu_prepare = intel_pmu_cpu_prepare, .cpu_starting = intel_pmu_cpu_starting, .cpu_dying = intel_pmu_cpu_dying,
arch/x86/kernel/cpu/perf_event_p6.c +19 -0
@@ -87,6 +87,23 @@ static void p6_pmu_enable_event(struct perf_event *event) (void )checking_wrmsrl (hwc->config_base, val); } +PMU_FORMAT_ATTR (event,"config:0-7" ); +PMU_FORMAT_ATTR (umask,"config:8-15" ); +PMU_FORMAT_ATTR (edge,"config:18" ); +PMU_FORMAT_ATTR (pc,"config:19" ); +PMU_FORMAT_ATTR (inv,"config:23" ); +PMU_FORMAT_ATTR (cmask,"config:24-31" ); + +static struct attribute *intel_p6_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_pc.attr, + &format_attr_inv.attr, + &format_attr_cmask.attr, +NULL , +}; +static __initconst const struct x86_pmu p6_pmu = { .name ="p6" , .handle_irq = x86_pmu_handle_irq,
@@ -115,6 +132,8 @@ static __initconst const struct x86_pmu p6_pmu = { .cntval_mask = (1ULL << 32) - 1, .get_event_constraints = x86_get_event_constraints, .event_constraints = p6_event_constraints, + + .format_attrs = intel_p6_formats_attr, };__init int p6_pmu_init (void )
include/linux/perf_event.h +14 -0
@@ -550,6 +550,7 @@ struct perf_guest_info_callbacks {#include <linux/irq_work.h> #include <linux/static_key.h> #include <linux/atomic.h> +#include <linux/sysfs.h> #include <asm/local.h> #define PERF_MAX_STACK_DEPTH 255
@@ -1291,5 +1292,18 @@ do { \ register_cpu_notifier(&fn##_nb); \ } while (0) + +#define PMU_FORMAT_ATTR (_name, _format) \ +static ssize_t \ +_name##_show(struct device *dev, \ + struct device_attribute *attr, \ + char *page) \ +{ \ + BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ + return sprintf(page, _format "\n"); \ +} \ + \ +static struct device_attribute format_attr_##_name = __ATTR_RO(_name) +#endif /* __KERNEL__ */ #endif /* _LINUX_PERF_EVENT_H */