• Wang Nan's avatar
    perf tools: Enable indices setting syntax for BPF map · e571e029
    Wang Nan authored
    This patch introduces a new syntax to perf event parser:
    
     # perf record -e './test_bpf_map_3.c/map:channel.value[0,1,2,3...5]=101/' usleep 2
    
    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 **************************/
      #include <uapi/linux/bpf.h>
      #define SEC(NAME) __attribute__((section(NAME), used))
      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 *)BPF_FUNC_map_lookup_elem;
      static int (*trace_printk)(const char *fmt, int fmt_size, ...) =
     	(void *)BPF_FUNC_trace_printk;
      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);
    
     	if (!pval)
     		return 0;
     	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/map: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/map:channel.value[0...9,20...29]=102,map: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/map:channel.value[0...9,20...29]=102,map: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/map: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/map:channel.value[10...1000]=104/' usleep 99
      event syntax error: '..annel.value[10...1000]=104/'
                                       \___ Index too large
      Hint:	Valid config terms:
          	map:[<arraymap>].value<indices>=[value]
          	map:[<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: default avatarWang Nan <wangnan0@huawei.com>
    Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
    Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Alexei Starovoitov <ast@kernel.org>
    Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
    Cc: Cody P Schafer <dev@codyps.com>
    Cc: He Kuang <hekuang@huawei.com>
    Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com>
    Cc: Kirill Smelkov <kirr@nexedi.com>
    Cc: Li Zefan <lizefan@huawei.com>
    Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Zefan Li <lizefan@huawei.com>
    Cc: pi3orama@163.com
    Link: http://lkml.kernel.org/r/1456132275-98875-9-git-send-email-wangnan0@huawei.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    e571e029
parse-events.y 12.8 KB