[tip:perf/core] perf bpf: Add API to set values to map entries in a bpf object

2016-02-24 Thread tip-bot for Wang Nan
Commit-ID:  066dacbf2a32defb4de23ea4c1af9e77578b5ac2
Gitweb: http://git.kernel.org/tip/066dacbf2a32defb4de23ea4c1af9e77578b5ac2
Author: Wang Nan 
AuthorDate: Mon, 22 Feb 2016 09:10:30 +
Committer:  Arnaldo Carvalho de Melo 
CommitDate: Mon, 22 Feb 2016 12:17:48 -0300

perf bpf: Add API to set values to map entries in a bpf object

bpf__config_obj() is introduced as a core API to config BPF object after
loading. One configuration option of maps is introduced. After this
patch BPF object can accept assignments like:

  map:my_map.value=1234

(map.my_map.value looks pretty. However, there's a small but hard to fix
problem related to flex's greedy matching. Please see [1].  Choose ':'
to avoid it in a simpler way.)

This patch is more complex than the work it does because the
consideration of extension. In designing BPF map configuration, the
following things should be considered:

 1. Array indices selection: perf should allow user setting different
value for different slots in an array, with syntax like:
map:my_map.value[0,3...6]=1234;

 2. A map should be set by different config terms, each for a part
of it. For example, set each slot to the pid of a thread;

 3. Type of value: integer is not the only valid value type. A perf
