Re: [PATCH 12/16] perf tools: Support setting different slots in a BPF map separately
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
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 NanCc: 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
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
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 NanCc: 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