This patchset introduces conditional branch filter in perf branch stack
sampling framework incorporating review comments from Michael Neuling,
Peter Zijlstra and Stephane Eranian.
Anshuman Khandual (5):
perf: New conditional branch filter criteria in branch stack sampling
powerpc, perf: Enable conditional branch filter for POWER8
perf, tool: Conditional branch filter 'cond' added to perf record
x86, perf: Add conditional branch filtering support
perf, documentation: Description for conditional branch filter
arch/powerpc/perf/power8-pmu.c | 10 ++++++++++
arch/x86/kernel/cpu/perf_event_intel_lbr.c | 6 ++++++
include/uapi/linux/perf_event.h | 3 ++-
tools/perf/Documentation/perf-record.txt | 3 ++-
tools/perf/builtin-record.c | 1 +
5 files changed, 21 insertions(+), 2 deletions(-)
--
1.7.11.7
Enables conditional branch filter support for POWER8
utilizing MMCRA register based filter and also invalidates
a BHRB branch filter combination involving conditional
branches.
Signed-off-by: Anshuman Khandual <[email protected]>
---
arch/powerpc/perf/power8-pmu.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 8ed323d..e60b38f 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -548,11 +548,21 @@ static u64 power8_bhrb_filter_map(u64 branch_sample_type)
if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
return -1;
+ /* Invalid branch filter combination - HW does not support */
+ if ((branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) &&
+ (branch_sample_type & PERF_SAMPLE_BRANCH_COND))
+ return -1;
+
if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
pmu_bhrb_filter |= POWER8_MMCRA_IFM1;
return pmu_bhrb_filter;
}
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_COND) {
+ pmu_bhrb_filter |= POWER8_MMCRA_IFM3;
+ return pmu_bhrb_filter;
+ }
+
/* Every thing else is unsupported */
return -1;
}
--
1.7.11.7
Adding documentation support for conditional branch filter.
Signed-off-by: Anshuman Khandual <[email protected]>
---
tools/perf/Documentation/perf-record.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index d4da111..8b5e1ed 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -169,12 +169,13 @@ following filters are defined:
- any_call: any function call or system call
- any_ret: any function return or system call return
- ind_call: any indirect branch
+ - cond: conditional branches
- u: only when the branch target is at the user level
- k: only when the branch target is in the kernel
- hv: only when the target is at the hypervisor level
+
-The option requires at least one branch type among any, any_call, any_ret, ind_call.
+The option requires at least one branch type among any, any_call, any_ret, ind_call, cond.
The privilege levels may be omitted, in which case, the privilege levels of the associated
event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege
levels are subject to permissions. When sampling on multiple events, branch stack sampling
--
1.7.11.7
POWER8 PMU based BHRB supports filtering for conditional branches.
This patch introduces new branch filter PERF_SAMPLE_BRANCH_COND which
will extend the existing perf ABI. Other architectures can provide
this functionality with either HW filtering support (if present) or
with SW filtering of instructions.
Signed-off-by: Anshuman Khandual <[email protected]>
---
include/uapi/linux/perf_event.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index fb104e5..cb0de86 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -157,8 +157,9 @@ enum perf_branch_sample_type {
PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */
PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */
PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */
+ PERF_SAMPLE_BRANCH_COND = 1U << 7, /* conditional branches */
- PERF_SAMPLE_BRANCH_MAX = 1U << 7, /* non-ABI */
+ PERF_SAMPLE_BRANCH_MAX = 1U << 8, /* non-ABI */
};
#define PERF_SAMPLE_BRANCH_PLM_ALL \
--
1.7.11.7
Adding perf record support for new branch stack filter criteria
PERF_SAMPLE_BRANCH_COND.
Signed-off-by: Anshuman Khandual <[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 cdf58ec..833743a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -676,6 +676,7 @@ static const struct branch_mode branch_modes[] = {
BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
+ BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_CONDITIONAL),
BRANCH_END
};
--
1.7.11.7
From: Peter Zijlstra <[email protected]>
This patch adds conditional branch filtering support,
enabling it for PERF_SAMPLE_BRANCH_COND in perf branch
stack sampling framework by utilizing an available
software filter X86_BR_JCC.
Signed-off-by: Peter Zijlstra <[email protected]>
Signed-off-by: Anshuman Khandual <[email protected]>
---
arch/x86/kernel/cpu/perf_event_intel_lbr.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index d978353..a0d6387 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -337,6 +337,10 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
mask |= X86_BR_IND_CALL;
+
+ if (br_type & PERF_SAMPLE_BRANCH_COND)
+ mask |= X86_BR_JCC;
+
/*
* stash actual user request into reg, it may
* be used by fixup code for some CPU
@@ -626,6 +630,7 @@ static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX] = {
* NHM/WSM erratum: must include IND_JMP to capture IND_CALL
*/
[PERF_SAMPLE_BRANCH_IND_CALL] = LBR_IND_CALL | LBR_IND_JMP,
+ [PERF_SAMPLE_BRANCH_COND] = LBR_JCC,
};
static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX] = {
@@ -637,6 +642,7 @@ static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX] = {
[PERF_SAMPLE_BRANCH_ANY_CALL] = LBR_REL_CALL | LBR_IND_CALL
| LBR_FAR,
[PERF_SAMPLE_BRANCH_IND_CALL] = LBR_IND_CALL,
+ [PERF_SAMPLE_BRANCH_COND] = LBR_JCC,
};
/* core */
--
1.7.11.7
On Wed, May 22, 2013 at 11:52:38AM +0530, Anshuman Khandual wrote:
> Enables conditional branch filter support for POWER8
> utilizing MMCRA register based filter and also invalidates
> a BHRB branch filter combination involving conditional
> branches.
>
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> arch/powerpc/perf/power8-pmu.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
> index 8ed323d..e60b38f 100644
> --- a/arch/powerpc/perf/power8-pmu.c
> +++ b/arch/powerpc/perf/power8-pmu.c
> @@ -548,11 +548,21 @@ static u64 power8_bhrb_filter_map(u64 branch_sample_type)
> if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
> return -1;
>
> + /* Invalid branch filter combination - HW does not support */
> + if ((branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) &&
> + (branch_sample_type & PERF_SAMPLE_BRANCH_COND))
> + return -1;
> +
> if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
> pmu_bhrb_filter |= POWER8_MMCRA_IFM1;
> return pmu_bhrb_filter;
> }
>
> + if (branch_sample_type & PERF_SAMPLE_BRANCH_COND) {
> + pmu_bhrb_filter |= POWER8_MMCRA_IFM3;
> + return pmu_bhrb_filter;
> + }
> +
> /* Every thing else is unsupported */
> return -1;
> }
So I suppose you've seen what x86 does in this case? ;-) I'm not saying
you _have_ to do the software filter, but I would like the changelog to at
least mention the issue.
In fact, I suppose that should have been in the original patches :/ as
this patch series only adds the conditional branch support.
Peter Zijlstra <[email protected]> wrote:
> On Wed, May 22, 2013 at 11:52:38AM +0530, Anshuman Khandual wrote:
> > Enables conditional branch filter support for POWER8
> > utilizing MMCRA register based filter and also invalidates
> > a BHRB branch filter combination involving conditional
> > branches.
> >
> > Signed-off-by: Anshuman Khandual <[email protected]>
> > ---
> > arch/powerpc/perf/power8-pmu.c | 10 ++++++++++
> > 1 file changed, 10 insertions(+)
> >
> > diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
> > index 8ed323d..e60b38f 100644
> > --- a/arch/powerpc/perf/power8-pmu.c
> > +++ b/arch/powerpc/perf/power8-pmu.c
> > @@ -548,11 +548,21 @@ static u64 power8_bhrb_filter_map(u64 branch_sample_type)
> > if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
> > return -1;
> >
> > + /* Invalid branch filter combination - HW does not support */
> > + if ((branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) &&
> > + (branch_sample_type & PERF_SAMPLE_BRANCH_COND))
> > + return -1;
> > +
> > if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
> > pmu_bhrb_filter |= POWER8_MMCRA_IFM1;
> > return pmu_bhrb_filter;
> > }
> >
> > + if (branch_sample_type & PERF_SAMPLE_BRANCH_COND) {
> > + pmu_bhrb_filter |= POWER8_MMCRA_IFM3;
> > + return pmu_bhrb_filter;
> > + }
> > +
> > /* Every thing else is unsupported */
> > return -1;
> > }
>
> So I suppose you've seen what x86 does in this case? ;-) I'm not saying
> you _have_ to do the software filter, but I would like the changelog to at
> least mention the issue.
>
> In fact, I suppose that should have been in the original patches :/ as
> this patch series only adds the conditional branch support.
Anshuman,
Now we have the branch reading and parsing code (for the "to" case), we
should use that to do what Peter is suggesting.
Mikey
On Wed, May 22, 2013 at 8:22 AM, Anshuman Khandual
<[email protected]> wrote:
> POWER8 PMU based BHRB supports filtering for conditional branches.
> This patch introduces new branch filter PERF_SAMPLE_BRANCH_COND which
> will extend the existing perf ABI. Other architectures can provide
> this functionality with either HW filtering support (if present) or
> with SW filtering of instructions.
>
Reviewed-by: Stephane Eranian <[email protected]>
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> include/uapi/linux/perf_event.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index fb104e5..cb0de86 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -157,8 +157,9 @@ enum perf_branch_sample_type {
> PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */
> PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */
> PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */
> + PERF_SAMPLE_BRANCH_COND = 1U << 7, /* conditional branches */
>
> - PERF_SAMPLE_BRANCH_MAX = 1U << 7, /* non-ABI */
> + PERF_SAMPLE_BRANCH_MAX = 1U << 8, /* non-ABI */
> };
>
> #define PERF_SAMPLE_BRANCH_PLM_ALL \
> --
> 1.7.11.7
>
On Wed, May 22, 2013 at 8:22 AM, Anshuman Khandual
<[email protected]> wrote:
> From: Peter Zijlstra <[email protected]>
>
> This patch adds conditional branch filtering support,
> enabling it for PERF_SAMPLE_BRANCH_COND in perf branch
> stack sampling framework by utilizing an available
> software filter X86_BR_JCC.
>
Reviewed-by: Stephane Eranian <[email protected]>
> Signed-off-by: Peter Zijlstra <[email protected]>
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> arch/x86/kernel/cpu/perf_event_intel_lbr.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
> index d978353..a0d6387 100644
> --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
> +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
> @@ -337,6 +337,10 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
>
> if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
> mask |= X86_BR_IND_CALL;
> +
> + if (br_type & PERF_SAMPLE_BRANCH_COND)
> + mask |= X86_BR_JCC;
> +
> /*
> * stash actual user request into reg, it may
> * be used by fixup code for some CPU
> @@ -626,6 +630,7 @@ static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX] = {
> * NHM/WSM erratum: must include IND_JMP to capture IND_CALL
> */
> [PERF_SAMPLE_BRANCH_IND_CALL] = LBR_IND_CALL | LBR_IND_JMP,
> + [PERF_SAMPLE_BRANCH_COND] = LBR_JCC,
> };
>
> static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX] = {
> @@ -637,6 +642,7 @@ static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX] = {
> [PERF_SAMPLE_BRANCH_ANY_CALL] = LBR_REL_CALL | LBR_IND_CALL
> | LBR_FAR,
> [PERF_SAMPLE_BRANCH_IND_CALL] = LBR_IND_CALL,
> + [PERF_SAMPLE_BRANCH_COND] = LBR_JCC,
> };
>
> /* core */
> --
> 1.7.11.7
>
On Wed, May 22, 2013 at 8:22 AM, Anshuman Khandual
<[email protected]> wrote:
> Adding documentation support for conditional branch filter.
>
Reviewed-by: Stephane Eranian <[email protected]>
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> tools/perf/Documentation/perf-record.txt | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> index d4da111..8b5e1ed 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -169,12 +169,13 @@ following filters are defined:
> - any_call: any function call or system call
> - any_ret: any function return or system call return
> - ind_call: any indirect branch
> + - cond: conditional branches
> - u: only when the branch target is at the user level
> - k: only when the branch target is in the kernel
> - hv: only when the target is at the hypervisor level
>
> +
> -The option requires at least one branch type among any, any_call, any_ret, ind_call.
> +The option requires at least one branch type among any, any_call, any_ret, ind_call, cond.
> The privilege levels may be omitted, in which case, the privilege levels of the associated
> event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege
> levels are subject to permissions. When sampling on multiple events, branch stack sampling
> --
> 1.7.11.7
>