diff mbox series

[v4,10/11] perf env: Set flag for kernel is 64-bit mode

Message ID 20210711104105.505728-11-leo.yan@linaro.org (mailing list archive)
State New, archived
Headers show
Series perf: Refine barriers for AUX ring buffer | expand

Commit Message

Leo Yan July 11, 2021, 10:41 a.m. UTC
It's useful to know that the kernel is running in 32-bit or 64-bit
mode.  E.g. We can decide if perf tool is running in compat mode
from this info.

This patch adds a global variable "kernel_is_64_bit", it's initialized
when a session setups environment, its value is decided by checking the
architecture string.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
 tools/perf/util/env.c | 17 ++++++++++++++++-
 tools/perf/util/env.h |  1 +
 2 files changed, 17 insertions(+), 1 deletion(-)

Comments

Adrian Hunter July 12, 2021, 2:37 p.m. UTC | #1
On 11/07/21 1:41 pm, Leo Yan wrote:
> It's useful to know that the kernel is running in 32-bit or 64-bit
> mode.  E.g. We can decide if perf tool is running in compat mode
> from this info.
> 
> This patch adds a global variable "kernel_is_64_bit", it's initialized
> when a session setups environment, its value is decided by checking the
> architecture string.
> 
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> ---
>  tools/perf/util/env.c | 17 ++++++++++++++++-
>  tools/perf/util/env.h |  1 +
>  2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
> index ebc5e9ad35db..345635a2e842 100644
> --- a/tools/perf/util/env.c
> +++ b/tools/perf/util/env.c
> @@ -11,6 +11,7 @@
>  #include <stdlib.h>
>  #include <string.h>
>  
> +int kernel_is_64_bit;
>  struct perf_env perf_env;
>  
>  #ifdef HAVE_LIBBPF_SUPPORT
> @@ -172,6 +173,19 @@ static void perf_env__purge_bpf(struct perf_env *env __maybe_unused)
>  }
>  #endif // HAVE_LIBBPF_SUPPORT
>  
> +static void perf_env__init_kernel_mode(struct perf_env *env)
> +{
> +	const char *arch = perf_env__raw_arch(env);
> +
> +	if (!strncmp(arch, "x86_64", 6) || !strncmp(arch, "aarch64", 7) ||
> +	    !strncmp(arch, "arm64", 5) || !strncmp(arch, "mips64", 6) ||
> +	    !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
> +	    !strncmp(arch, "s390x", 5) || !strncmp(arch, "sparc64", 7))
> +		kernel_is_64_bit = 1;
> +	else
> +		kernel_is_64_bit = 0;
> +}
> +
>  void perf_env__exit(struct perf_env *env)
>  {
>  	int i;
> @@ -217,13 +231,14 @@ void perf_env__exit(struct perf_env *env)
>  	zfree(&env->hybrid_cpc_nodes);
>  }
>  
> -void perf_env__init(struct perf_env *env __maybe_unused)
> +void perf_env__init(struct perf_env *env)
>  {
>  #ifdef HAVE_LIBBPF_SUPPORT
>  	env->bpf_progs.infos = RB_ROOT;
>  	env->bpf_progs.btfs = RB_ROOT;
>  	init_rwsem(&env->bpf_progs.lock);
>  #endif
> +	perf_env__init_kernel_mode(env);

perf_env__init() is also used for session->header.env which is not
necessarily the current machine.  So this initialization could be
separate from perf_env__init() to avoid confusion.

>  }
>  
>  int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 6824a7423a2d..cc989ff49740 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -139,6 +139,7 @@ enum perf_compress_type {
>  struct bpf_prog_info_node;
>  struct btf_node;
>  
> +extern int kernel_is_64_bit;
>  extern struct perf_env perf_env;
>  
>  void perf_env__exit(struct perf_env *env);
>
Arnaldo Carvalho de Melo July 12, 2021, 6:14 p.m. UTC | #2
Em Sun, Jul 11, 2021 at 06:41:04PM +0800, Leo Yan escreveu:
> It's useful to know that the kernel is running in 32-bit or 64-bit
> mode.  E.g. We can decide if perf tool is running in compat mode
> from this info.
> 
> This patch adds a global variable "kernel_is_64_bit", it's initialized
> when a session setups environment, its value is decided by checking the
> architecture string.
> 
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> ---
>  tools/perf/util/env.c | 17 ++++++++++++++++-
>  tools/perf/util/env.h |  1 +
>  2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
> index ebc5e9ad35db..345635a2e842 100644
> --- a/tools/perf/util/env.c
> +++ b/tools/perf/util/env.c
> @@ -11,6 +11,7 @@
>  #include <stdlib.h>
>  #include <string.h>
>  
> +int kernel_is_64_bit;
>  struct perf_env perf_env;

Why can't this be in 'struct perf_env'?

- Arnaldo
  
>  #ifdef HAVE_LIBBPF_SUPPORT
> @@ -172,6 +173,19 @@ static void perf_env__purge_bpf(struct perf_env *env __maybe_unused)
>  }
>  #endif // HAVE_LIBBPF_SUPPORT
>  
> +static void perf_env__init_kernel_mode(struct perf_env *env)
> +{
> +	const char *arch = perf_env__raw_arch(env);
> +
> +	if (!strncmp(arch, "x86_64", 6) || !strncmp(arch, "aarch64", 7) ||
> +	    !strncmp(arch, "arm64", 5) || !strncmp(arch, "mips64", 6) ||
> +	    !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
> +	    !strncmp(arch, "s390x", 5) || !strncmp(arch, "sparc64", 7))
> +		kernel_is_64_bit = 1;
> +	else
> +		kernel_is_64_bit = 0;
> +}
> +
>  void perf_env__exit(struct perf_env *env)
>  {
>  	int i;
> @@ -217,13 +231,14 @@ void perf_env__exit(struct perf_env *env)
>  	zfree(&env->hybrid_cpc_nodes);
>  }
>  
> -void perf_env__init(struct perf_env *env __maybe_unused)
> +void perf_env__init(struct perf_env *env)
>  {
>  #ifdef HAVE_LIBBPF_SUPPORT
>  	env->bpf_progs.infos = RB_ROOT;
>  	env->bpf_progs.btfs = RB_ROOT;
>  	init_rwsem(&env->bpf_progs.lock);
>  #endif
> +	perf_env__init_kernel_mode(env);
>  }
>  
>  int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 6824a7423a2d..cc989ff49740 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -139,6 +139,7 @@ enum perf_compress_type {
>  struct bpf_prog_info_node;
>  struct btf_node;
>  
> +extern int kernel_is_64_bit;
>  extern struct perf_env perf_env;
>  
>  void perf_env__exit(struct perf_env *env);
> -- 
> 2.25.1
>
Leo Yan July 13, 2021, 3:09 p.m. UTC | #3
Hi Arnaldo, Adrian,

On Mon, Jul 12, 2021 at 03:14:35PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Sun, Jul 11, 2021 at 06:41:04PM +0800, Leo Yan escreveu:
> > It's useful to know that the kernel is running in 32-bit or 64-bit
> > mode.  E.g. We can decide if perf tool is running in compat mode
> > from this info.
> > 
> > This patch adds a global variable "kernel_is_64_bit", it's initialized
> > when a session setups environment, its value is decided by checking the
> > architecture string.
> > 
> > Signed-off-by: Leo Yan <leo.yan@linaro.org>
> > ---
> >  tools/perf/util/env.c | 17 ++++++++++++++++-
> >  tools/perf/util/env.h |  1 +
> >  2 files changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
> > index ebc5e9ad35db..345635a2e842 100644
> > --- a/tools/perf/util/env.c
> > +++ b/tools/perf/util/env.c
> > @@ -11,6 +11,7 @@
> >  #include <stdlib.h>
> >  #include <string.h>
> >  
> > +int kernel_is_64_bit;
> >  struct perf_env perf_env;
> 
> Why can't this be in 'struct perf_env'?

Good question.  I considered to add it in struct perf_env but finally
I used this way; the reason is this variable "kernel_is_64_bit" is only
used during recording phase for AUX ring buffer, and don't use it for
report.  So seems to me it's over complexity to add a new field and
just wander if it's necessary to save this field as new feature in the
perf header.

Combining the comment from Adrian in another email, I think it's good
to add a new field "compat_mode" in the struct perf_env, and this field
will be initialized in build-record.c.  Currently we don't need to save
this value into the perf file, if later we need to use this value for
decoding phase, then we can add a new feature item to save "compat_mode"
into the perf file's header.

If you have any different idea, please let me know.  Thanks!

Leo
Adrian Hunter July 13, 2021, 5:31 p.m. UTC | #4
> -----Original Message-----
> From: Leo Yan <leo.yan@linaro.org>
> Sent: Tuesday, July 13, 2021 6:10 PM
> To: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Hunter, Adrian <adrian.hunter@intel.com>; Peter Zijlstra
> <peterz@infradead.org>; Ingo Molnar <mingo@redhat.com>; Mark Rutland
> <mark.rutland@arm.com>; Alexander Shishkin
> <alexander.shishkin@linux.intel.com>; Jiri Olsa <jolsa@redhat.com>;
> Namhyung Kim <namhyung@kernel.org>; Thomas Gleixner
> <tglx@linutronix.de>; Borislav Petkov <bp@alien8.de>; x86@kernel.org; H.
> Peter Anvin <hpa@zytor.com>; Mathieu Poirier
> <mathieu.poirier@linaro.org>; Suzuki K Poulose
> <suzuki.poulose@arm.com>; Mike Leach <mike.leach@linaro.org>; linux-
> perf-users@vger.kernel.org; linux-kernel@vger.kernel.org;
> coresight@lists.linaro.org; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH v4 10/11] perf env: Set flag for kernel is 64-bit mode
> 
> Hi Arnaldo, Adrian,
> 
> On Mon, Jul 12, 2021 at 03:14:35PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Sun, Jul 11, 2021 at 06:41:04PM +0800, Leo Yan escreveu:
> > > It's useful to know that the kernel is running in 32-bit or 64-bit
> > > mode.  E.g. We can decide if perf tool is running in compat mode
> > > from this info.
> > >
> > > This patch adds a global variable "kernel_is_64_bit", it's
> > > initialized when a session setups environment, its value is decided
> > > by checking the architecture string.
> > >
> > > Signed-off-by: Leo Yan <leo.yan@linaro.org>
> > > ---
> > >  tools/perf/util/env.c | 17 ++++++++++++++++-  tools/perf/util/env.h
> > > |  1 +
> > >  2 files changed, 17 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index
> > > ebc5e9ad35db..345635a2e842 100644
> > > --- a/tools/perf/util/env.c
> > > +++ b/tools/perf/util/env.c
> > > @@ -11,6 +11,7 @@
> > >  #include <stdlib.h>
> > >  #include <string.h>
> > >
> > > +int kernel_is_64_bit;
> > >  struct perf_env perf_env;
> >
> > Why can't this be in 'struct perf_env'?
> 
> Good question.  I considered to add it in struct perf_env but finally I used this
> way; the reason is this variable "kernel_is_64_bit" is only used during
> recording phase for AUX ring buffer, and don't use it for report.  So seems to
> me it's over complexity to add a new field and just wander if it's necessary to
> save this field as new feature in the perf header.

