Re: [PATCH 12/16] perf tools: Support setting different slots in a BPF map separately

2015-11-26 Thread Wangnan (F)



On 2015/11/24 21:36, Wang Nan wrote:

This patch introduces basic facilities to support config different
slots in a BPF map one by one.

array.nr_ranges and array.ranges are introduced into 'struct
parse_events_term', where ranges is an array of indices range (start,
length) which will be configured by this config term. nr_ranges
is the size of the array. The array is passed to 'struct bpf_map_priv'.
To indicate the new type of configuration, BPF_MAP_KEY_RANGES is
added as a new key type. bpf_map_config_foreach_key() is extended to
iterate over those indices instead of all possible keys.

Code in this commit will be enabled by following commit which enables
the indices syntax for array configuration.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
  tools/perf/util/bpf-loader.c   | 133 ++---
  tools/perf/util/bpf-loader.h   |   1 +
  tools/perf/util/parse-events.c |  33 +-
  tools/perf/util/parse-events.h |  12 
  4 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a6e4bde..185d2cf 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c


[SNIP]


+static int
+bpf_map_op_setkey(struct bpf_map_op *op, struct parse_events_term *term,
+ const char *map_name)
+{
+   op->key_type = BPF_MAP_KEY_ALL;
+
+   if (term->array.nr_ranges) {
+   size_t memsz = term->array.nr_ranges *
+   sizeof(op->k.array.ranges[0]);
+
+   op->k.array.ranges = malloc(memsz);
+   if (!op->k.array.ranges) {
+   pr_debug("No enough memory to alloc indices for %s\n",
+map_name);
+   return -ENOMEM;
+   }
+   memcpy(op->k.array.ranges, term->array.ranges, memsz);


Here can use memdup.


+   op->key_type = BPF_MAP_KEY_RANGES;
+   op->k.array.nr_ranges = term->array.nr_ranges;
+   }
+   return 0;
+}
+



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 12/16] perf tools: Support setting different slots in a BPF map separately

2015-11-26 Thread Wangnan (F)



On 2015/11/24 21:36, Wang Nan wrote:

This patch introduces basic facilities to support config different
slots in a BPF map one by one.

array.nr_ranges and array.ranges are introduced into 'struct
parse_events_term', where ranges is an array of indices range (start,
length) which will be configured by this config term. nr_ranges
is the size of the array. The array is passed to 'struct bpf_map_priv'.
To indicate the new type of configuration, BPF_MAP_KEY_RANGES is
added as a new key type. bpf_map_config_foreach_key() is extended to
iterate over those indices instead of all possible keys.

Code in this commit will be enabled by following commit which enables
the indices syntax for array configuration.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
  tools/perf/util/bpf-loader.c   | 133 ++---
  tools/perf/util/bpf-loader.h   |   1 +
  tools/perf/util/parse-events.c |  33 +-
  tools/perf/util/parse-events.h |  12 
  4 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a6e4bde..185d2cf 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c


[SNIP]


+static int
+bpf_map_op_setkey(struct bpf_map_op *op, struct parse_events_term *term,
+ const char *map_name)
+{
+   op->key_type = BPF_MAP_KEY_ALL;
+
+   if (term->array.nr_ranges) {
+   size_t memsz = term->array.nr_ranges *
+   sizeof(op->k.array.ranges[0]);
+
+   op->k.array.ranges = malloc(memsz);
+   if (!op->k.array.ranges) {
+   pr_debug("No enough memory to alloc indices for %s\n",
+map_name);
+   return -ENOMEM;
+   }
+   memcpy(op->k.array.ranges, term->array.ranges, memsz);


Here can use memdup.


+   op->key_type = BPF_MAP_KEY_RANGES;
+   op->k.array.nr_ranges = term->array.nr_ranges;
+   }
+   return 0;
+}
+



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 12/16] perf tools: Support setting different slots in a BPF map separately

2015-11-24 Thread Wang Nan
This patch introduces basic facilities to support config different
slots in a BPF map one by one.

array.nr_ranges and array.ranges are introduced into 'struct
parse_events_term', where ranges is an array of indices range (start,
length) which will be configured by this config term. nr_ranges
is the size of the array. The array is passed to 'struct bpf_map_priv'.
To indicate the new type of configuration, BPF_MAP_KEY_RANGES is
added as a new key type. bpf_map_config_foreach_key() is extended to
iterate over those indices instead of all possible keys.

