2015-05-14 21:10:08

by Stephane Eranian

[permalink] [raw]
Subject: [PATCH v1 0/3] perf: add indirect jump filtering support

This short patch series adds a new filter to the branch stack
sampling feature. The new filter enables sampling only indirect
jumps. For each the source and target are captured.

The new branch_sample_type flag is: PERF_SAMPLE_BRANCH_IND_JUMP

The series provides full support in the perf record tool:

$ perf record -j ind_jmp ...

On Intel x86 processors, the filter is implemented using the
LBR hw filter.

This filter is useful to study targets of indirect jumps.

Stephane Eranian (3):
perf: add new PERF_SAMPLE_BRANCH_IND_JUMP branch sample type
perf/x86: add support for PERF_SAMPLE_BRANCH_IND_JUMP
perf record: add support for sampling indirect jumps

arch/x86/kernel/cpu/perf_event_intel_lbr.c | 10 +++++++++-
include/uapi/linux/perf_event.h | 2 ++
tools/perf/builtin-record.c | 1 +
3 files changed, 12 insertions(+), 1 deletion(-)

--
1.9.1


2015-05-14 21:10:17

by Stephane Eranian

[permalink] [raw]
Subject: [PATCH v1 1/3] perf: add new PERF_SAMPLE_BRANCH_IND_JUMP branch sample type

This patch adds a new branch_sample_type flag to enable
filtering branch sampling to indirect jumps. The support
is subject to hardware or kernel software support on each
architecture.

Filtering on indirect jump is useful to study the targets
of the jump.

Signed-off-by: Stephane Eranian <[email protected]>
---
include/uapi/linux/perf_event.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 309211b..c4622f1 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -167,6 +167,7 @@ enum perf_branch_sample_type_shift {
PERF_SAMPLE_BRANCH_COND_SHIFT = 10, /* conditional branches */

PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 11, /* call/ret stack */
+ PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT = 12, /* indirect jumps */

PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
};
@@ -186,6 +187,7 @@ enum perf_branch_sample_type {
PERF_SAMPLE_BRANCH_COND = 1U << PERF_SAMPLE_BRANCH_COND_SHIFT,

PERF_SAMPLE_BRANCH_CALL_STACK = 1U << PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT,
+ PERF_SAMPLE_BRANCH_IND_JUMP = 1U << PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT,

PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
};
--
1.9.1

2015-05-14 21:10:25

by Stephane Eranian

[permalink] [raw]
Subject: [PATCH v1 2/3] perf/x86: add support for PERF_SAMPLE_BRANCH_IND_JUMP

This patch enables support for branch sampling filter
for indirect jumps (IND_JUMP). It enables LBR IND_JMP
filtering where available. There is also software filtering
support.

Signed-off-by: Stephane Eranian <[email protected]>
---
arch/x86/kernel/cpu/perf_event_intel_lbr.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 94e5b50..201e16f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -96,6 +96,7 @@ enum {
X86_BR_NO_TX = 1 << 14,/* not in transaction */
X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
X86_BR_CALL_STACK = 1 << 16,/* call stack */
+ X86_BR_IND_JMP = 1 << 17,/* indirect jump */
};

#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
@@ -113,6 +114,7 @@ enum {
X86_BR_IRQ |\
X86_BR_ABORT |\
X86_BR_IND_CALL |\
+ X86_BR_IND_JMP |\
X86_BR_ZERO_CALL)

#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
@@ -523,6 +525,9 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
X86_BR_CALL_STACK;
}

+ if (br_type & PERF_SAMPLE_BRANCH_IND_JUMP)
+ mask |= X86_BR_IND_JMP;
+
/*
* stash actual user request into reg, it may
* be used by fixup code for some CPU
@@ -736,7 +741,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
break;
case 4:
case 5:
- ret = X86_BR_JMP;
+ ret = X86_BR_IND_JMP;
break;
}
break;
@@ -844,6 +849,7 @@ static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
*/
[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL | LBR_IND_JMP,
[PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
};

static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
@@ -856,6 +862,7 @@ static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
| LBR_FAR,
[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL,
[PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
};

static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
@@ -870,6 +877,7 @@ static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
[PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
| LBR_RETURN | LBR_CALL_STACK,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
};

/* core */
--
1.9.1

2015-05-14 21:10:22

by Stephane Eranian

[permalink] [raw]
Subject: [PATCH v1 3/3] perf record: add support for sampling indirect jumps

This patch adds a new branch sampling type support for indirect jumps:

perf record -j ind_jmp .......

It enables analysis of indirect jumps targets. It requires kernel and
possibly hardware support to operate correctly.

Signed-off-by: Stephane Eranian <[email protected]>
---
tools/perf/builtin-record.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 5dfe913..860c133 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -773,6 +773,7 @@ static const struct branch_mode branch_modes[] = {
BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX),
BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND),
+ BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP),
BRANCH_END
};

--
1.9.1

2015-05-14 23:04:05

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH v1 0/3] perf: add indirect jump filtering support

On Thu, May 14, 2015 at 11:09:57PM +0200, Stephane Eranian wrote:
> This short patch series adds a new filter to the branch stack
> sampling feature. The new filter enables sampling only indirect
> jumps. For each the source and target are captured.
>
> The new branch_sample_type flag is: PERF_SAMPLE_BRANCH_IND_JUMP
>
> The series provides full support in the perf record tool:
>
> $ perf record -j ind_jmp ...
>
> On Intel x86 processors, the filter is implemented using the
> LBR hw filter.
>
> This filter is useful to study targets of indirect jumps.