I think we store the arch, so if the "kernel_is_64_bit" calculation depends only on arch
then I guess we don't need a new feature at the moment.

> 
> Combining the comment from Adrian in another email, I think it's good to add
> a new field "compat_mode" in the struct perf_env, and this field will be
> initialized in build-record.c.  Currently we don't need to save this value into
> the perf file, if later we need to use this value for decoding phase, then we
> can add a new feature item to save "compat_mode"
> into the perf file's header.
> 
> If you have any different idea, please let me know.  Thanks!
> 
> Leo
Arnaldo Carvalho de Melo July 14, 2021, 1:59 p.m. UTC | #5
Em Tue, Jul 13, 2021 at 05:31:03PM +0000, Hunter, Adrian escreveu:
> > On Mon, Jul 12, 2021 at 03:14:35PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Sun, Jul 11, 2021 at 06:41:04PM +0800, Leo Yan escreveu:
> > > > +++ b/tools/perf/util/env.c
> > > > @@ -11,6 +11,7 @@
> > > >  #include <stdlib.h>
> > > >  #include <string.h>

> > > > +int kernel_is_64_bit;
> > > >  struct perf_env perf_env;

> > > Why can't this be in 'struct perf_env'?

> > Good question.  I considered to add it in struct perf_env but finally I used this
> > way; the reason is this variable "kernel_is_64_bit" is only used during
> > recording phase for AUX ring buffer, and don't use it for report.  So seems to
> > me it's over complexity to add a new field and just wander if it's necessary to
> > save this field as new feature in the perf header.