Code in this commit will be enabled by following commit which enables
the indices syntax for array configuration.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c   | 133 ++---
 tools/perf/util/bpf-loader.h   |   1 +
 tools/perf/util/parse-events.c |  33 +-
 tools/perf/util/parse-events.h |  12 
 4 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a6e4bde..185d2cf 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -17,6 +17,7 @@
 #include "llvm-utils.h"
 #include "probe-event.h"
 #include "probe-finder.h" // for MAX_PROBES
+#include "parse-events.h"
 #include "llvm-utils.h"
 
 #define DEFINE_PRINT_FN(name, level) \
@@ -747,6 +748,7 @@ enum bpf_map_op_type {
 
 enum bpf_map_key_type {
BPF_MAP_KEY_ALL,
+   BPF_MAP_KEY_RANGES,
 };
 
 struct bpf_map_op {
@@ -754,6 +756,9 @@ struct bpf_map_op {
enum bpf_map_op_type op_type;
enum bpf_map_key_type key_type;
union {
+   struct parse_events_array array;
+   } k;
+   union {
u64 value;
struct perf_evsel *evsel;
} v;
@@ -768,6 +773,8 @@ bpf_map_op__free(struct bpf_map_op *op)
 {
if (!list_is_singular(>list))
list_del(>list);
+   if (op->key_type == BPF_MAP_KEY_RANGES)
+   parse_events__clear_array(>k.array);
free(op);
 }
 
@@ -783,8 +790,31 @@ bpf_map_priv__clear(struct bpf_map *map __maybe_unused,
free(priv);
 }
 
+static int
+bpf_map_op_setkey(struct bpf_map_op *op, struct parse_events_term *term,
+ const char *map_name)
+{
+   op->key_type = BPF_MAP_KEY_ALL;
+
+   if (term->array.nr_ranges) {
+   size_t memsz = term->array.nr_ranges *
+   sizeof(op->k.array.ranges[0]);
+
+   op->k.array.ranges = malloc(memsz);
+   if (!op->k.array.ranges) {
+   pr_debug("No enough memory to alloc indices for %s\n",
+map_name);
+   return -ENOMEM;
+   }
+   memcpy(op->k.array.ranges, term->array.ranges, memsz);
+   op->key_type = BPF_MAP_KEY_RANGES;
+   op->k.array.nr_ranges = term->array.nr_ranges;
+   }
+   return 0;
+}
+
 static struct bpf_map_op *
-bpf_map_op__alloc(struct bpf_map *map)
+bpf_map_op__alloc(struct bpf_map *map, struct parse_events_term *term)
 {
struct bpf_map_op *op;
struct bpf_map_priv *priv;
@@ -818,7 +848,12 @@ bpf_map_op__alloc(struct bpf_map *map)
return ERR_PTR(-ENOMEM);
}
 
-   op->key_type = BPF_MAP_KEY_ALL;
+   err = bpf_map_op_setkey(op, term, map_name);
+   if (err) {
+   free(op);
+   return ERR_PTR(err);
+   }
+
list_add_tail(>list, >ops_list);
return op;
 }
@@ -861,7 +896,7 @@ bpf__obj_config_map_array_value(struct bpf_map *map,
return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE;
}
 
-   op = bpf_map_op__alloc(map);
+   op = bpf_map_op__alloc(map, term);
if (IS_ERR(op))
return PTR_ERR(op);
op->op_type = BPF_MAP_OP_SET_VALUE;
@@ -922,7 +957,7 @@ bpf__obj_config_map_array_event(struct bpf_map *map,
return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
}
 
-   op = bpf_map_op__alloc(map);
+   op = bpf_map_op__alloc(map, term);
if (IS_ERR(op))
return PTR_ERR(op);
 
@@ -961,6 +996,44 @@ struct bpf_obj_config_map_func bpf_obj_config_map_funcs[] 
= {
 };
 
 static int
+config_map_indices_range_check(struct parse_events_term *term,
+  struct bpf_map *map,
+  const char *map_name)
+{
+   struct parse_events_array *array = >array;
+   struct bpf_map_def def;
+   unsigned int i;
+   int err;
+
+   if (!array->nr_ranges)
+   return 0;
+   if (!array->ranges) {
+   pr_debug("ERROR: map %s: array->nr_ranges is %d but range array 
is NULL\n",
+map_name, (int)array->nr_ranges);
+   return -BPF_LOADER_ERRNO__INTERNAL;
+   }
+

[PATCH 12/16] perf tools: Support setting different slots in a BPF map separately

2015-11-24 Thread Wang Nan
This patch introduces basic facilities to support config different
slots in a BPF map one by one.

array.nr_ranges and array.ranges are introduced into 'struct
parse_events_term', where ranges is an array of indices range (start,
length) which will be configured by this config term. nr_ranges
is the size of the array. The array is passed to 'struct bpf_map_priv'.
To indicate the new type of configuration, BPF_MAP_KEY_RANGES is
added as a new key type. bpf_map_config_foreach_key() is extended to
iterate over those indices instead of all possible keys.

Code in this commit will be enabled by following commit which enables
the indices syntax for array configuration.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Masami Hiramatsu 
Cc: Namhyung Kim 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c   | 133 ++---
 tools/perf/util/bpf-loader.h   |   1 +
 tools/perf/util/parse-events.c |  33 +-
 tools/perf/util/parse-events.h |  12 
 4 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a6e4bde..185d2cf 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -17,6 +17,7 @@
 #include "llvm-utils.h"
 #include "probe-event.h"
 #include "probe-finder.h" // for MAX_PROBES
+#include "parse-events.h"
 #include "llvm-utils.h"
 
 #define DEFINE_PRINT_FN(name, level) \
@@ -747,6 +748,7 @@ enum bpf_map_op_type {
 
 enum bpf_map_key_type {
BPF_MAP_KEY_ALL,
+   BPF_MAP_KEY_RANGES,
 };
 
 struct bpf_map_op {
@@ -754,6 +756,9 @@ struct bpf_map_op {
enum bpf_map_op_type op_type;
enum bpf_map_key_type key_type;
union {
+   struct parse_events_array array;
+   } k;
+   union {
u64 value;
struct perf_evsel *evsel;
} v;
@@ -768,6 +773,8 @@ bpf_map_op__free(struct bpf_map_op *op)
 {
if (!list_is_singular(>list))
list_del(>list);
+   if (op->key_type == BPF_MAP_KEY_RANGES)
+   parse_events__clear_array(>k.array);
free(op);
 }
 
@@ -783,8 +790,31 @@ bpf_map_priv__clear(struct bpf_map *map __maybe_unused,
free(priv);
 }
 
+static int
+bpf_map_op_setkey(struct bpf_map_op *op, struct parse_events_term *term,
+ const char *map_name)
+{
+   op->key_type = BPF_MAP_KEY_ALL;
+
+   if (term->array.nr_ranges) {
+   size_t memsz = term->array.nr_ranges *
+   sizeof(op->k.array.ranges[0]);
+
+   op->k.array.ranges = malloc(memsz);
+   if (!op->k.array.ranges) {
+   pr_debug("No enough memory to alloc indices for %s\n",
+map_name);
+   return -ENOMEM;
+   }
+   memcpy(op->k.array.ranges, term->array.ranges, memsz);
+   op->key_type = BPF_MAP_KEY_RANGES;
+   op->k.array.nr_ranges = term->array.nr_ranges;
+   }
+   return 0;
+}
+
 static struct bpf_map_op *
-bpf_map_op__alloc(struct bpf_map *map)
+bpf_map_op__alloc(struct bpf_map *map, struct parse_events_term *term)
 {
struct bpf_map_op *op;
struct bpf_map_priv *priv;
@@ -818,7 +848,12 @@ bpf_map_op__alloc(struct bpf_map *map)
return ERR_PTR(-ENOMEM);
}
 
-   op->key_type = BPF_MAP_KEY_ALL;
+   err = bpf_map_op_setkey(op, term, map_name);
+   if (err) {
+   free(op);
+   return ERR_PTR(err);
+   }
+
list_add_tail(>list, >ops_list);
return op;
 }
@@ -861,7 +896,7 @@ bpf__obj_config_map_array_value(struct bpf_map *map,
return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE;
}
 
-   op = bpf_map_op__alloc(map);
+   op = bpf_map_op__alloc(map, term);
if (IS_ERR(op))
return PTR_ERR(op);
op->op_type = BPF_MAP_OP_SET_VALUE;
@@ -922,7 +957,7 @@ bpf__obj_config_map_array_event(struct bpf_map *map,
return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
}
 
-   op = bpf_map_op__alloc(map);
+   op = bpf_map_op__alloc(map, term);
if (IS_ERR(op))
return PTR_ERR(op);
 
@@ -961,6 +996,44 @@ struct bpf_obj_config_map_func bpf_obj_config_map_funcs[] 
= {
 };
 
 static int
+config_map_indices_range_check(struct parse_events_term *term,
+  struct bpf_map *map,
+  const char *map_name)
+{
+   struct parse_events_array *array = >array;
+   struct bpf_map_def def;
+   unsigned int i;
+   int err;
+
+   if (!array->nr_ranges)
+   return 0;
+   if (!array->ranges) {
+   pr_debug("ERROR: map %s: array->nr_ranges is %d but range array 
is