linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: James Clark <james.clark@arm.com>
To: Anshuman Khandual <anshuman.khandual@arm.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	linux-perf-users@vger.kernel.org, Jiri Olsa <jolsa@redhat.com>,
	Namhyung Kim <namhyung@kernel.org>,
	Rob Herring <rob.herring@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>
Subject: Re: [RFC V1 11/11] perf: Capture branch privilege information
Date: Wed, 26 Jan 2022 17:27:19 +0000	[thread overview]
Message-ID: <b85da904-50cb-b7e3-1429-6f5ef244567b@arm.com> (raw)
In-Reply-To: <1642998653-21377-12-git-send-email-anshuman.khandual@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> Platforms like arm64 could capture privilege level information for all the
> branch records. Hence this adds a new element in the struct branch_entry to
> record the privilege level information, which could be requested through a
> new event.attr.branch_sample_type flag PERF_SAMPLE_BRANCH_PRIV_SAVE. While
> here, update the BRBE driver as required.
> 
> Cc: Will Deacon <will@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-perf-users@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>  drivers/perf/arm_pmu_brbe.c              | 28 ++++++++++++++++++++++++
>  include/linux/perf_event.h               |  5 +++++
>  include/uapi/linux/perf_event.h          | 13 ++++++++++-
>  tools/include/uapi/linux/perf_event.h    | 13 ++++++++++-
>  tools/perf/Documentation/perf-record.txt |  1 +
>  tools/perf/util/parse-branch-options.c   |  1 +
>  6 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
> index 7cd1208c6c58..d4cbea74c148 100644
> --- a/drivers/perf/arm_pmu_brbe.c
> +++ b/drivers/perf/arm_pmu_brbe.c
> @@ -270,6 +270,25 @@ static int brbe_fetch_perf_type(u64 brbinf)
>  	}
>  }
>  
> +static int brbe_fetch_perf_priv(u64 brbinf)
> +{
> +	int brbe_el = brbe_fetch_el(brbinf);
> +
> +	switch (brbe_el) {
> +	case BRBINF_EL_EL0:
> +		return PERF_BR_USER;
> +	case BRBINF_EL_EL1:
> +		return PERF_BR_KERNEL;
> +	case BRBINF_EL_EL2:
> +		if (is_kernel_in_hyp_mode())
> +			return PERF_BR_KERNEL;
> +		return PERF_BR_HV;
> +	default:
> +		pr_warn("unknown branch privilege captured\n");
> +		return -1;
> +	}
> +}
> +
>  static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *event,
>  			       u64 brbinf, int idx)
>  {
> @@ -302,6 +321,15 @@ static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *ev
>  			cpuc->brbe_entries[idx].in_tx = brbinf & BRBINF_TX;
>  		}
>  	}
> +
> +	if (branch_sample_priv(event)) {
> +		/*
> +		 * All these information (i.e branch privilege level) are not
> +		 * available for source only branch records.
> +		 */
> +		if (type != BRBINF_VALID_SOURCE)
> +			cpuc->brbe_entries[idx].priv = brbe_fetch_perf_priv(brbinf);
> +	}
>  }
>  
>  /*
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 916ce5102b33..8021b6a30d86 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -1688,4 +1688,9 @@ static inline bool branch_sample_hw_index(const struct perf_event *event)
>  {
>  	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
>  }
> +
> +static inline bool branch_sample_priv(const struct perf_event *event)
> +{
> +	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_PRIV_SAVE;
> +}
>  #endif /* _LINUX_PERF_EVENT_H */
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index 361fdc6b87a0..4d77710f7a4e 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
> +
>  	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
>  };
>  
> @@ -233,6 +235,8 @@ enum perf_branch_sample_type {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
> +
>  	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
>  };
>  
> @@ -265,6 +269,12 @@ enum {
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_USER	= 0,
> +	PERF_BR_KERNEL	= 1,
> +	PERF_BR_HV	= 2,
> +};
> +

Can we have 0 as "UNKNOWN". It's going to be difficult to parse files when privilege information
isn't saved and get accurate results without that. For example if it's not set then presumably
the field would be 0 (PERF_BR_USER), but that doesn't mean the samples are user in that case.

I know you might be able to go backwards and look at what arguments were passed to the kernel but
it's not guaranteed that the kernel honored the request anyway. There are also other platforms
to think about etc.