> I think we store the arch, so if the "kernel_is_64_bit" calculation depends only on arch
> then I guess we don't need a new feature at the moment.

So, I wasn't suggesting to add this info to the perf.data file header,
just to the in-memory 'struct perf_env'.

And also we should avoid unconditionally initializing things that we may
never need, please structure it as:

static void perf_env__init_kernel_mode(struct perf_env *env)
{
       const char *arch = perf_env__raw_arch(env);

       if (!strncmp(arch, "x86_64", 6)   || !strncmp(arch, "aarch64", 7) ||
           !strncmp(arch, "arm64", 5)    || !strncmp(arch, "mips64", 6) ||
           !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
           !strncmp(arch, "s390x", 5)    || !strncmp(arch, "sparc64", 7))
               kernel_is_64_bit = 1;
       else
               kernel_is_64_bit = 0;
}


void perf_env__init(struct perf_env *env)
{
	...
	env->kernel_is_64_bit = -1;
	...
}

bool perf_env__kernel_is_64_bit(struct perf_env *env)
{
	if (env->kernel_is_64_bit == -1)
		perf_env__init_kernel_mode(env);

	return env->kernel_is_64_bit;
}

One thing in my TODO is to crack down on the tons of initializations
perf does unconditionally, last time I looked there are lots :-\

