mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 15:04:27 +08:00
a34f3be70c
This patch adds the final step for BPF map configuration. A new syntax is appended into parser so user can config BPF objects through '/' '/' enclosed config terms. After this patch, following syntax is available: # perf record -e ./test_bpf_map_1.c/map:channel.value=10/ ... It would takes effect after appling following commits. Test result: # cat ./test_bpf_map_1.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(int), .max_entries = 1, }; SEC("func=sys_nanosleep") int func(void *ctx) { int key = 0; char fmt[] = "%d\n"; int *pval = map_lookup_elem(&channel, &key); if (!pval) return 0; trace_printk(fmt, sizeof(fmt), *pval); return 0; } char _license[] SEC("license") = "GPL"; int _version SEC("version") = LINUX_VERSION_CODE; /************************* END ***************************/ - Normal case: # ./perf record -e './test_bpf_map_1.c/map:channel.value=10/' usleep 10 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.012 MB perf.data ] - Error case: # ./perf record -e './test_bpf_map_1.c/map:channel.value/' usleep 10 event syntax error: '..ps:channel:value/' \___ Config value not set (missing '=') Hint: Valid config term: map:[<arraymap>]:value=[value] (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 # ./perf record -e './test_bpf_map_1.c/xmap:channel.value=10/' usleep 10 event syntax error: '..pf_map_1.c/xmap:channel.value=10/' \___ Invalid object config option [SNIP] # ./perf record -e './test_bpf_map_1.c/map:xchannel.value=10/' usleep 10 event syntax error: '..p_1.c/map:xchannel.value=10/' \___ Target map not exist [SNIP] # ./perf record -e './test_bpf_map_1.c/map:channel.xvalue=10/' usleep 10 event syntax error: '..ps:channel.xvalue=10/' \___ Invalid object map config option [SNIP] # ./perf record -e './test_bpf_map_1.c/map:channel.value=x10/' usleep 10 event syntax error: '..nnel.value=x10/' \___ Incorrect value type for map [SNIP] Change BPF_MAP_TYPE_ARRAY to '1' in test_bpf_map_1.c: # ./perf record -e './test_bpf_map_1.c/map:channel.value=10/' usleep 10 event syntax error: '..ps:channel.value=10/' \___ Can't use this config term to this type of map Hint: Valid config term: map:[<arraymap>].value=[value] (add -v to see detail) Signed-off-by: Wang Nan <wangnan0@huawei.com> [for parser part] Acked-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Arnaldo 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-5-git-send-email-wangnan0@huawei.com Signed-off-by: He Kuang <hekuang@huawei.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
180 lines
5.6 KiB
C
180 lines
5.6 KiB
C
#ifndef __PERF_PARSE_EVENTS_H
|
|
#define __PERF_PARSE_EVENTS_H
|
|
/*
|
|
* Parse symbolic events/counts passed in as options:
|
|
*/
|
|
|
|
#include <linux/list.h>
|
|
#include <stdbool.h>
|
|
#include <linux/types.h>
|
|
#include <linux/perf_event.h>
|
|
|
|
struct list_head;
|
|
struct perf_evsel;
|
|
struct perf_evlist;
|
|
struct parse_events_error;
|
|
|
|
struct option;
|
|
|
|
struct tracepoint_path {
|
|
char *system;
|
|
char *name;
|
|
struct tracepoint_path *next;
|
|
};
|
|
|
|
extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
|
|
extern struct tracepoint_path *tracepoint_name_to_path(const char *name);
|
|
extern bool have_tracepoints(struct list_head *evlist);
|
|
|
|
const char *event_type(int type);
|
|
|
|
extern int parse_events_option(const struct option *opt, const char *str,
|
|
int unset);
|
|
extern int parse_events(struct perf_evlist *evlist, const char *str,
|
|
struct parse_events_error *error);
|
|
extern int parse_events_terms(struct list_head *terms, const char *str);
|
|
extern int parse_filter(const struct option *opt, const char *str, int unset);
|
|
extern int exclude_perf(const struct option *opt, const char *arg, int unset);
|
|
|
|
#define EVENTS_HELP_MAX (128*1024)
|
|
|
|
enum perf_pmu_event_symbol_type {
|
|
PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */
|
|
PMU_EVENT_SYMBOL, /* normal style PMU event */
|
|
PMU_EVENT_SYMBOL_PREFIX, /* prefix of pre-suf style event */
|
|
PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */
|
|
};
|
|
|
|
struct perf_pmu_event_symbol {
|
|
char *symbol;
|
|
enum perf_pmu_event_symbol_type type;
|
|
};
|
|
|
|
enum {
|
|
PARSE_EVENTS__TERM_TYPE_NUM,
|
|
PARSE_EVENTS__TERM_TYPE_STR,
|
|
};
|
|
|
|
enum {
|
|
PARSE_EVENTS__TERM_TYPE_USER,
|
|
PARSE_EVENTS__TERM_TYPE_CONFIG,
|
|
PARSE_EVENTS__TERM_TYPE_CONFIG1,
|
|
PARSE_EVENTS__TERM_TYPE_CONFIG2,
|
|
PARSE_EVENTS__TERM_TYPE_NAME,
|
|
PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
|
|
PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ,
|
|
PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
|
|
PARSE_EVENTS__TERM_TYPE_TIME,
|
|
PARSE_EVENTS__TERM_TYPE_CALLGRAPH,
|
|
PARSE_EVENTS__TERM_TYPE_STACKSIZE,
|
|
PARSE_EVENTS__TERM_TYPE_NOINHERIT,
|
|
PARSE_EVENTS__TERM_TYPE_INHERIT,
|
|
__PARSE_EVENTS__TERM_TYPE_NR,
|
|
};
|
|
|
|
struct parse_events_term {
|
|
char *config;
|
|
union {
|
|
char *str;
|
|
u64 num;
|
|
} val;
|
|
int type_val;
|
|
int type_term;
|
|
struct list_head list;
|
|
bool used;
|
|
|
|
/* error string indexes for within parsed string */
|
|
int err_term;
|
|
int err_val;
|
|
};
|
|
|
|
struct parse_events_error {
|
|
int idx; /* index in the parsed string */
|
|
char *str; /* string to display at the index */
|
|
char *help; /* optional help string */
|
|
};
|
|
|
|
struct parse_events_evlist {
|
|
struct list_head list;
|
|
int idx;
|
|
int nr_groups;
|
|
struct parse_events_error *error;
|
|
};
|
|
|
|
struct parse_events_terms {
|
|
struct list_head *terms;
|
|
};
|
|
|
|
void parse_events__shrink_config_terms(void);
|
|
int parse_events__is_hardcoded_term(struct parse_events_term *term);
|
|
int parse_events_term__num(struct parse_events_term **term,
|
|
int type_term, char *config, u64 num,
|
|
void *loc_term, void *loc_val);
|
|
int parse_events_term__str(struct parse_events_term **term,
|
|
int type_term, char *config, char *str,
|
|
void *loc_term, void *loc_val);
|
|
int parse_events_term__sym_hw(struct parse_events_term **term,
|
|
char *config, unsigned idx);
|
|
int parse_events_term__clone(struct parse_events_term **new,
|
|
struct parse_events_term *term);
|
|
void parse_events_terms__delete(struct list_head *terms);
|
|
void parse_events_terms__purge(struct list_head *terms);
|
|
int parse_events__modifier_event(struct list_head *list, char *str, bool add);
|
|
int parse_events__modifier_group(struct list_head *list, char *event_mod);
|
|
int parse_events_name(struct list_head *list, char *name);
|
|
int parse_events_add_tracepoint(struct list_head *list, int *idx,
|
|
char *sys, char *event,
|
|
struct parse_events_error *error,
|
|
struct list_head *head_config);
|
|
int parse_events_load_bpf(struct parse_events_evlist *data,
|
|
struct list_head *list,
|
|
char *bpf_file_name,
|
|
bool source,
|
|
struct list_head *head_config);
|
|
/* Provide this function for perf test */
|
|
struct bpf_object;
|
|
int parse_events_load_bpf_obj(struct parse_events_evlist *data,
|
|
struct list_head *list,
|
|
struct bpf_object *obj);
|
|
int parse_events_add_numeric(struct parse_events_evlist *data,
|
|
struct list_head *list,
|
|
u32 type, u64 config,
|
|
struct list_head *head_config);
|
|
int parse_events_add_cache(struct list_head *list, int *idx,
|
|
char *type, char *op_result1, char *op_result2,
|
|
struct parse_events_error *error,
|
|
struct list_head *head_config);
|
|
int parse_events_add_breakpoint(struct list_head *list, int *idx,
|
|
void *ptr, char *type, u64 len);
|
|
int parse_events_add_pmu(struct parse_events_evlist *data,
|
|
struct list_head *list, char *name,
|
|
struct list_head *head_config);
|
|
enum perf_pmu_event_symbol_type
|
|
perf_pmu__parse_check(const char *name);
|
|
void parse_events__set_leader(char *name, struct list_head *list);
|
|
void parse_events_update_lists(struct list_head *list_event,
|
|
struct list_head *list_all);
|
|
void parse_events_evlist_error(struct parse_events_evlist *data,
|
|
int idx, const char *str);
|
|
|
|
void print_events(const char *event_glob, bool name_only);
|
|
|
|
struct event_symbol {
|
|
const char *symbol;
|
|
const char *alias;
|
|
};
|
|
extern struct event_symbol event_symbols_hw[];
|
|
extern struct event_symbol event_symbols_sw[];
|
|
void print_symbol_events(const char *event_glob, unsigned type,
|
|
struct event_symbol *syms, unsigned max,
|
|
bool name_only);
|
|
void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
|
|
bool name_only);
|
|
int print_hwcache_events(const char *event_glob, bool name_only);
|
|
extern int is_valid_tracepoint(const char *event_string);
|
|
|
|
int valid_event_mount(const char *eventfs);
|
|
char *parse_events_formats_error_string(char *additional_terms);
|
|
|
|
#endif /* __PERF_PARSE_EVENTS_H */
|