If you look at the branch type definitions above they start at 0 (PERF_BR_UNKNOWN) which I think
works out quite nicely in the userspace code.

>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1377,7 +1387,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:6,     /* branch type */
> -		reserved:38;
> +		priv:2,     /* privilege level */> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index 9a82b8aaed93..a2208400b0b9 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
> +
>  	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
>  };
>  
> @@ -233,6 +235,8 @@ enum perf_branch_sample_type {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
> +
>  	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
>  };
>  
> @@ -265,6 +269,12 @@ enum {
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_USER    = 0,
> +	PERF_BR_KERNEL  = 1,
> +	PERF_BR_HV      = 2,
> +};
> +
>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1377,7 +1387,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:6,     /* branch type */
> -		reserved:38;
> +		priv:2,     /* privilege level */
> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> index 9ccc75935bc5..3e33686977a1 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -387,6 +387,7 @@ following filters are defined:
>  	- abort_tx: only when the target is a hardware transaction abort
>  	- cond: conditional branches
>  	- save_type: save branch type during sampling in case binary is not available later
> +	- priv: save privilege state during sampling in case binary is not available later
>  
>  +
>  The option requires at least one branch type among any, any_call, any_ret, ind_call, cond.
> diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
> index bb4aa88c50a8..00588b9db474 100644
> --- a/tools/perf/util/parse-branch-options.c
> +++ b/tools/perf/util/parse-branch-options.c
> @@ -32,6 +32,7 @@ static const struct branch_mode branch_modes[] = {
>  	BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL),
>  	BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE),
>  	BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK),
> +	BRANCH_OPT("priv", PERF_SAMPLE_BRANCH_PRIV_SAVE),
>  	BRANCH_END
>  };
>  
> 

  parent reply	other threads:[~2022-01-26 17:27 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-24  4:30 [RFC V1 00/11] arm64/perf: Enable branch stack sampling Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 01/11] perf: Consolidate branch sample filter helpers Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 02/11] arm64/perf: Add register definitions for BRBE Anshuman Khandual
2022-01-24 14:05   ` Marc Zyngier
2022-01-25  5:04     ` Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 03/11] arm64/perf: Update struct arm_pmu " Anshuman Khandual
2022-01-26 16:59   ` Rob Herring
2022-01-28  3:38     ` Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 04/11] arm64/perf: Update struct pmu_hw_events " Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 05/11] arm64/perf: Detect support " Anshuman Khandual
2022-01-26 17:18   ` Rob Herring
2022-01-28  3:27     ` Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 06/11] arm64/perf: Drive BRBE from perf event states Anshuman Khandual
2022-01-26 17:07   ` Rob Herring
2022-01-27 12:20     ` Anshuman Khandual
2022-01-27 14:31       ` Rob Herring
2022-01-24  4:30 ` [RFC V1 07/11] arm64/perf: Add BRBE driver Anshuman Khandual
2022-01-24 18:11   ` James Clark
2022-01-24 18:15   ` James Clark
2022-01-24  4:30 ` [RFC V1 08/11] arm64/perf: Enable branch stack sampling Anshuman Khandual
2022-01-24 18:02   ` James Clark
2022-01-24  4:30 ` [RFC V1 09/11] perf: Add more generic branch types Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 10/11] perf: Expand perf_branch_entry.type Anshuman Khandual
2022-01-25 16:58   ` James Clark
2022-01-28  4:14     ` Anshuman Khandual
2022-01-26 16:47   ` Rob Herring
2022-01-27 10:41     ` Anshuman Khandual
2022-01-24  4:30 ` [RFC V1 11/11] perf: Capture branch privilege information Anshuman Khandual
2022-01-25 15:39   ` James Clark
2022-02-02 11:11     ` Anshuman Khandual
2022-01-26 17:27   ` James Clark [this message]
2022-03-14  6:47     ` Anshuman Khandual
2022-01-25 16:25 ` [PATCH 0/1] perf test: Add branch stack sampling tests for ARM64 German Gomez
2022-01-25 16:25   ` [PATCH 1/1] " German Gomez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b85da904-50cb-b7e3-1429-6f5ef244567b@arm.com \
    --to=james.clark@arm.com \
    --cc=acme@kernel.org \
    --cc=anshuman.khandual@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=jolsa@redhat.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rob.herring@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).