- Arnaldo
 
> > Combining the comment from Adrian in another email, I think it's good to add
> > a new field "compat_mode" in the struct perf_env, and this field will be
> > initialized in build-record.c.  Currently we don't need to save this value into
> > the perf file, if later we need to use this value for decoding phase, then we
> > can add a new feature item to save "compat_mode"
> > into the perf file's header.

> > If you have any different idea, please let me know.  Thanks!
Arnaldo Carvalho de Melo July 14, 2021, 2 p.m. UTC | #6
Em Wed, Jul 14, 2021 at 10:59:49AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jul 13, 2021 at 05:31:03PM +0000, Hunter, Adrian escreveu:
> > > On Mon, Jul 12, 2021 at 03:14:35PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > Em Sun, Jul 11, 2021 at 06:41:04PM +0800, Leo Yan escreveu:
> > > > > +++ b/tools/perf/util/env.c
> > > > > @@ -11,6 +11,7 @@
> > > > >  #include <stdlib.h>
> > > > >  #include <string.h>
> 
> > > > > +int kernel_is_64_bit;
> > > > >  struct perf_env perf_env;
> 
> > > > Why can't this be in 'struct perf_env'?
> 
> > > Good question.  I considered to add it in struct perf_env but finally I used this
> > > way; the reason is this variable "kernel_is_64_bit" is only used during
> > > recording phase for AUX ring buffer, and don't use it for report.  So seems to
> > > me it's over complexity to add a new field and just wander if it's necessary to
> > > save this field as new feature in the perf header.
> 
> > I think we store the arch, so if the "kernel_is_64_bit" calculation depends only on arch
> > then I guess we don't need a new feature at the moment.
> 
> So, I wasn't suggesting to add this info to the perf.data file header,
> just to the in-memory 'struct perf_env'.
> 
> And also we should avoid unconditionally initializing things that we may
> never need, please structure it as:

Oops, forgot these:
 
> static void perf_env__init_kernel_mode(struct perf_env *env)
> {
>        const char *arch = perf_env__raw_arch(env);
> 
>        if (!strncmp(arch, "x86_64", 6)   || !strncmp(arch, "aarch64", 7) ||
>            !strncmp(arch, "arm64", 5)    || !strncmp(arch, "mips64", 6) ||
>            !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
>            !strncmp(arch, "s390x", 5)    || !strncmp(arch, "sparc64", 7))
>                kernel_is_64_bit = 1;
                 env->kernel_is_64_bit = 1;
>        else
>                kernel_is_64_bit = 0;
                 env->kernel_is_64_bit = 0;
> }
> 
> 
> void perf_env__init(struct perf_env *env)
> {
> 	...
> 	env->kernel_is_64_bit = -1;
> 	...
> }
> 
> bool perf_env__kernel_is_64_bit(struct perf_env *env)
> {
> 	if (env->kernel_is_64_bit == -1)
> 		perf_env__init_kernel_mode(env);
> 
> 	return env->kernel_is_64_bit;
> }
> 
> One thing in my TODO is to crack down on the tons of initializations
> perf does unconditionally, last time I looked there are lots :-\
> 
> - Arnaldo
>  
> > > Combining the comment from Adrian in another email, I think it's good to add
> > > a new field "compat_mode" in the struct perf_env, and this field will be
> > > initialized in build-record.c.  Currently we don't need to save this value into
> > > the perf file, if later we need to use this value for decoding phase, then we
> > > can add a new feature item to save "compat_mode"
> > > into the perf file's header.
> 
> > > If you have any different idea, please let me know.  Thanks!
Leo Yan July 23, 2021, 7:11 a.m. UTC | #7
Hi Arnaldo,

