perf: add ability to sample interrupted machine state
Subsystems (2)
v7 cover perf: add ability to sample interrupted machine state
This short patch series add the ability to sample the interrupted machine state for each hardware sample. This is useful to analyze the state after certain events, for instance for function value profiling after a call instruction.
The patch extends the interface with a new PERF_SAMPLE_REGS_INTR smaple_type flag. The register to sample can be named in the sample_regs_intr bitmask for each event. The name and bit position for each register is architecture dependent and provided, just like for PERF_SAMPLE_REGS_USER by asm/perf_regs.h.
The support is similar to PERF_SAMPLE_REGS_USER.
On Intel x86, the series includes support for capturing the PEBS state as well. When precise sampling is used, the interrupted state is collect from the PEBS records, at least partially. The PEBS machine state is a subset of the machine state.
The series provides access to this new feature in perf record with the -I option. It is possible to display the sampled register values using perf report -D.
This patch series is the fundation for a future series adding function value profiling.
In V2, we address the issues raised during reviews:
- add sample parsing test
- shorten perf record option to --intr-regs
- added man page for perf record -I/--intr-regs option
- refactor register printf code between user and intr regs
- rebase to v3.16-rc3
In V3, we rebase to 3.16.0+ and made the modifications suggested by PeterZ. We also integrated his patch to improve the layout of perf_sample_data.
In V4, we rebase to 3.17-rc3 and we fix the ABI change issue reported by Namhyung Kim.
In V5, the patch is rebased to 3.17-rc4 and the bugs reported on LKML about the PEBS machine state copying code have been fixed (a few registers were missing).
In V6, we added the missing copy of the eflags from the PEBS mahcine state (reported by Andi). We fixed some formatting issues. We rebased to 3.17-rc6.
In V7, we fix the eflags compilation error, we added the #ifndef CONFIG_X86_32 to enable 32-bit compilations. Still relative to 3.17-rc6
Peter Zijlstra (1):
perf: improve perf_sample_data struct layout
Stephane Eranian (5):
perf: add ability to sample machine state on interrupt perf/x86: add support for sampling PEBS machine state registers perf tools: add core support for sampling intr machine state regs perf/tests: add interrupted state sample parsing test perf record: add new -I option to sample interrupted machine state
arch/x86/kernel/cpu/perf_event_intel_ds.c | 23 ++++++++++++ include/linux/perf_event.h | 37 ++++++++++--------- include/uapi/linux/perf_event.h | 15 +++++++- kernel/events/core.c | 51 ++++++++++++++++++++++++-- tools/perf/Documentation/perf-record.txt | 6 ++++ tools/perf/builtin-record.c | 2 ++ tools/perf/perf.h | 1 + tools/perf/tests/sample-parsing.c | 55 +++++++++++++++++++++-------- tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 46 +++++++++++++++++++++++- tools/perf/util/header.c | 1 + tools/perf/util/session.c | 44 ++++++++++++++++++++--- 12 files changed, 240 insertions(+), 42 deletions(-)
Signature · 1 line
1.7.9.5
PATCH v7 1/6 perf: add ability to sample machine state on interrupt
Enable capture of interrupted machine state for each sample.
Registers to sample are passed per event in the sample_regs_intr bitmask.
To sample interrupt machine state, the PERF_SAMPLE_INTR_REGS must be passed in sample_type.
The list of available registers is arch dependent and provided by asm/perf_regs.h
Registers are laid out as u64 in the order of the bit order of sample_intr_regs.
This patch also adds a new ABI version PERF_ATTR_SIZE_VER4 because we extend the perf_event_attr struct with a new u64 field.
--- include/linux/perf_event.h | 7 ++++-- include/uapi/linux/perf_event.h | 15 ++++++++++++- kernel/events/core.c | 46 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-)
include/linux/perf_event.h +5 -2
@@ -79,7 +79,7 @@ struct perf_branch_stack {struct perf_branch_entry entries[0 ]; }; -struct perf_regs_user { +struct perf_regs {__u64 abi;struct pt_regs *regs; };
@@ -600,7 +600,8 @@ struct perf_sample_data {struct perf_callchain_entry *callchain;struct perf_raw_record *raw;struct perf_branch_stack *br_stack; -struct perf_regs_user regs_user; +struct perf_regs regs_user; +struct perf_regs regs_intr;u64 stack_user_size;u64 weight;/*
@@ -630,6 +631,8 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->weight =0 ; data->data_src.val =PERF_MEM_NA ; data->txn =0 ; + data->regs_intr.abi =PERF_SAMPLE_REGS_ABI_NONE ; + data->regs_intr.regs =NULL ; } extern void perf_output_sample(struct perf_output_handle *handle,
include/uapi/linux/perf_event.h +14 -1
@@ -137,8 +137,9 @@ enum perf_event_sample_format {PERF_SAMPLE_DATA_SRC =1U <<15 ,PERF_SAMPLE_IDENTIFIER =1U <<16 ,PERF_SAMPLE_TRANSACTION =1U <<17 , +PERF_SAMPLE_REGS_INTR =1U <<18 , - PERF_SAMPLE_MAX = 1U << 18, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ };/*
@@ -238,6 +239,7 @@ enum perf_event_read_format {#define PERF_ATTR_SIZE_VER2 80/* add: branch_sample_type */ #define PERF_ATTR_SIZE_VER3 96/* add: sample_regs_user */ /* add: sample_stack_user */ +#define PERF_ATTR_SIZE_VER4 104/* add: sample_regs_intr */ /* * Hardware event_id to monitor via a performance monitoring event:
@@ -334,6 +336,15 @@ struct perf_event_attr {/* Align to u64. */ __u32 __reserved_2; +/* +* Defines set of regs to dump for each sample +* state captured on: +* - precise = 0: PMU interrupt +* - precise > 0: sampled instruction +* +* See asm/perf_regs.h for details. +*/ +__u64 sample_regs_intr; };#define perf_flags (attr) (*(&(attr)->read_format + 1))
@@ -686,6 +697,8 @@ enum perf_event_type {* { u64 weight; } && PERF_SAMPLE_WEIGHT * { u64 data_src; } && PERF_SAMPLE_DATA_SRC * { u64 transaction; } && PERF_SAMPLE_TRANSACTION +* { u64 abi; # enum perf_sample_regs_abi +* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR * }; */ PERF_RECORD_SAMPLE = 9,
kernel/events/core.c +44 -2
82 lines not on this page · raw message
Signature · 1 line
1.7.9.5
tip-bot for Stephane Eranian
merge bot[tip:perf/core] perf: Add ability to sample machine state on interrupt
perf: Add ability to sample machine state on interrupt
Commit-ID: 60e2364e60e86e81bc6377f49779779e6120977f Gitweb: http://git.kernel.org/tip/60e2364e60e86e81bc6377f49779779e6120977f Author: Stephane Eranian <[email protected]> AuthorDate: Wed, 24 Sep 2014 13:48:37 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 16 Nov 2014 11:41:57 +0100
perf: Add ability to sample machine state on interrupt
Enable capture of interrupted machine state for each sample.
Registers to sample are passed per event in the sample_regs_intr bitmask.
To sample interrupt machine state, the PERF_SAMPLE_INTR_REGS must be passed in sample_type.
The list of available registers is arch dependent and provided by asm/perf_regs.h
Registers are laid out as u64 in the order of the bit order of sample_intr_regs.
This patch also adds a new ABI version PERF_ATTR_SIZE_VER4 because we extend the perf_event_attr struct with a new u64 field.
--- include/linux/perf_event.h | 7 +++++-- include/uapi/linux/perf_event.h | 15 +++++++++++++- kernel/events/core.c | 46 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-)
include/linux/perf_event.h +5 -2
@@ -79,7 +79,7 @@ struct perf_branch_stack {struct perf_branch_entry entries[0 ]; }; -struct perf_regs_user { +struct perf_regs {__u64 abi;struct pt_regs *regs; };
@@ -600,7 +600,8 @@ struct perf_sample_data {struct perf_callchain_entry *callchain;struct perf_raw_record *raw;struct perf_branch_stack *br_stack; -struct perf_regs_user regs_user; +struct perf_regs regs_user; +struct perf_regs regs_intr;u64 stack_user_size;u64 weight;/*
@@ -630,6 +631,8 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->weight =0 ; data->data_src.val =PERF_MEM_NA ; data->txn =0 ; + data->regs_intr.abi =PERF_SAMPLE_REGS_ABI_NONE ; + data->regs_intr.regs =NULL ; } extern void perf_output_sample(struct perf_output_handle *handle,
include/uapi/linux/perf_event.h +14 -1
@@ -137,8 +137,9 @@ enum perf_event_sample_format {PERF_SAMPLE_DATA_SRC =1U <<15 ,PERF_SAMPLE_IDENTIFIER =1U <<16 ,PERF_SAMPLE_TRANSACTION =1U <<17 , +PERF_SAMPLE_REGS_INTR =1U <<18 , - PERF_SAMPLE_MAX = 1U << 18, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ };/*
@@ -238,6 +239,7 @@ enum perf_event_read_format {#define PERF_ATTR_SIZE_VER2 80/* add: branch_sample_type */ #define PERF_ATTR_SIZE_VER3 96/* add: sample_regs_user */ /* add: sample_stack_user */ +#define PERF_ATTR_SIZE_VER4 104/* add: sample_regs_intr */ /* * Hardware event_id to monitor via a performance monitoring event:
@@ -334,6 +336,15 @@ struct perf_event_attr {/* Align to u64. */ __u32 __reserved_2; +/* +* Defines set of regs to dump for each sample +* state captured on: +* - precise = 0: PMU interrupt +* - precise > 0: sampled instruction +* +* See asm/perf_regs.h for details. +*/ +__u64 sample_regs_intr; };#define perf_flags (attr) (*(&(attr)->read_format + 1))
@@ -686,6 +697,8 @@ enum perf_event_type {* { u64 weight; } && PERF_SAMPLE_WEIGHT * { u64 data_src; } && PERF_SAMPLE_DATA_SRC * { u64 transaction; } && PERF_SAMPLE_TRANSACTION +* { u64 abi; # enum perf_sample_regs_abi +* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR * }; */ PERF_RECORD_SAMPLE = 9,
kernel/events/core.c +44 -2
82 lines not on this page · raw message
Re: [PATCH v7 1/6] perf: add ability to sample machine state on interrupt
In reply to Stephane EranianEm Wed, Sep 24, 2014 at 01:48:37PM +0200, Stephane Eranian escreveu:
Quoted 13 lines
Enable capture of interrupted machine state for each sample.
Registers to sample are passed per event in the
sample_regs_intrbitmask.To sample interrupt machine state, the
PERF_SAMPLE_INTR_REGSmust be passed insample_type.The list of available registers is arch dependent and provided by
asm/perf_regs.h
Quoted 7 lines
Registers are laid out as u64 in the order of the bit order of
sample_intr_regs.This patch also adds a new ABI version
PERF_ATTR_SIZE_VER4because we extend theperf_event_attrstruct with a new u64 field.
So, trying to bisect a problem with how the TUI hist_entries browser renders callchains I got stuck with:
[root@zoo acme]# perf report
incompatible file format (rerun with -v to learn more)
[root@zoo acme]# perf report -v
file uses a more recent and unsupported ABI (8 bytes extra)
Because the perf.data file was generated with HEAD of perf/core and probably the above warning comes from a simple check against the ABI version...
I wonder if we can't just check that there are no sample_types that we don't know and if not, just process the file anyway, i.e. the sample will be parseable, no?
For now, in this case, I'll just regenerate the perf.data file with an older tool...
- Arnaldo
Quoted 183 lines
Reviewed-by Jiri Olsa <[email protected]>Reviewed-by Andi Kleen <[email protected]>Signed-off-by Stephane Eranian <[email protected]>--- include/linux/perf_event.h | 7 ++++-- include/uapi/linux/perf_event.h | 15 ++++++++++++- kernel/events/core.c | 46 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-)include/linux/perf_event.h +5
-2@@ -79,7 +79,7 @@ struct perf_branch_stack {struct perf_branch_entry entries[0 ]; }; -struct perf_regs_user { +struct perf_regs {__u64 abi;struct pt_regs *regs; };@@ -600,7 +600,8 @@ struct perf_sample_data {struct perf_callchain_entry *callchain;struct perf_raw_record *raw;struct perf_branch_stack *br_stack; -struct perf_regs_user regs_user; +struct perf_regs regs_user; +struct perf_regs regs_intr;u64 stack_user_size;u64 weight;/* @@ -630,6 +631,8 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->weight =0 ; data->data_src.val =PERF_MEM_NA ; data->txn =0 ; + data->regs_intr.abi =PERF_SAMPLE_REGS_ABI_NONE ; + data->regs_intr.regs =NULL ; } extern void perf_output_sample(struct perf_output_handle *handle,include/uapi/linux/perf_event.h +14
-1@@ -137,8 +137,9 @@ enum perf_event_sample_format {PERF_SAMPLE_DATA_SRC =1U <<15 ,PERF_SAMPLE_IDENTIFIER =1U <<16 ,PERF_SAMPLE_TRANSACTION =1U <<17 , +PERF_SAMPLE_REGS_INTR =1U <<18 , - PERF_SAMPLE_MAX = 1U << 18, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ };/* @@ -238,6 +239,7 @@ enum perf_event_read_format {#define PERF_ATTR_SIZE_VER2 80/* add: branch_sample_type */ #define PERF_ATTR_SIZE_VER3 96/* add: sample_regs_user */ /* add: sample_stack_user */ +#define PERF_ATTR_SIZE_VER4 104/* add: sample_regs_intr */ /* * Hardware event_id to monitor via a performance monitoring event: @@ -334,6 +336,15 @@ struct perf_event_attr {/* Align to u64. */ __u32 __reserved_2; +/* +* Defines set of regs to dump for each sample +* state captured on: +* - precise = 0: PMU interrupt +* - precise > 0: sampled instruction +* +* See asm/perf_regs.h for details. +*/ +__u64 sample_regs_intr; };#define perf_flags (attr) (*(&(attr)->read_format + 1))@@ -686,6 +697,8 @@ enum perf_event_type {* { u64 weight; } && PERF_SAMPLE_WEIGHT * { u64 data_src; } && PERF_SAMPLE_DATA_SRC * { u64 transaction; } && PERF_SAMPLE_TRANSACTION +* { u64 abi; # enum perf_sample_regs_abi +* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR * }; */ PERF_RECORD_SAMPLE = 9,kernel/events/core.c +44
-2@@ -4430,7 +4430,7 @@ perf_output_sample_regs(struct perf_output_handle *handle, } } -static void perf_sample_regs_user (struct perf_regs_user *regs_user, +static void perf_sample_regs_user (struct perf_regs *regs_user,struct pt_regs *regs) {if (!user_mode (regs)) {@@ -4446,6 +4446,14 @@ static void perf_sample_regs_user(struct perf_regs_user *regs_user, } } +static void perf_sample_regs_intr (struct perf_regs *regs_intr, +struct pt_regs *regs) +{ + regs_intr->regs = regs; + regs_intr->abi =perf_reg_abi (current); +} + +/* * Get remaining task size from user stack pointer. * @@ -4827,6 +4835,23 @@ void perf_output_sample(struct perf_output_handle *handle,if (sample_type &PERF_SAMPLE_TRANSACTION )perf_output_put (handle, data->txn); +if (sample_type &PERF_SAMPLE_REGS_INTR ) { +u64 abi = data->regs_intr.abi; +/* +* If there are no regs to dump, notice it through +* first u64 being zero (PERF_SAMPLE_REGS_ABI_NONE). +*/ +perf_output_put (handle, abi); + +if (abi) { +u64 mask = event->attr.sample_regs_intr; + +perf_output_sample_regs (handle, + data->regs_intr.regs, + mask); + } + } +if (!event->attr.watermark) {int wakeup_events = event->attr.wakeup_events;@@ -4913,7 +4938,7 @@ void perf_prepare_sample(struct perf_event_header *header,* in case new sample type is added, because we could eat * up the rest of the sample size. */ -struct perf_regs_user *uregs = &data->regs_user; +struct perf_regs *uregs = &data->regs_user;u16 stack_size = event->attr.sample_stack_user;u16 size =sizeof (u64);@@ -4934,6 +4959,21 @@ void perf_prepare_sample(struct perf_event_header *header, data->stack_user_size = stack_size; header->size += size; } + +if (sample_type &PERF_SAMPLE_REGS_INTR ) { +/* regs dump ABI info */ +int size =sizeof (u64); + +perf_sample_regs_intr (&data->regs_intr, regs); + +if (data->regs_intr.regs) { +u64 mask = event->attr.sample_regs_intr; + + size +=hweight64 (mask) *sizeof (u64); + } + + header->size += size; + } } static void perf_event_output(struct perf_event *event,@@ -7134,6 +7174,8 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, ret = -EINVAL ; } +if (attr->sample_type &PERF_SAMPLE_REGS_INTR ) + ret =perf_reg_validate (attr->sample_regs_intr); out:return ret;Signature · 1 line
1.7.9.5
Re: [PATCH v7 1/6] perf: add ability to sample machine state on interrupt
Em Fri, Nov 21, 2014 at 07:26:31PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 21 lines
Em Wed, Sep 24, 2014 at 01:48:37PM +0200, Stephane Eranian escreveu:
Quoted 20 lines
Enable capture of interrupted machine state for each sample.
Registers to sample are passed per event in the
sample_regs_intrbitmask.To sample interrupt machine state, the
PERF_SAMPLE_INTR_REGSmust be passed insample_type.The list of available registers is arch dependent and provided by
asm/perf_regs.hRegisters are laid out as u64 in the order of the bit order of
sample_intr_regs.This patch also adds a new ABI version
PERF_ATTR_SIZE_VER4because we extend theperf_event_attrstruct with a new u64 field.
I think this problem is also related to this changeset:
[root@zoo ~]# perf test 15
15: struct perf_event_attr setup :FAILED
'/home/acme/libexec/perf-core/tests/attr/test-stat-default' - match failure
Ok
[root@zoo ~]# perf test -v 15
15: struct perf_event_attr setup :
--- start ---
test child forked, pid 17464
running '/home/acme/libexec/perf-core/tests/attr/test-record-branch-filter-hv' unsupp '/home/acme/libexec/perf-core/tests/attr/test-record-branch-filter-hv' running '/home/acme/libexec/perf-core/tests/attr/test-record-count' unsupp '/home/acme/libexec/perf-core/tests/attr/test-record-count' running '/home/acme/libexec/perf-core/tests/attr/test-record-basic' unsupp '/home/acme/libexec/perf-core/tests/attr/test-record-basic' running '/home/acme/libexec/perf-core/tests/attr/test-stat-default' expected size=96, got 104
FAILED '/home/acme/libexec/perf-core/tests/attr/test-stat-default' - match failure
test child finished with 0
---- end ----
struct perf_event_attr setup: Ok
[root@zoo ~]# uname -r
3.17.3-200.fc20.x86_64
[root@zoo ~]#
Checking if this is just a matter of updating the test entry.
- Arnaldo
Quoted 206 lines
So, trying to bisect a problem with how the TUI
hist_entriesbrowser renders callchains I got stuck with:[root@zoo acme]# perf report
incompatible file format (rerun with -v to learn more)[root@zoo acme]# perf report -v
file uses a more recent and unsupported ABI (8 bytes extra)Because the perf.data file was generated with HEAD of perf/core and probably the above warning comes from a simple check against the ABI version...
I wonder if we can't just check that there are no
sample_typesthat we don't know and if not, just process the file anyway, i.e. the sample will be parseable, no?For now, in this case, I'll just regenerate the perf.data file with an older tool...
- Arnaldo
Quoted 183 lines
Reviewed-by Jiri Olsa <[email protected]>Reviewed-by Andi Kleen <[email protected]>Signed-off-by Stephane Eranian <[email protected]>--- include/linux/perf_event.h | 7 ++++-- include/uapi/linux/perf_event.h | 15 ++++++++++++- kernel/events/core.c | 46 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-)include/linux/perf_event.h +5
-2@@ -79,7 +79,7 @@ struct perf_branch_stack {struct perf_branch_entry entries[0 ]; }; -struct perf_regs_user { +struct perf_regs {__u64 abi;struct pt_regs *regs; };@@ -600,7 +600,8 @@ struct perf_sample_data {struct perf_callchain_entry *callchain;struct perf_raw_record *raw;struct perf_branch_stack *br_stack; -struct perf_regs_user regs_user; +struct perf_regs regs_user; +struct perf_regs regs_intr;u64 stack_user_size;u64 weight;/* @@ -630,6 +631,8 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->weight =0 ; data->data_src.val =PERF_MEM_NA ; data->txn =0 ; + data->regs_intr.abi =PERF_SAMPLE_REGS_ABI_NONE ; + data->regs_intr.regs =NULL ; } extern void perf_output_sample(struct perf_output_handle *handle,include/uapi/linux/perf_event.h +14
-1@@ -137,8 +137,9 @@ enum perf_event_sample_format {PERF_SAMPLE_DATA_SRC =1U <<15 ,PERF_SAMPLE_IDENTIFIER =1U <<16 ,PERF_SAMPLE_TRANSACTION =1U <<17 , +PERF_SAMPLE_REGS_INTR =1U <<18 , - PERF_SAMPLE_MAX = 1U << 18, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ };/* @@ -238,6 +239,7 @@ enum perf_event_read_format {#define PERF_ATTR_SIZE_VER2 80/* add: branch_sample_type */ #define PERF_ATTR_SIZE_VER3 96/* add: sample_regs_user */ /* add: sample_stack_user */ +#define PERF_ATTR_SIZE_VER4 104/* add: sample_regs_intr */ /* * Hardware event_id to monitor via a performance monitoring event: @@ -334,6 +336,15 @@ struct perf_event_attr {/* Align to u64. */ __u32 __reserved_2; +/* +* Defines set of regs to dump for each sample +* state captured on: +* - precise = 0: PMU interrupt +* - precise > 0: sampled instruction +* +* See asm/perf_regs.h for details. +*/ +__u64 sample_regs_intr; };#define perf_flags (attr) (*(&(attr)->read_format + 1))@@ -686,6 +697,8 @@ enum perf_event_type {* { u64 weight; } && PERF_SAMPLE_WEIGHT * { u64 data_src; } && PERF_SAMPLE_DATA_SRC * { u64 transaction; } && PERF_SAMPLE_TRANSACTION +* { u64 abi; # enum perf_sample_regs_abi +* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR * }; */ PERF_RECORD_SAMPLE = 9,kernel/events/core.c +44
-2@@ -4430,7 +4430,7 @@ perf_output_sample_regs(struct perf_output_handle *handle, } } -static void perf_sample_regs_user (struct perf_regs_user *regs_user, +static void perf_sample_regs_user (struct perf_regs *regs_user,struct pt_regs *regs) {if (!user_mode (regs)) {@@ -4446,6 +4446,14 @@ static void perf_sample_regs_user(struct perf_regs_user *regs_user, } } +static void perf_sample_regs_intr (struct perf_regs *regs_intr, +struct pt_regs *regs) +{ + regs_intr->regs = regs; + regs_intr->abi =perf_reg_abi (current); +} + +/* * Get remaining task size from user stack pointer. * @@ -4827,6 +4835,23 @@ void perf_output_sample(struct perf_output_handle *handle,if (sample_type &PERF_SAMPLE_TRANSACTION )perf_output_put (handle, data->txn); +if (sample_type &PERF_SAMPLE_REGS_INTR ) { +u64 abi = data->regs_intr.abi; +/* +* If there are no regs to dump, notice it through +* first u64 being zero (PERF_SAMPLE_REGS_ABI_NONE). +*/ +perf_output_put (handle, abi); + +if (abi) { +u64 mask = event->attr.sample_regs_intr; + +perf_output_sample_regs (handle, + data->regs_intr.regs, + mask); + } + } +if (!event->attr.watermark) {int wakeup_events = event->attr.wakeup_events;@@ -4913,7 +4938,7 @@ void perf_prepare_sample(struct perf_event_header *header,* in case new sample type is added, because we could eat * up the rest of the sample size. */ -struct perf_regs_user *uregs = &data->regs_user; +struct perf_regs *uregs = &data->regs_user;u16 stack_size = event->attr.sample_stack_user;u16 size =sizeof (u64);@@ -4934,6 +4959,21 @@ void perf_prepare_sample(struct perf_event_header *header, data->stack_user_size = stack_size; header->size += size; } + +if (sample_type &PERF_SAMPLE_REGS_INTR ) { +/* regs dump ABI info */ +int size =sizeof (u64); + +perf_sample_regs_intr (&data->regs_intr, regs); + +if (data->regs_intr.regs) { +u64 mask = event->attr.sample_regs_intr; + + size +=hweight64 (mask) *sizeof (u64); + } + + header->size += size; + } } static void perf_event_output(struct perf_event *event,@@ -7134,6 +7174,8 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, ret = -EINVAL ; } +if (attr->sample_type &PERF_SAMPLE_REGS_INTR ) + ret =perf_reg_validate (attr->sample_regs_intr); out:return ret;Signature · 1 line
1.7.9.5
Re: [PATCH v7 1/6] perf: add ability to sample machine state on interrupt
Em Tue, Dec 09, 2014 at 11:30:31AM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 11 lines
Em Fri, Nov 21, 2014 at 07:26:31PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 5 lines
Em Wed, Sep 24, 2014 at 01:48:37PM +0200, Stephane Eranian escreveu:
Quoted 4 lines
This patch also adds a new ABI version
PERF_ATTR_SIZE_VER4because we extend
theperf_event_attrstruct with a new u64
field.I think this problem is also related to this changeset:
[root@zoo ~]# perf test -v 15
15: structperf_event_attrsetup :
<SNIP>
Quoted 11 lines
running '
/home/acme/libexec/perf-core/tests/attr/test-stat-default' expected size=96, got 104
FAILED '/home/acme/libexec/perf-core/tests/attr/test-stat-default' - match failure
test child finished with 0
---- end ----
structperf_event_attrsetup: Ok
[root@zoo ~]# uname -r
3.17.3-200.fc20.x86_64
[root@zoo ~]#
Quoted 1 line
Checking if this is just a matter of updating the test entry.
Well, here I think that size variable needs to somehow be tested against the value of another field, the ABI one, so that for each ABI we test against the rightsize, that is, after this cset, 8 bytes (sizeof u64) bigger, Jiri?
- Arnaldo
perf tests: Fix attr tests size values interrupt
Quoted 24 lines · Arnaldo Carvalho de Melo
Em Tue, Dec 09, 2014 at 11:30:31AM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 11 lines
Em Fri, Nov 21, 2014 at 07:26:31PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 5 lines
Em Wed, Sep 24, 2014 at 01:48:37PM +0200, Stephane Eranian escreveu:
Quoted 4 lines
This patch also adds a new ABI version
PERF_ATTR_SIZE_VER4because we extend
theperf_event_attrstruct with a new u64
field.I think this problem is also related to this changeset:
[root@zoo ~]# perf test -v 15
15: structperf_event_attrsetup :<SNIP>
Quoted 11 lines
running '
/home/acme/libexec/perf-core/tests/attr/test-stat-default' expected size=96, got 104
FAILED '/home/acme/libexec/perf-core/tests/attr/test-stat-default' - match failure
test child finished with 0
---- end ----
structperf_event_attrsetup: Ok
[root@zoo ~]# uname -r
3.17.3-200.fc20.x86_64
[root@zoo ~]#
Quoted 6 lines
Quoted 1 line
Checking if this is just a matter of updating the test entry.
Well, here I think that size variable needs to somehow be tested against the value of another field, the ABI one, so that for each ABI we test against the rightsize, that is, after this cset, 8 bytes (sizeof u64) bigger, Jiri?
well this patch enlarged the perf_event_attr so the test needs to be adjusted like in patch below
[jolsa@krava perf]$ ./perf test attr -vv
15: struct perf_event_attr setup :
--- start ---
test child forked, pid 9719
running './tests/attr/test-stat-group1'
'PERF_TEST_ATTR=/tmp/tmp4drvul ./perf stat -o /tmp/tmp4drvul/perf.data -e '{cycles,instructions}' kill >/dev/null 2>&1' ret 1
expected size=96, got 104
FAILED './tests/attr/test-stat-group1' - match failure
jirka
---
Following change adjusted 'struct perf_event_attr', but let the attr test's sizes untouched:
60e2364e60e8 perf: Add ability to sample machine state on interrupt
Adjusting test size values for attr test.
---
tools/perf/tests/attr/base-record +1 -1
@@ -5,7 +5,7 @@ group_fd=-1 flags=0|8 cpu=* type=0|1 -size=96 +size=104 config=0 sample_period=4000 sample_type=263
tools/perf/tests/attr/base-stat +1 -1
@@ -5,7 +5,7 @@ group_fd=-1 flags=0|8 cpu=* type=0 -size=96 +size=104 config=0 sample_period=0 sample_type=0
Re: perf tests: Fix attr tests size values interrupt
Em Tue, Dec 09, 2014 at 02:53:01PM +0100, Jiri Olsa escreveu:
Quoted 27 lines · Arnaldo Carvalho de Melo
Quoted 26 lines
Em Tue, Dec 09, 2014 at 11:30:31AM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 11 lines
Em Fri, Nov 21, 2014 at 07:26:31PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 5 lines
Em Wed, Sep 24, 2014 at 01:48:37PM +0200, Stephane Eranian escreveu:
Quoted 4 lines
This patch also adds a new ABI version
PERF_ATTR_SIZE_VER4because we extend
theperf_event_attrstruct with a new u64
field.I think this problem is also related to this changeset:
[root@zoo ~]# perf test -v 15
15: structperf_event_attrsetup :<SNIP>
Quoted 12 lines
running '
/home/acme/libexec/perf-core/tests/attr/test-stat-default' expected size=96, got 104
FAILED '/home/acme/libexec/perf-core/tests/attr/test-stat-default' - match failure
test child finished with 0
---- end ----
structperf_event_attrsetup: Ok
[root@zoo ~]# uname -r
3.17.3-200.fc20.x86_64
[root@zoo ~]#Checking if this is just a matter of updating the test entry.
Quoted 7 lines
Quoted 4 lines
Well, here I think that size variable needs to somehow be tested against the value of another field, the ABI one, so that for each ABI we test against the rightsize, that is, after this cset, 8 bytes (sizeof u64) bigger, Jiri?
well this patch enlarged the
perf_event_attrso the test needs to be adjusted like in patch below
Ok, got it, since the perf.data file is generated in the test, it will have the current value, that now is 104, ok, applying your patch.
Thanks,
- Arnaldo
Quoted 47 lines
[jolsa@krava perf]$ ./perf test attr -vv
15: structperf_event_attrsetup :
--- start ---
test child forked, pid 9719
running './tests/attr/test-stat-group1'
'PERF_TEST_ATTR=/tmp/tmp4drvul ./perf stat -o/tmp/tmp4drvul/perf.data-e '{cycles,instructions}' kill >/dev/null 2>&1' ret 1
expected size=96, got 104
FAILED './tests/attr/test-stat-group1' - match failurejirka
---
Following change adjusted 'structperf_event_attr', but let the attr test's sizes untouched:
60e2364e60e8perf: Add ability to sample machine state on interruptAdjusting test size values for attr test.
Signed-off-by Jiri Olsa <[email protected]>---
tools/perf/tests/attr/base-record +1
-1@@ -5,7 +5,7 @@ group_fd=-1 flags=0|8 cpu=* type=0|1 -size=96 +size=104 config=0 sample_period=4000 sample_type=263tools/perf/tests/attr/base-stat +1
-1@@ -5,7 +5,7 @@ group_fd=-1 flags=0|8 cpu=* type=0 -size=96 +size=104 config=0 sample_period=0 sample_type=0
tip-bot for Jiri Olsa
merge bot[tip:perf/urgent] perf tests: Fix attr tests size values to cope with machine state on interrupt ABI changes
In reply to Jiri Olsaperf tests: Fix attr tests size values to cope with machine state on interrupt ABI changes
Commit-ID: 75226c577c8869ae1449cf92d781edda0177f1cf Gitweb: http://git.kernel.org/tip/75226c577c8869ae1449cf92d781edda0177f1cf Author: Jiri Olsa <[email protected]> AuthorDate: Tue, 9 Dec 2014 14:53:01 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Tue, 9 Dec 2014 11:02:43 -0300
perf tests: Fix attr tests size values to cope with machine state on interrupt ABI changes
Following change adjusted 'struct perf_event_attr', but let the attr test's sizes untouched:
60e2364e60e8 perf: Add ability to sample machine state on interrupt
[jolsa@krava perf]$ ./perf test attr -vv
--- start ---
test child forked, pid 9719
running './tests/attr/test-stat-group1'
'PERF_TEST_ATTR=/tmp/tmp4drvul ./perf stat -o /tmp/tmp4drvul/perf.data -e '{cycles,instructions}' kill >/dev/null 2>&1' ret 1
expected size=96, got 104
FAILED './tests/attr/test-stat-group1' - match failure
Adjusting test size values for attr test.
--- tools/perf/tests/attr/base-record | 2 +- tools/perf/tests/attr/base-stat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/perf/tests/attr/base-record +1 -1
@@ -5,7 +5,7 @@ group_fd=-1 flags=0|8 cpu=* type=0|1 -size=96 +size=104 config=0 sample_period=4000 sample_type=263
tools/perf/tests/attr/base-stat +1 -1
@@ -5,7 +5,7 @@ group_fd=-1 flags=0|8 cpu=* type=0 -size=96 +size=104 config=0 sample_period=0 sample_type=0
PATCH v7 2/6 perf/x86: add support for sampling PEBS machine state registers
In reply to Stephane EranianPEBS can capture machine state regs at retiremnt of the sampled instructions. When precise sampling is enabled on an event, PEBS is used, so substitute the interrupted state with the PEBS state. Note that not all registers are captured by PEBS. Those missing are replaced by the interrupt state counter-parts.
--- arch/x86/kernel/cpu/perf_event_intel_ds.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
arch/x86/kernel/cpu/perf_event_intel_ds.c +23 -0
@@ -886,6 +886,29 @@ static void __intel_pmu_pebs_event(struct perf_event *event, regs.bp = pebs->bp; regs.sp = pebs->sp; +if (sample_type &PERF_SAMPLE_REGS_INTR ) { + regs.ax = pebs->ax; + regs.bx = pebs->bx; + regs.cx = pebs->cx; + regs.dx = pebs->dx; + regs.si = pebs->si; + regs.di = pebs->di; + regs.bp = pebs->bp; + regs.sp = pebs->sp; + + regs.flags = pebs->flags; +#ifndef CONFIG_X86_32 + regs.r8 = pebs->r8; + regs.r9 = pebs->r9; + regs.r10 = pebs->r10; + regs.r11 = pebs->r11; + regs.r12 = pebs->r12; + regs.r13 = pebs->r13; + regs.r14 = pebs->r14; + regs.r15 = pebs->r15; +#endif + } +if (event->attr.precise_ip >1 && x86_pmu.intel_cap.pebs_format >=2 ) { regs.ip = pebs->real_ip; regs.flags |=PERF_EFLAGS_EXACT ;
Signature · 1 line
1.7.9.5
tip-bot for Stephane Eranian
merge bot[tip:perf/core] perf/x86: Add support for sampling PEBS machine state registers
perf/x86: Add support for sampling PEBS machine state registers
Commit-ID: aea48559ac454a065244d3eff0c94cc8af9c553e Gitweb: http://git.kernel.org/tip/aea48559ac454a065244d3eff0c94cc8af9c553e Author: Stephane Eranian <[email protected]> AuthorDate: Wed, 24 Sep 2014 13:48:38 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 16 Nov 2014 11:41:58 +0100
perf/x86: Add support for sampling PEBS machine state registers
PEBS can capture machine state regs at retiremnt of the sampled instructions. When precise sampling is enabled on an event, PEBS is used, so substitute the interrupted state with the PEBS state. Note that not all registers are captured by PEBS. Those missing are replaced by the interrupt state counter-parts.
--- arch/x86/kernel/cpu/perf_event_intel_ds.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
arch/x86/kernel/cpu/perf_event_intel_ds.c +23 -0
@@ -886,6 +886,29 @@ static void __intel_pmu_pebs_event(struct perf_event *event, regs.bp = pebs->bp; regs.sp = pebs->sp; +if (sample_type &PERF_SAMPLE_REGS_INTR ) { + regs.ax = pebs->ax; + regs.bx = pebs->bx; + regs.cx = pebs->cx; + regs.dx = pebs->dx; + regs.si = pebs->si; + regs.di = pebs->di; + regs.bp = pebs->bp; + regs.sp = pebs->sp; + + regs.flags = pebs->flags; +#ifndef CONFIG_X86_32 + regs.r8 = pebs->r8; + regs.r9 = pebs->r9; + regs.r10 = pebs->r10; + regs.r11 = pebs->r11; + regs.r12 = pebs->r12; + regs.r13 = pebs->r13; + regs.r14 = pebs->r14; + regs.r15 = pebs->r15; +#endif + } +if (event->attr.precise_ip >1 && x86_pmu.intel_cap.pebs_format >=2 ) { regs.ip = pebs->real_ip; regs.flags |=PERF_EFLAGS_EXACT ;
PATCH v7 3/6 perf tools: add core support for sampling intr machine state regs
In reply to Stephane EranianAdd the infrastructure to setup, collect and report the interrupt machine state regs which can be captured by the kernel.
--- tools/perf/perf.h | 1 + tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 46 ++++++++++++++++++++++++++++++++++++++++++++- tools/perf/util/header.c | 1 + tools/perf/util/session.c | 44 ++++++++++++++++++++++++++++++++++++++----- 5 files changed, 87 insertions(+), 6 deletions(-)
tools/perf/perf.h +1 -0
@@ -54,6 +54,7 @@ struct record_opts {bool sample_weight;bool sample_time;bool period; +bool sample_intr_regs;unsigned int freq;unsigned int mmap_pages;unsigned int user_freq;
tools/perf/util/event.h +1 -0
@@ -162,6 +162,7 @@ struct perf_sample {struct ip_callchain *callchain;struct branch_stack *branch_stack;struct regs_dump user_regs; +struct regs_dump intr_regs;struct stack_dump user_stack;struct sample_read read; };
tools/perf/util/evsel.c +45 -1
82 lines not on this page · raw message
tools/perf/util/header.c +1 -0
@@ -2458,6 +2458,7 @@ static const int attr_file_abi_sizes[] = { [1] = PERF_ATTR_SIZE_VER1, [2] = PERF_ATTR_SIZE_VER2, [3] = PERF_ATTR_SIZE_VER3, + [4 ] =PERF_ATTR_SIZE_VER4 , 0, };
tools/perf/util/session.c +39 -5
60 lines not on this page · raw message
Signature · 1 line
1.7.9.5
tip-bot for Stephane Eranian
merge bot[tip:perf/core] perf tools: Add core support for sampling intr machine state regs
perf tools: Add core support for sampling intr machine state regs
Commit-ID: 6a21c0b5c2abd2fdfa6fff79f11df3d6082c1873 Gitweb: http://git.kernel.org/tip/6a21c0b5c2abd2fdfa6fff79f11df3d6082c1873 Author: Stephane Eranian <[email protected]> AuthorDate: Wed, 24 Sep 2014 13:48:39 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 16 Nov 2014 11:41:59 +0100
perf tools: Add core support for sampling intr machine state regs
Add the infrastructure to setup, collect and report the interrupt machine state regs which can be captured by the kernel.
--- tools/perf/perf.h | 1 + tools/perf/util/event.h | 1 + tools/perf/util/evsel.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- tools/perf/util/header.c | 1 + tools/perf/util/session.c | 44 +++++++++++++++++++++++++++++++++++++++----- 5 files changed, 87 insertions(+), 6 deletions(-)
tools/perf/perf.h +1 -0
@@ -52,6 +52,7 @@ struct record_opts {bool sample_weight;bool sample_time;bool period; +bool sample_intr_regs;unsigned int freq;unsigned int mmap_pages;unsigned int user_freq;
tools/perf/util/event.h +1 -0
@@ -188,6 +188,7 @@ struct perf_sample {struct ip_callchain *callchain;struct branch_stack *branch_stack;struct regs_dump user_regs; +struct regs_dump intr_regs;struct stack_dump user_stack;struct sample_read read; };
tools/perf/util/evsel.c +45 -1
82 lines not on this page · raw message
tools/perf/util/header.c +1 -0
@@ -2143,6 +2143,7 @@ static const int attr_file_abi_sizes[] = { [1] = PERF_ATTR_SIZE_VER1, [2] = PERF_ATTR_SIZE_VER2, [3] = PERF_ATTR_SIZE_VER3, + [4 ] =PERF_ATTR_SIZE_VER4 , 0, };
tools/perf/util/session.c +39 -5
60 lines not on this page · raw message
PATCH v7 4/6 perf/tests: add interrupted state sample parsing test
In reply to Stephane EranianThis patch updates the sample parsing test with support for the sampling of machine interrupted state.
The patch modifies the do_test() code to sahred the sample regts bitmask between user and intr regs.
--- tools/perf/tests/sample-parsing.c | 55 +++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 15 deletions(-)
tools/perf/tests/sample-parsing.c +40 -15
@@ -126,16 +126,28 @@ static bool samples_same(const struct perf_sample *s1,if (type &PERF_SAMPLE_TRANSACTION )COMP (transaction); +if (type &PERF_SAMPLE_REGS_INTR ) { +size_t sz =hweight_long (s1->intr_regs.mask) *sizeof (u64); + +COMP (intr_regs.mask); +COMP (intr_regs.abi); +if (s1->intr_regs.abi && + (!s1->intr_regs.regs || !s2->intr_regs.regs || +memcmp (s1->intr_regs.regs, s2->intr_regs.regs, sz))) { +pr_debug ("Samples differ at 'intr_regs'\n" ); +return false; + } + } +return true; } -static int do_test (u64 sample_type,u64 sample_regs_user,u64 read_format) +static int do_test (u64 sample_type,u64 sample_regs,u64 read_format) {struct perf_evsel evsel = { .needs_swap = false, .attr = { .sample_type = sample_type, - .sample_regs_user = sample_regs_user, .read_format = read_format, }, };
@@ -154,7 +166,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format)/* 1 branch_entry */ .data = {1, 211, 212, 213}, }; -u64 user_regs[64 ]; +u64 regs[64 ];const u64 raw_data[] = {0x123456780a0b0c0dULL ,0x1102030405060708ULL };const u64 data[] = {0x2211443366558877ULL ,0 ,0xaabbccddeeff4321ULL }; struct perf_sample sample = {
@@ -176,8 +188,8 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) .branch_stack = &branch_stack.branch_stack, .user_regs = { .abi = PERF_SAMPLE_REGS_ABI_64, - .mask = sample_regs_user, - .regs = user_regs, + .mask = sample_regs, + .regs = regs, }, .user_stack = { .size = sizeof(data),
@@ -187,14 +199,25 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) .time_enabled = 0x030a59d664fca7deULL, .time_running = 0x011b6ae553eb98edULL, }, + .intr_regs = { + .abi = PERF_SAMPLE_REGS_ABI_64, + .mask = sample_regs, + .regs = regs, + }, };struct sample_read_value values[] = {{1 ,5 }, {9 ,3 }, {2 ,7 }, {6 ,4 },};struct perf_sample sample_out;size_t i, sz, bufsz;int err, ret =-1 ; -for (i =0 ; i <sizeof (user_regs); i++) - *(i + (u8 *)user_regs) = i &0xfe ; +if (sample_type &PERF_SAMPLE_REGS_USER ) + evsel.attr.sample_regs_user = sample_regs; + +if (sample_type &PERF_SAMPLE_REGS_INTR ) + evsel.attr.sample_regs_intr = sample_regs; + +for (i =0 ; i <sizeof (regs); i++) + *(i + (u8 *)regs) = i &0xfe ;if (read_format &PERF_FORMAT_GROUP ) { sample.read.group.nr =4 ;
@@ -271,7 +294,7 @@ int test__sample_parsing(void) {const u64 rf[] = {4 ,5 ,6 ,7 ,12 ,13 ,14 ,15 };u64 sample_type; -u64 sample_regs_user; +u64 sample_regs;size_t i;int err;
@@ -280,7 +303,7 @@ int test__sample_parsing(void)* were added. Please actually update the test rather than just change * the condition below. */ -if (PERF_SAMPLE_MAX >PERF_SAMPLE_TRANSACTION <<1 ) { +if (PERF_SAMPLE_MAX >PERF_SAMPLE_REGS_INTR <<1 ) {pr_debug ("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n" );return -1 ; }
@@ -297,22 +320,24 @@ int test__sample_parsing(void) }continue ; } + sample_regs =0 ;if (sample_type ==PERF_SAMPLE_REGS_USER ) - sample_regs_user =0x3fff ; -else - sample_regs_user =0 ; + sample_regs =0x3fff ; + +if (sample_type ==PERF_SAMPLE_REGS_INTR ) + sample_regs =0xff0fff ; - err =do_test (sample_type, sample_regs_user,0 ); + err =do_test (sample_type, sample_regs,0 );if (err)return err; }/* Test all sample format bits together */ sample_type =PERF_SAMPLE_MAX -1 ; - sample_regs_user =0x3fff ; + sample_regs =0x3fff ;/* shared yb intr and user regs */ for (i =0 ; i <ARRAY_SIZE (rf); i++) { - err =do_test (sample_type, sample_regs_user, rf[i]); + err =do_test (sample_type, sample_regs, rf[i]);if (err)return err; }
Signature · 1 line
1.7.9.5
tip-bot for Stephane Eranian
merge bot[tip:perf/core] perf/tests: Add interrupted state sample parsing test
perf/tests: Add interrupted state sample parsing test
Commit-ID: 26ff0f0af79d0a9fc1f783d45e470059b840c7c1 Gitweb: http://git.kernel.org/tip/26ff0f0af79d0a9fc1f783d45e470059b840c7c1 Author: Stephane Eranian <[email protected]> AuthorDate: Wed, 24 Sep 2014 13:48:40 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 16 Nov 2014 11:42:01 +0100
perf/tests: Add interrupted state sample parsing test
This patch updates the sample parsing test with support for the sampling of machine interrupted state.
The patch modifies the do_test() code to sahred the sample regts bitmask between user and intr regs.
--- tools/perf/tests/sample-parsing.c | 55 ++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 15 deletions(-)
tools/perf/tests/sample-parsing.c +40 -15
@@ -126,16 +126,28 @@ static bool samples_same(const struct perf_sample *s1,if (type &PERF_SAMPLE_TRANSACTION )COMP (transaction); +if (type &PERF_SAMPLE_REGS_INTR ) { +size_t sz =hweight_long (s1->intr_regs.mask) *sizeof (u64); + +COMP (intr_regs.mask); +COMP (intr_regs.abi); +if (s1->intr_regs.abi && + (!s1->intr_regs.regs || !s2->intr_regs.regs || +memcmp (s1->intr_regs.regs, s2->intr_regs.regs, sz))) { +pr_debug ("Samples differ at 'intr_regs'\n" ); +return false; + } + } +return true; } -static int do_test (u64 sample_type,u64 sample_regs_user,u64 read_format) +static int do_test (u64 sample_type,u64 sample_regs,u64 read_format) {struct perf_evsel evsel = { .needs_swap = false, .attr = { .sample_type = sample_type, - .sample_regs_user = sample_regs_user, .read_format = read_format, }, };
@@ -154,7 +166,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format)/* 1 branch_entry */ .data = {1, 211, 212, 213}, }; -u64 user_regs[64 ]; +u64 regs[64 ];const u64 raw_data[] = {0x123456780a0b0c0dULL ,0x1102030405060708ULL };const u64 data[] = {0x2211443366558877ULL ,0 ,0xaabbccddeeff4321ULL }; struct perf_sample sample = {
@@ -176,8 +188,8 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) .branch_stack = &branch_stack.branch_stack, .user_regs = { .abi = PERF_SAMPLE_REGS_ABI_64, - .mask = sample_regs_user, - .regs = user_regs, + .mask = sample_regs, + .regs = regs, }, .user_stack = { .size = sizeof(data),
@@ -187,14 +199,25 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) .time_enabled = 0x030a59d664fca7deULL, .time_running = 0x011b6ae553eb98edULL, }, + .intr_regs = { + .abi = PERF_SAMPLE_REGS_ABI_64, + .mask = sample_regs, + .regs = regs, + }, };struct sample_read_value values[] = {{1 ,5 }, {9 ,3 }, {2 ,7 }, {6 ,4 },};struct perf_sample sample_out;size_t i, sz, bufsz;int err, ret =-1 ; -for (i =0 ; i <sizeof (user_regs); i++) - *(i + (u8 *)user_regs) = i &0xfe ; +if (sample_type &PERF_SAMPLE_REGS_USER ) + evsel.attr.sample_regs_user = sample_regs; + +if (sample_type &PERF_SAMPLE_REGS_INTR ) + evsel.attr.sample_regs_intr = sample_regs; + +for (i =0 ; i <sizeof (regs); i++) + *(i + (u8 *)regs) = i &0xfe ;if (read_format &PERF_FORMAT_GROUP ) { sample.read.group.nr =4 ;
@@ -271,7 +294,7 @@ int test__sample_parsing(void) {const u64 rf[] = {4 ,5 ,6 ,7 ,12 ,13 ,14 ,15 };u64 sample_type; -u64 sample_regs_user; +u64 sample_regs;size_t i;int err;
@@ -280,7 +303,7 @@ int test__sample_parsing(void)* were added. Please actually update the test rather than just change * the condition below. */ -if (PERF_SAMPLE_MAX >PERF_SAMPLE_TRANSACTION <<1 ) { +if (PERF_SAMPLE_MAX >PERF_SAMPLE_REGS_INTR <<1 ) {pr_debug ("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n" );return -1 ; }
@@ -297,22 +320,24 @@ int test__sample_parsing(void) }continue ; } + sample_regs =0 ;if (sample_type ==PERF_SAMPLE_REGS_USER ) - sample_regs_user =0x3fff ; -else - sample_regs_user =0 ; + sample_regs =0x3fff ; + +if (sample_type ==PERF_SAMPLE_REGS_INTR ) + sample_regs =0xff0fff ; - err =do_test (sample_type, sample_regs_user,0 ); + err =do_test (sample_type, sample_regs,0 );if (err)return err; }/* Test all sample format bits together */ sample_type =PERF_SAMPLE_MAX -1 ; - sample_regs_user =0x3fff ; + sample_regs =0x3fff ;/* shared yb intr and user regs */ for (i =0 ; i <ARRAY_SIZE (rf); i++) { - err =do_test (sample_type, sample_regs_user, rf[i]); + err =do_test (sample_type, sample_regs, rf[i]);if (err)return err; }
PATCH v7 5/6 perf record: add new -I option to sample interrupted machine state
In reply to Stephane EranianAdd -I/--intr-regs option to capture machine state registers at interrupt.
Add the corresponding man page description
--- tools/perf/Documentation/perf-record.txt | 6 ++++++ tools/perf/builtin-record.c | 2 ++ 2 files changed, 8 insertions(+)
tools/perf/Documentation/perf-record.txt +6 -0
@@ -214,6 +214,12 @@ if combined with -a or -C options. After starting the program, wait msecs before measuring. This is useful to filter out the startup phase of the program, which is often very different. +-I:: +--intr-regs:: +Capture machine state (registers) at interrupt, i.e., on counter overflows for +each sample. List of captured registers depends on the architecture. This option +is off by default. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1]
tools/perf/builtin-record.c +2 -0
@@ -883,6 +883,8 @@ const struct option record_options[] = { "sample transaction flags (special events only)"),OPT_BOOLEAN (0 ,"per-thread" , &record.opts.target.per_thread,"use per-thread mmaps" ), +OPT_BOOLEAN ('I' ,"intr-regs" , &record.opts.sample_intr_regs, +"Sample machine registers on interrupt" ), OPT_END() };
Signature · 1 line
1.7.9.5
tip-bot for Stephane Eranian
merge bot[tip:perf/core] perf record: Add new -I option to sample interrupted machine state
perf record: Add new -I option to sample interrupted machine state
Commit-ID: 4b6c51773d86883a2e80cffadbe4f178ac1babd8 Gitweb: http://git.kernel.org/tip/4b6c51773d86883a2e80cffadbe4f178ac1babd8 Author: Stephane Eranian <[email protected]> AuthorDate: Wed, 24 Sep 2014 13:48:41 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 16 Nov 2014 11:42:02 +0100
perf record: Add new -I option to sample interrupted machine state
Add -I/--intr-regs option to capture machine state registers at interrupt.
Add the corresponding man page description
--- tools/perf/Documentation/perf-record.txt | 6 ++++++ tools/perf/builtin-record.c | 2 ++ 2 files changed, 8 insertions(+)
tools/perf/Documentation/perf-record.txt +6 -0
@@ -214,6 +214,12 @@ if combined with -a or -C options. After starting the program, wait msecs before measuring. This is useful to filter out the startup phase of the program, which is often very different. +-I:: +--intr-regs:: +Capture machine state (registers) at interrupt, i.e., on counter overflows for +each sample. List of captured registers depends on the architecture. This option +is off by default. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1]
tools/perf/builtin-record.c +2 -0
@@ -811,6 +811,8 @@ struct option __record_options[] = { "sample transaction flags (special events only)"),OPT_BOOLEAN (0 ,"per-thread" , &record.opts.target.per_thread,"use per-thread mmaps" ), +OPT_BOOLEAN ('I' ,"intr-regs" , &record.opts.sample_intr_regs, +"Sample machine registers on interrupt" ), OPT_END() };
PATCH v7 6/6 perf: improve perf_sample_data struct layout
In reply to Stephane EranianFrom: Peter Zijlstra <[email protected]>
This patch reorders fields in the perf_sample_data struct in order to minimize the number of cachelines touched in perf_sample_data_init(). It also removes some intializations which are redundant with the code in kernel/events/core.c
--- include/linux/perf_event.h | 34 +++++++++++++++++----------------- kernel/events/core.c | 5 ++++- 2 files changed, 21 insertions(+), 18 deletions(-)
include/linux/perf_event.h +17 -17
@@ -580,35 +580,40 @@ extern u64 perf_event_read_value(struct perf_event *event,struct perf_sample_data { -u64 type; +/* +* Fields set by perf_sample_data_init(), group so as to +* minimize the cachelines touched. +*/ +u64 addr; +struct perf_raw_record *raw; +struct perf_branch_stack *br_stack; +u64 period; +u64 weight; +u64 txn; +union perf_mem_data_src data_src; +/* +* The other fields, optionally {set,used} by +* perf_{prepare,output}_sample(). +*/ +u64 type;u64 ip;struct {u32 pid;u32 tid; } tid_entry;u64 time; -u64 addr;u64 id;u64 stream_id;struct {u32 cpu;u32 reserved; } cpu_entry; -u64 period; -union perf_mem_data_src data_src;struct perf_callchain_entry *callchain; -struct perf_raw_record *raw; -struct perf_branch_stack *br_stack;struct perf_regs regs_user;struct perf_regs regs_intr;u64 stack_user_size; -u64 weight; -/* -* Transaction flags for abort events: -*/ -u64 txn; -}; +}____cacheline_aligned ;/* default value for data source */ #define PERF_MEM_NA (PERF_MEM_S(OP, NA) |\
@@ -625,14 +630,9 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->raw =NULL ; data->br_stack =NULL ; data->period = period; - data->regs_user.abi =PERF_SAMPLE_REGS_ABI_NONE ; - data->regs_user.regs =NULL ; - data->stack_user_size =0 ; data->weight =0 ; data->data_src.val =PERF_MEM_NA ; data->txn =0 ; - data->regs_intr.abi =PERF_SAMPLE_REGS_ABI_NONE ; - data->regs_intr.regs =NULL ; } extern void perf_output_sample(struct perf_output_handle *handle,
kernel/events/core.c +4 -1
@@ -4441,8 +4441,11 @@ static void perf_sample_regs_user(struct perf_regs *regs_user, }if (regs) { - regs_user->regs = regs; regs_user->abi =perf_reg_abi (current); + regs_user->regs = regs; + }else { + regs_user->abi =PERF_SAMPLE_REGS_ABI_NONE ; + regs_user->regs =NULL ; } }
Signature · 1 line
1.7.9.5
tip-bot for Peter Zijlstra
merge bot[tip:perf/core] perf: Improve the perf_sample_data struct layout
perf: Improve the perf_sample_data struct layout
Commit-ID: 2565711fb7d7c28e0cd93c8971b520d1b10b857c Gitweb: http://git.kernel.org/tip/2565711fb7d7c28e0cd93c8971b520d1b10b857c Author: Peter Zijlstra <[email protected]> AuthorDate: Wed, 24 Sep 2014 13:48:42 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 16 Nov 2014 11:42:04 +0100
perf: Improve the perf_sample_data struct layout
This patch reorders fields in the perf_sample_data struct in order to minimize the number of cachelines touched in perf_sample_data_init(). It also removes some intializations which are redundant with the code in kernel/events/core.c
--- include/linux/perf_event.h | 34 +++++++++++++++++----------------- kernel/events/core.c | 16 ++++++++-------- 2 files changed, 25 insertions(+), 25 deletions(-)
include/linux/perf_event.h +17 -17
@@ -580,35 +580,40 @@ extern u64 perf_event_read_value(struct perf_event *event,struct perf_sample_data { -u64 type; +/* +* Fields set by perf_sample_data_init(), group so as to +* minimize the cachelines touched. +*/ +u64 addr; +struct perf_raw_record *raw; +struct perf_branch_stack *br_stack; +u64 period; +u64 weight; +u64 txn; +union perf_mem_data_src data_src; +/* +* The other fields, optionally {set,used} by +* perf_{prepare,output}_sample(). +*/ +u64 type;u64 ip;struct {u32 pid;u32 tid; } tid_entry;u64 time; -u64 addr;u64 id;u64 stream_id;struct {u32 cpu;u32 reserved; } cpu_entry; -u64 period; -union perf_mem_data_src data_src;struct perf_callchain_entry *callchain; -struct perf_raw_record *raw; -struct perf_branch_stack *br_stack;struct perf_regs regs_user;struct perf_regs regs_intr;u64 stack_user_size; -u64 weight; -/* -* Transaction flags for abort events: -*/ -u64 txn; -}; +}____cacheline_aligned ;/* default value for data source */ #define PERF_MEM_NA (PERF_MEM_S(OP, NA) |\
@@ -625,14 +630,9 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->raw =NULL ; data->br_stack =NULL ; data->period = period; - data->regs_user.abi =PERF_SAMPLE_REGS_ABI_NONE ; - data->regs_user.regs =NULL ; - data->stack_user_size =0 ; data->weight =0 ; data->data_src.val =PERF_MEM_NA ; data->txn =0 ; - data->regs_intr.abi =PERF_SAMPLE_REGS_ABI_NONE ; - data->regs_intr.regs =NULL ; } extern void perf_output_sample(struct perf_output_handle *handle,
kernel/events/core.c +8 -8
@@ -4471,8 +4471,11 @@ static void perf_sample_regs_user(struct perf_regs *regs_user, }if (regs) { - regs_user->regs = regs; regs_user->abi =perf_reg_abi (current); + regs_user->regs = regs; + }else { + regs_user->abi =PERF_SAMPLE_REGS_ABI_NONE ; + regs_user->regs =NULL ; } }
@@ -4947,12 +4950,13 @@ void perf_prepare_sample(struct perf_event_header *header, header->size += size; } +if (sample_type & (PERF_SAMPLE_REGS_USER |PERF_SAMPLE_STACK_USER )) +perf_sample_regs_user (&data->regs_user, regs); +if (sample_type &PERF_SAMPLE_REGS_USER ) {/* regs dump ABI info */ int size =sizeof (u64); -perf_sample_regs_user (&data->regs_user, regs); -if (data->regs_user.regs) {u64 mask = event->attr.sample_regs_user; size +=hweight64 (mask) *sizeof (u64);
@@ -4968,15 +4972,11 @@ void perf_prepare_sample(struct perf_event_header *header,* in case new sample type is added, because we could eat * up the rest of the sample size. */ -struct perf_regs *uregs = &data->regs_user;u16 stack_size = event->attr.sample_stack_user;u16 size =sizeof (u64); -if (!uregs->abi) -perf_sample_regs_user (uregs, regs); - stack_size =perf_sample_ustack_size (stack_size, header->size, - uregs->regs); + data->regs_user.regs);/* * If there is something to dump, add space for the dump
Peter Zijlstra
maintainerThese do indeed appear to compile just fine, thanks!
Arnaldo, may I gently prod you to pass judgement over the tools bits?
Peter,
Quoted 4 lines · Peter Zijlstra
These do indeed appear to compile just fine, thanks!
I posted v7 with the x86_32 fixes and the eflags changes. Is that what you compiled?
Quoted 1 line
Arnaldo, may I gently prod you to pass judgement over the tools bits?
Peter Zijlstra
maintainerQuoted 9 lines · Stephane Eranian
Peter,
Quoted 4 lines · Peter Zijlstra
These do indeed appear to compile just fine, thanks!
I posted v7 with the
x86_32fixes and the eflags changes. Is that what you compiled?
Yep, I grabbed the latest. I've not yet tried the x86_32 compile, but I did check the 'offending' patch and it has the #ifdef guard in place so I'll assume it works for now.
Quoted 6 lines · Peter Zijlstra
Quoted 5 lines · Stephane Eranian
Peter,
Quoted 2 lines · Peter Zijlstra
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
These do indeed appear to compile just fine, thanks!
I posted v7 with the
x86_32fixes and the eflags changes. Is that what you compiled?Yep, I grabbed the latest. I've not yet tried the
x86_32compile, but I did check the 'offending' patch and it has the #ifdef guard in place so I'll assume it works for now.
Yes, I compiled on my 32-bit Atom laptop. It compiles.