Patches look all good to me.
Reviewed-by: Andi Kleen <[email protected]>
-Andi

Subject: [tip:perf/core] perf: add new PERF_SAMPLE_BRANCH_IND_JUMP branch sample type

Commit-ID: c9fdfa14c3792c0160849c484e83aa57afd80ccc
Gitweb: http://git.kernel.org/tip/c9fdfa14c3792c0160849c484e83aa57afd80ccc
Author: Stephane Eranian <[email protected]>
AuthorDate: Thu, 14 May 2015 23:09:58 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sun, 7 Jun 2015 16:08:22 +0200

perf: add new PERF_SAMPLE_BRANCH_IND_JUMP branch sample type

This patch adds a new branch_sample_type flag to enable
filtering branch sampling to indirect jumps. The support
is subject to hardware or kernel software support on each
architecture.

Filtering on indirect jump is useful to study the targets
of the jump.

Signed-off-by: Stephane Eranian <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
include/uapi/linux/perf_event.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 309211b..c4622f1 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -167,6 +167,7 @@ enum perf_branch_sample_type_shift {
PERF_SAMPLE_BRANCH_COND_SHIFT = 10, /* conditional branches */

PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 11, /* call/ret stack */
+ PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT = 12, /* indirect jumps */

PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
};
@@ -186,6 +187,7 @@ enum perf_branch_sample_type {
PERF_SAMPLE_BRANCH_COND = 1U << PERF_SAMPLE_BRANCH_COND_SHIFT,

PERF_SAMPLE_BRANCH_CALL_STACK = 1U << PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT,
+ PERF_SAMPLE_BRANCH_IND_JUMP = 1U << PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT,

PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
};

Subject: [tip:perf/core] perf/x86/intel: add support for PERF_SAMPLE_BRANCH_IND_JUMP

Commit-ID: 7b74cfb2ecb4d56a25c89cdb561e4926db85feb1
Gitweb: http://git.kernel.org/tip/7b74cfb2ecb4d56a25c89cdb561e4926db85feb1
Author: Stephane Eranian <[email protected]>
AuthorDate: Thu, 14 May 2015 23:09:59 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sun, 7 Jun 2015 16:08:27 +0200

perf/x86/intel: add support for PERF_SAMPLE_BRANCH_IND_JUMP

This patch enables support for branch sampling filter
for indirect jumps (IND_JUMP). It enables LBR IND_JMP
filtering where available. There is also software filtering
support.

Signed-off-by: Stephane Eranian <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/kernel/cpu/perf_event_intel_lbr.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 94e5b50..201e16f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -96,6 +96,7 @@ enum {
X86_BR_NO_TX = 1 << 14,/* not in transaction */
X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
X86_BR_CALL_STACK = 1 << 16,/* call stack */
+ X86_BR_IND_JMP = 1 << 17,/* indirect jump */
};

#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
@@ -113,6 +114,7 @@ enum {
X86_BR_IRQ |\
X86_BR_ABORT |\
X86_BR_IND_CALL |\
+ X86_BR_IND_JMP |\
X86_BR_ZERO_CALL)

#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
@@ -523,6 +525,9 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
X86_BR_CALL_STACK;
}

+ if (br_type & PERF_SAMPLE_BRANCH_IND_JUMP)
+ mask |= X86_BR_IND_JMP;
+
/*
* stash actual user request into reg, it may
* be used by fixup code for some CPU
@@ -736,7 +741,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
break;
case 4:
case 5:
- ret = X86_BR_JMP;
+ ret = X86_BR_IND_JMP;
break;
}
break;
@@ -844,6 +849,7 @@ static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
*/
[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL | LBR_IND_JMP,
[PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
};

static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
@@ -856,6 +862,7 @@ static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
| LBR_FAR,
[PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL,
[PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
};

static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
@@ -870,6 +877,7 @@ static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
[PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
| LBR_RETURN | LBR_CALL_STACK,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
};

/* core */

Subject: [tip:perf/core] perf record: Add support for sampling indirect jumps

Commit-ID: 5b68164d6a1fdbe02b30bd777d1f686c6d901f28
Gitweb: http://git.kernel.org/tip/5b68164d6a1fdbe02b30bd777d1f686c6d901f28
Author: Stephane Eranian <[email protected]>
AuthorDate: Thu, 14 May 2015 23:10:00 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Sun, 7 Jun 2015 16:08:31 +0200

perf record: Add support for sampling indirect jumps

This patch adds a new branch sampling type support for indirect jumps:

perf record -j ind_jmp .......

It enables analysis of indirect jumps targets. It requires kernel and
possibly hardware support to operate correctly.

Signed-off-by: Stephane Eranian <[email protected]>
[ Fixup against: f00898f4e20b (perf tools: Move branch option parsing to own file) ]
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>

Signed-off-by: Ingo Molnar <[email protected]>
---
tools/perf/util/parse-branch-options.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
index 9d99943..a3b1e13 100644
--- a/tools/perf/util/parse-branch-options.c
+++ b/tools/perf/util/parse-branch-options.c
@@ -26,6 +26,7 @@ static const struct branch_mode branch_modes[] = {
BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX),
BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND),
+ BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP),
BRANCH_END
};