On Wed, Jul 14, 2021 at 11:00:44AM -0300, Arnaldo Carvalho de Melo wrote:

[...]

> > So, I wasn't suggesting to add this info to the perf.data file header,
> > just to the in-memory 'struct perf_env'.
> > 
> > And also we should avoid unconditionally initializing things that we may
> > never need, please structure it as:
> 
> Oops, forgot these:
>  
> > static void perf_env__init_kernel_mode(struct perf_env *env)
> > {
> >        const char *arch = perf_env__raw_arch(env);
> > 
> >        if (!strncmp(arch, "x86_64", 6)   || !strncmp(arch, "aarch64", 7) ||
> >            !strncmp(arch, "arm64", 5)    || !strncmp(arch, "mips64", 6) ||
> >            !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
> >            !strncmp(arch, "s390x", 5)    || !strncmp(arch, "sparc64", 7))
> >                kernel_is_64_bit = 1;
>                  env->kernel_is_64_bit = 1;
> >        else
> >                kernel_is_64_bit = 0;
>                  env->kernel_is_64_bit = 0;
> > }
> > 
> > 
> > void perf_env__init(struct perf_env *env)
> > {
> > 	...
> > 	env->kernel_is_64_bit = -1;
> > 	...
> > }
> > 
> > bool perf_env__kernel_is_64_bit(struct perf_env *env)
> > {
> > 	if (env->kernel_is_64_bit == -1)
> > 		perf_env__init_kernel_mode(env);
> > 
> > 	return env->kernel_is_64_bit;
> > }

Thanks a lot for the suggestion; this is much clear for me, will spin
new patch set by following it.

Sorry for slow response due to my bandwidth was occupied by a task in
hand.

Thanks,
Leo
diff mbox series

Patch

diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index ebc5e9ad35db..345635a2e842 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -11,6 +11,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 
+int kernel_is_64_bit;
 struct perf_env perf_env;
 
 #ifdef HAVE_LIBBPF_SUPPORT
@@ -172,6 +173,19 @@  static void perf_env__purge_bpf(struct perf_env *env __maybe_unused)
 }
 #endif // HAVE_LIBBPF_SUPPORT
 
+static void perf_env__init_kernel_mode(struct perf_env *env)
+{
+	const char *arch = perf_env__raw_arch(env);
+
+	if (!strncmp(arch, "x86_64", 6) || !strncmp(arch, "aarch64", 7) ||
+	    !strncmp(arch, "arm64", 5) || !strncmp(arch, "mips64", 6) ||
+	    !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
+	    !strncmp(arch, "s390x", 5) || !strncmp(arch, "sparc64", 7))
+		kernel_is_64_bit = 1;
+	else
+		kernel_is_64_bit = 0;
+}
+
 void perf_env__exit(struct perf_env *env)
 {
 	int i;
@@ -217,13 +231,14 @@  void perf_env__exit(struct perf_env *env)
 	zfree(&env->hybrid_cpc_nodes);
 }
 
-void perf_env__init(struct perf_env *env __maybe_unused)
+void perf_env__init(struct perf_env *env)
 {
 #ifdef HAVE_LIBBPF_SUPPORT
 	env->bpf_progs.infos = RB_ROOT;
 	env->bpf_progs.btfs = RB_ROOT;
 	init_rwsem(&env->bpf_progs.lock);
 #endif
+	perf_env__init_kernel_mode(env);
 }
 
 int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 6824a7423a2d..cc989ff49740 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -139,6 +139,7 @@  enum perf_compress_type {
 struct bpf_prog_info_node;
 struct btf_node;
 
+extern int kernel_is_64_bit;
 extern struct perf_env perf_env;
 
 void perf_env__exit(struct perf_env *env);