counter can also be put into a map after commit 35578d798400
("bpf: Implement function bpf_perf_event_read() that get the
  selected hardware PMU counter")

 4. For a hash table, it should be possible to use a string or other
value as a key;

 5. It is possible that map configuration is unable to be setup
during parsing. A perf counter is an example.

Therefore, this patch does the following:

 1. Instead of updating map element during parsing, this patch stores
map config options in 'struct bpf_map_priv'. Following patches
will apply those configs at an appropriate time;

 2. Link map operations in a list so a map can have multiple config
terms attached, so different parts can be configured separately;

 3. Make 'struct bpf_map_priv' extensible so that the following patches
can add new types of keys and operations;

 4. Use bpf_obj_config__map_funcs array to support more map config options.

Since the patch changing the event parser to parse BPF object config is
relative large, I've put it in another commit. Code in this patch can be
tested after applying the next patch.

[1] http://lkml.kernel.org/g/564ed621.4050...@huawei.com

Signed-off-by: Wang Nan 
Cc: Adrian Hunter 
Cc: Alexei Starovoitov 
Cc: Brendan Gregg 
Cc: Cody P Schafer 
Cc: He Kuang 
Cc: Jeremie Galarneau 
Cc: Jiri Olsa 
Cc: Kirill Smelkov 
Cc: Li Zefan 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Peter Zijlstra 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1456132275-98875-4-git-send-email-wangn...@huawei.com
Signed-off-by: He Kuang 
[ Changes "maps:my_map.value" to "map:my_map.value", improved error messages ]
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/bpf-loader.c | 276 +++
 tools/perf/util/bpf-loader.h |  38 ++
 2 files changed, 314 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 0bdccf4..caeef9e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -739,6 +739,261 @@ int bpf__foreach_tev(struct bpf_object *obj,
return 0;
 }
 
+enum bpf_map_op_type {
+   BPF_MAP_OP_SET_VALUE,
+};
+
+enum bpf_map_key_type {
+   BPF_MAP_KEY_ALL,
+};
+
+struct bpf_map_op {
+   struct list_head list;
+   enum bpf_map_op_type op_type;
+   enum bpf_map_key_type key_type;
+   union {
+   u64 value;
+   } v;
+};
+
+struct bpf_map_priv {
+   struct list_head ops_list;
+};
+
+static void
+bpf_map_op__delete(struct bpf_map_op *op)
+{
+   if (!list_empty(>list))
+   list_del(>list);
+   free(op);
+}
+
+static void
+bpf_map_priv__purge(struct bpf_map_priv *priv)
+{
+   struct bpf_map_op *pos, *n;
+
+   list_for_each_entry_safe(pos, n, >ops_list, list) {
+   list_del_init(>list);
+   bpf_map_op__delete(pos);
+   }
+}
+
+static void
+bpf_map_priv__clear(struct bpf_map *map __maybe_unused,
+   void *_priv)
+{
+   struct bpf_map_priv *priv = _priv;
+
+   bpf_map_priv__purge(priv);
+   free(priv);
+}
+
+static struct bpf_map_op *
+bpf_map_op__new(void)
+{
+   struct bpf_map_op *op;
+
+   op = zalloc(sizeof(*op));
+   if (!op) {
+   pr_debug("Failed to alloc bpf_map_op\n");
+   return 

[tip:perf/core] perf bpf: Add API to set values to map entries in a bpf object

2016-02-24 Thread tip-bot for Wang Nan
Commit-ID:  066dacbf2a32defb4de23ea4c1af9e77578b5ac2
Gitweb: http://git.kernel.org/tip/066dacbf2a32defb4de23ea4c1af9e77578b5ac2
Author: Wang Nan 
AuthorDate: Mon, 22 Feb 2016 09:10:30 +
Committer:  Arnaldo Carvalho de Melo 
CommitDate: Mon, 22 Feb 2016 12:17:48 -0300

perf bpf: Add API to set values to map entries in a bpf object

bpf__config_obj() is introduced as a core API to config BPF object after
loading. One configuration option of maps is introduced. After this
patch BPF object can accept assignments like:

  map:my_map.value=1234

(map.my_map.value looks pretty. However, there's a small but hard to fix
problem related to flex's greedy matching. Please see [1].  Choose ':'
to avoid it in a simpler way.)

This patch is more complex than the work it does because the
consideration of extension. In designing BPF map configuration, the
following things should be considered:

 1. Array indices selection: perf should allow user setting different
value for different slots in an array, with syntax like:
map:my_map.value[0,3...6]=1234;

 2. A map should be set by different config terms, each for a part
of it. For example, set each slot to the pid of a thread;

 3. Type of value: integer is not the only valid value type. A perf
counter can also be put into a map after commit 35578d798400
("bpf: Implement function bpf_perf_event_read() that get the
  selected hardware PMU counter")

 4. For a hash table, it should be possible to use a string or other
value as a key;

 5. It is possible that map configuration is unable to be setup
during parsing. A perf counter is an example.

Therefore, this patch does the following:

 1. Instead of updating map element during parsing, this patch stores
map config options in 'struct bpf_map_priv'. Following patches
will apply those configs at an appropriate time;

 2. Link map operations in a list so a map can have multiple config
terms attached, so different parts can be configured separately;

 3. Make 'struct bpf_map_priv' extensible so that the following patches
can add new types of keys and operations;

 4. Use bpf_obj_config__map_funcs array to support more map config options.

Since the patch changing the event parser to parse BPF object config is
relative large, I've put it in another commit. Code in this patch can be
tested after applying the next patch.

[1] http://lkml.kernel.org/g/564ed621.4050...@huawei.com

Signed-off-by: Wang Nan 
Cc: Adrian Hunter 
Cc: Alexei Starovoitov 
Cc: Brendan Gregg 
Cc: Cody P Schafer 
Cc: He Kuang 
Cc: Jeremie Galarneau 
Cc: Jiri Olsa 
Cc: Kirill Smelkov 
Cc: Li Zefan 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Peter Zijlstra 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1456132275-98875-4-git-send-email-wangn...@huawei.com
Signed-off-by: He Kuang 
[ Changes "maps:my_map.value" to "map:my_map.value", improved error messages ]
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/bpf-loader.c | 276 +++
 tools/perf/util/bpf-loader.h |  38 ++
 2 files changed, 314 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 0bdccf4..caeef9e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -739,6 +739,261 @@ int bpf__foreach_tev(struct bpf_object *obj,
return 0;
 }
 
+enum bpf_map_op_type {
+   BPF_MAP_OP_SET_VALUE,
+};
+
+enum bpf_map_key_type {
+   BPF_MAP_KEY_ALL,
+};
+
+struct bpf_map_op {
+   struct list_head list;
+   enum bpf_map_op_type op_type;
+   enum bpf_map_key_type key_type;
+   union {
+   u64 value;
+   } v;
+};
+
+struct bpf_map_priv {
+   struct list_head ops_list;
+};
+
+static void
+bpf_map_op__delete(struct bpf_map_op *op)
+{
+   if (!list_empty(>list))
+   list_del(>list);
+   free(op);
+}
+
+static void
+bpf_map_priv__purge(struct bpf_map_priv *priv)
+{
+   struct bpf_map_op *pos, *n;
+
+   list_for_each_entry_safe(pos, n, >ops_list, list) {
+   list_del_init(>list);
+   bpf_map_op__delete(pos);
+   }
+}
+
+static void
+bpf_map_priv__clear(struct bpf_map *map __maybe_unused,
+   void *_priv)
+{
+   struct bpf_map_priv *priv = _priv;
+
+   bpf_map_priv__purge(priv);
+   free(priv);
+}
+
+static struct bpf_map_op *
+bpf_map_op__new(void)
+{
+   struct bpf_map_op *op;
+
+   op = zalloc(sizeof(*op));
+   if (!op) {
+   pr_debug("Failed to alloc bpf_map_op\n");
+   return ERR_PTR(-ENOMEM);
+   }
+   INIT_LIST_HEAD(>list);
+
+   op->key_type = BPF_MAP_KEY_ALL;
+   return op;
+}
+
+static int
+bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
+{
+   struct bpf_map_priv *priv;
+   const char *map_name;
+   int err;
+
+   map_name = bpf_map__get_name(map);
+   err = bpf_map__get_private(map, (void **));
+   if