All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Wang Nan <wangnan0@huawei.com>
Cc: namhyung@kernel.org, linux-kernel@vger.kernel.org,
	pi3orama@163.com, mingo@kernel.org, lizefan@huawei.com,
	Alexei Starovoitov <ast@kernel.org>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Subject: Re: [PATCH v4 09/16] perf tools: Enable indices setting syntax for BPF maps
Date: Fri, 11 Dec 2015 09:11:45 -0300	[thread overview]
Message-ID: <20151211121145.GP17996@kernel.org> (raw)
In-Reply-To: <1449541544-67621-10-git-send-email-wangnan0@huawei.com>

Em Tue, Dec 08, 2015 at 02:25:37AM +0000, Wang Nan escreveu:
> This patch introduce a new syntax to perf event parser:
> 
>  # perf record -e bpf_file.c/maps.mymap.value[0,3...5,7]=1234/ ...

Is the above example valid? Wouldn't this be "maps:mymap.value" ?

> 
> By utilizing the basic facilities in bpf-loader.c which allow setting
> different slots in a BPF map separately, the newly introduced syntax
> allows perf to control specific elements in a BPF map.
> 
> Test result:
> 
>  # cat ./test_bpf_map_3.c
>  /************************ BEGIN **************************/
>  #define SEC(NAME) __attribute__((section(NAME), used))
>  enum bpf_map_type {
>      BPF_MAP_TYPE_ARRAY = 2,
>  };
>  struct bpf_map_def {
>      unsigned int type;
>      unsigned int key_size;
>      unsigned int value_size;
>      unsigned int max_entries;
>  };
>  static void *(*map_lookup_elem)(struct bpf_map_def *, void *) =
>      (void *)1;
>  static int (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
>      (void *)6;

Can you explain the above a bit more? What are the magic 1 and 6 values?

>  struct bpf_map_def SEC("maps") channel = {
>      .type = BPF_MAP_TYPE_ARRAY,
>      .key_size = sizeof(int),
>      .value_size = sizeof(unsigned char),
>      .max_entries = 100,
>  };

>  SEC("func=hrtimer_nanosleep rqtp->tv_nsec")
>  int func(void *ctx, int err, long nsec)
>  {
>      char fmt[] = "%ld\n";
>      long usec = nsec * 0x10624dd3 >> 38; // nsec / 1000
>      int key = (int)usec;
>      unsigned char *pval = map_lookup_elem(&channel, &key);

So that "mymap.value" name doesn't needs to be specified here?

> 
>      if (!pval)
>          return 0;
>      bpf_trace_printk(fmt, sizeof(fmt), (unsigned char)*pval);
>      return 0;
>  }
>  char _license[] SEC("license") = "GPL";
>  int _version SEC("version") = LINUX_VERSION_CODE;
>  /************************* END ***************************/
> 
> Normal case:
>  # echo "" > /sys/kernel/debug/tracing/trace
>  # ./perf record -e './test_bpf_map_3.c/maps:channel.value[0,1,2,3...5]=101/' usleep 2
>  [ perf record: Woken up 1 times to write data ]
>  [ perf record: Captured and wrote 0.012 MB perf.data ]
>  # cat /sys/kernel/debug/tracing/trace | grep usleep
>            usleep-405   [004] d... 2745423.547822: : 101
>  # ./perf record -e './test_bpf_map_3.c/maps:channel.value[0...9,20...29]=102,maps:channel.value[10...19]=103/' usleep 3
>  [ perf record: Woken up 1 times to write data ]
>  [ perf record: Captured and wrote 0.012 MB perf.data ]
>  # ./perf record -e './test_bpf_map_3.c/maps:channel.value[0...9,20...29]=102,maps:channel.value[10...19]=103/' usleep 15
>  [ perf record: Woken up 1 times to write data ]
>  [ perf record: Captured and wrote 0.012 MB perf.data ]
>  # cat /sys/kernel/debug/tracing/trace | grep usleep
>            usleep-405   [004] d... 2745423.547822: : 101
>            usleep-655   [006] d... 2745434.122814: : 102
>            usleep-904   [006] d... 2745439.916264: : 103
>  # ./perf record -e './test_bpf_map_3.c/maps:channel.value[all]=104/' usleep 99
>  # cat /sys/kernel/debug/tracing/trace | grep usleep
>            usleep-405   [004] d... 2745423.547822: : 101
>            usleep-655   [006] d... 2745434.122814: : 102
>            usleep-904   [006] d... 2745439.916264: : 103
>            usleep-1537  [003] d... 2745538.053737: : 104
> 
> Error case:
>  # ./perf record -e './test_bpf_map_3.c/maps:channel.value[10...1000]=104/' usleep 99
>  event syntax error: '..annel.value[10...1000]=104/'
>                                    \___ Index too large
>  Hint:	Valid config terms:
>       	maps:[<arraymap>].value<indices>=[value]
>       	maps:[<eventmap>].event<indices>=[event]
> 
>       	where <indices> is something like [0,3...5] or [all]
>       	(add -v to see detail)
>  Run 'perf list' for a list of valid events
> 
>   Usage: perf record [<options>] [<command>]
>      or: perf record [<options>] -- <command> [<options>]
> 
>      -e, --event <event>   event selector. use 'perf list' to list available events
> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Zefan Li <lizefan@huawei.com>
> Cc: pi3orama@163.com
> ---
>  tools/perf/util/parse-events.c |  5 ++-
>  tools/perf/util/parse-events.l | 13 ++++++-
>  tools/perf/util/parse-events.y | 85 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 100 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index af3d657..abdf551 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -660,9 +660,10 @@ parse_events_config_bpf(struct parse_events_evlist *data,
>  						 sizeof(errbuf));
>  			data->error->help = strdup(
>  "Hint:\tValid config terms:\n"
> -"     \tmaps:[<arraymap>].value=[value]\n"
> -"     \tmaps:[<eventmap>].event=[event]\n"
> +"     \tmaps:[<arraymap>].value<indices>=[value]\n"
> +"     \tmaps:[<eventmap>].event<indices>=[event]\n"
>  "\n"
> +"     \twhere <indices> is something like [0,3...5] or [all]\n"
>  "     \t(add -v to see detail)");
>  			data->error->str = strdup(errbuf);
>  			if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
> diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
> index 4387728..8bb3437 100644
> --- a/tools/perf/util/parse-events.l
> +++ b/tools/perf/util/parse-events.l
> @@ -9,8 +9,8 @@
>  %{
>  #include <errno.h>
>  #include "../perf.h"
> -#include "parse-events-bison.h"
>  #include "parse-events.h"
> +#include "parse-events-bison.h"
>  
>  char *parse_events_get_text(yyscan_t yyscanner);
>  YYSTYPE *parse_events_get_lval(yyscan_t yyscanner);
> @@ -111,6 +111,7 @@ do {							\
>  %x mem
>  %s config
>  %x event
> +%x array
>  
>  group		[^,{}/]*[{][^}]*[}][^,{}/]*
>  event_pmu	[^,{}/]+[/][^/]*[/][^,{}/]*
> @@ -176,6 +177,14 @@ modifier_bp	[rwx]{1,3}
>  
>  }
>  
> +<array>{
> +"]"			{ BEGIN(config); return ']'; }
> +{num_dec}		{ return value(yyscanner, 10); }
> +{num_hex}		{ return value(yyscanner, 16); }
> +,			{ return ','; }
> +"\.\.\."		{ return PE_ARRAY_RANGE; }
> +}
> +
>  <config>{
>  	/*
>  	 * Please update parse_events_formats_error_string any time
> @@ -196,6 +205,8 @@ no-inherit		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
>  ,			{ return ','; }
>  "/"			{ BEGIN(INITIAL); return '/'; }
>  {name_minus}		{ return str(yyscanner, PE_NAME); }
> +\[all\]			{ return PE_ARRAY_ALL; }
> +"["			{ BEGIN(array); return '['; }
>  }
>  
>  <mem>{
> diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
> index c3cbd7a..7e93b9f 100644
> --- a/tools/perf/util/parse-events.y
> +++ b/tools/perf/util/parse-events.y
> @@ -48,6 +48,7 @@ static inc_group_count(struct list_head *list,
>  %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
>  %token PE_ERROR
>  %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
> +%token PE_ARRAY_ALL PE_ARRAY_RANGE
>  %type <num> PE_VALUE
>  %type <num> PE_VALUE_SYM_HW
>  %type <num> PE_VALUE_SYM_SW
> @@ -84,6 +85,9 @@ static inc_group_count(struct list_head *list,
>  %type <head> group_def
>  %type <head> group
>  %type <head> groups
> +%type <array> array
> +%type <array> array_term
> +%type <array> array_terms
>  
>  %union
>  {
> @@ -95,6 +99,7 @@ static inc_group_count(struct list_head *list,
>  		char *sys;
>  		char *event;
>  	} tracepoint_name;
> +	struct parse_events_array array;
>  }
>  %%
>  
> @@ -601,6 +606,86 @@ PE_TERM
>  	ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL));
>  	$$ = term;
>  }
> +|
> +PE_NAME array '=' PE_NAME
> +{
> +	struct parse_events_term *term;
> +	int i;
> +
> +	ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
> +					$1, $4, &@1, &@4));
> +
> +	term->array = $2;
> +	$$ = term;
> +}
> +|
> +PE_NAME array '=' PE_VALUE
> +{
> +	struct parse_events_term *term;
> +
> +	ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
> +					$1, $4, &@1, &@4));
> +	term->array = $2;
> +	$$ = term;
> +}
> +
> +array:
> +'[' array_terms ']'
> +{
> +	$$ = $2;
> +}
> +|
> +PE_ARRAY_ALL
> +{
> +	$$.nr_ranges = 0;
> +	$$.ranges = NULL;
> +}
> +
> +array_terms:
> +array_terms ',' array_term
> +{
> +	struct parse_events_array new_array;
> +
> +	new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges;
> +	new_array.ranges = malloc(sizeof(new_array.ranges[0]) *
> +				  new_array.nr_ranges);
> +	ABORT_ON(!new_array.ranges);
> +	memcpy(&new_array.ranges[0], $1.ranges,
> +	       $1.nr_ranges * sizeof(new_array.ranges[0]));
> +	memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges,
> +	       $3.nr_ranges * sizeof(new_array.ranges[0]));
> +	free($1.ranges);
> +	free($3.ranges);
> +	$$ = new_array;
> +}
> +|
> +array_term
> +
> +array_term:
> +PE_VALUE
> +{
> +	struct parse_events_array array;
> +
> +	array.nr_ranges = 1;
> +	array.ranges = malloc(sizeof(array.ranges[0]));
> +	ABORT_ON(!array.ranges);
> +	array.ranges[0].start = $1;
> +	array.ranges[0].length = 1;
> +	$$ = array;
> +}
> +|
> +PE_VALUE PE_ARRAY_RANGE PE_VALUE
> +{
> +	struct parse_events_array array;
> +
> +	ABORT_ON($3 < $1);
> +	array.nr_ranges = 1;
> +	array.ranges = malloc(sizeof(array.ranges[0]));
> +	ABORT_ON(!array.ranges);
> +	array.ranges[0].start = $1;
> +	array.ranges[0].length = $3 - $1 + 1;
> +	$$ = array;
> +}
>  
>  sep_dc: ':' |
>  
> -- 
> 1.8.3.4

  reply	other threads:[~2015-12-11 12:11 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-08  2:25 [PATCH v4 00/16] perf tools: BPF related update and other improvements Wang Nan
2015-12-08  2:25 ` [PATCH v4 01/16] tools lib bpf: Check return value of strdup when reading map names Wang Nan
2015-12-14  8:37   ` [tip:perf/core] " tip-bot for Wang Nan
2015-12-08  2:25 ` [PATCH v4 02/16] tools lib bpf: Fetch map names from correct strtab Wang Nan
2015-12-14  8:38   ` [tip:perf/core] " tip-bot for Wang Nan
2015-12-08  2:25 ` [PATCH v4 03/16] perf tools: Add API to config maps in bpf object Wang Nan
2015-12-08  2:25 ` [PATCH v4 04/16] perf tools: Enable BPF object configure syntax Wang Nan
2015-12-08  2:25 ` [PATCH v4 05/16] perf record: Apply config to BPF objects before recording Wang Nan
2015-12-08  2:25 ` [PATCH v4 06/16] perf tools: Support perf event alias name Wang Nan
2015-12-11 12:03   ` Arnaldo Carvalho de Melo
2015-12-11 12:12     ` pi3orama
2015-12-08  2:25 ` [PATCH v4 07/16] perf tools: Enable passing event to BPF object Wang Nan
2015-12-08  2:25 ` [PATCH v4 08/16] perf tools: Support setting different slots in a BPF map separately Wang Nan
2015-12-08  2:25 ` [PATCH v4 09/16] perf tools: Enable indices setting syntax for BPF maps Wang Nan
2015-12-11 12:11   ` Arnaldo Carvalho de Melo [this message]
2015-12-11 12:15     ` Arnaldo Carvalho de Melo
2015-12-11 12:39       ` pi3orama
2015-12-11 12:47         ` Arnaldo Carvalho de Melo
2015-12-11 12:57           ` pi3orama
2015-12-11 18:21         ` Alexei Starovoitov
2015-12-14  3:27           ` Wangnan (F)
2015-12-14  4:28             ` Alexei Starovoitov
2015-12-14  4:39               ` Wangnan (F)
2015-12-14  5:51                 ` Alexei Starovoitov
2015-12-08  2:25 ` [PATCH v4 10/16] perf tools: Introduce bpf-output event Wang Nan
2015-12-08  2:25 ` [PATCH v4 11/16] perf data: Add u32_hex data type Wang Nan
2015-12-14  8:38   ` [tip:perf/core] " tip-bot for Wang Nan
2015-12-08  2:25 ` [PATCH v4 12/16] perf data: Support converting data from bpf_perf_event_output() Wang Nan
2015-12-08  2:25 ` [PATCH v4 13/16] perf tools: Always give options even it not compiled Wang Nan
2015-12-11 12:39   ` Arnaldo Carvalho de Melo
2015-12-08  2:25 ` [PATCH v4 14/16] perf record: Support custom vmlinux path Wang Nan
2015-12-08  2:25 ` [PATCH v4 15/16] perf script: Add support for PERF_TYPE_BREAKPOINT Wang Nan
2015-12-14  8:38   ` [tip:perf/core] " tip-bot for Wang Nan
2015-12-08  2:25 ` [PATCH v4 16/16] perf tools: Clear struct machine during machine__init() Wang Nan
2015-12-14  8:39   ` [tip:perf/core] " tip-bot for Wang Nan

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=20151211121145.GP17996@kernel.org \
    --to=acme@kernel.org \
    --cc=ast@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=pi3orama@163.com \
    --cc=wangnan0@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.