Messages in this thread Patch in this message | | | From | Tom Zanussi <> | Subject | [RFC][PATCH 08/10] samples/bpf: Add support for trace events to the eBPF loading code | Date | Fri, 12 Feb 2016 10:11:26 -0600 |
| |
Because we now have two types of eBPF programs that can attach to kprobes, we need to add a way to distinguish them.
BPF_PROG_TYPE_KPROBE programs are defined the same as they were before:
SEC("kprobe/...")
BPF_PROG_TYPE_TRACE_EVENT programs always start with 'event/'. A TRACE_EVENT program on a kprobe would be defined in the same way as a KPROBE program but would prepend the 'event/': before bu can be applied to kprobes by
SEC("event/kprobe/...") SEC("event/kretprobe/...")
BPF_PROG_TYPE_TRACE_EVENT program on a static trace event simply specifies 'event/' plus the colon-separated subsys:event name:
SEC("event/subsys:event")
Also, add a couple helper declarations for the new field-reading helper functions.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> --- samples/bpf/bpf_helpers.h | 4 ++++ samples/bpf/bpf_load.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index 7ad19e1..a2fe8df 100644 --- a/samples/bpf/bpf_helpers.h +++ b/samples/bpf/bpf_helpers.h @@ -39,6 +39,10 @@ static int (*bpf_redirect)(int ifindex, int flags) = (void *) BPF_FUNC_redirect; static int (*bpf_perf_event_output)(void *ctx, void *map, int index, void *data, int size) = (void *) BPF_FUNC_perf_event_output; +static int (*bpf_trace_event_field_read)(void *ctx, const char *field_name) = + (void *) BPF_FUNC_trace_event_field_read; +static int (*bpf_trace_event_field_read_string)(void *ctx, const char *field_name, void *buf, int size) = + (void *) BPF_FUNC_trace_event_field_read_string; /* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c index da86a8e..006a139 100644 --- a/samples/bpf/bpf_load.c +++ b/samples/bpf/bpf_load.c @@ -46,14 +46,39 @@ static int populate_prog_array(const char *event, int prog_fd) static int load_and_attach(const char *event, struct bpf_insn *prog, int size) { + bool is_trace_event = strncmp(event, "event/", 6) == 0; bool is_socket = strncmp(event, "socket", 6) == 0; - bool is_kprobe = strncmp(event, "kprobe/", 7) == 0; - bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0; + bool is_kretprobe = false; + bool is_kprobe = false; + enum bpf_prog_type prog_type; - char buf[256]; + char buf[256], event_buf[256]; int fd, efd, err, id; struct perf_event_attr attr = {}; + char *event_name = NULL; + char *subsys_name = NULL; + + if (is_trace_event) + event += 6; + + is_kprobe = strncmp(event, "kprobe/", 7) == 0; + is_kretprobe = strncmp(event, "kretprobe/", 10) == 0; + + if (is_trace_event) { + if (!(is_kprobe || is_kretprobe)) { + strncpy(event_buf, event, 255); + event_buf[255] = '\0'; + + event_name = event_buf; + subsys_name = strsep(&event_name, ":"); + if (!subsys_name || !event_name) { + printf("Unknown trace event '%s'\n", event); + return -1; + } + } + } + attr.type = PERF_TYPE_TRACEPOINT; attr.sample_type = PERF_SAMPLE_RAW; attr.sample_period = 1; @@ -61,6 +86,8 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) if (is_socket) { prog_type = BPF_PROG_TYPE_SOCKET_FILTER; + } else if (is_trace_event) { + prog_type = BPF_PROG_TYPE_TRACE_EVENT; } else if (is_kprobe || is_kretprobe) { prog_type = BPF_PROG_TYPE_KPROBE; } else { @@ -114,8 +141,15 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) } strcpy(buf, DEBUGFS); - strcat(buf, "events/kprobes/"); - strcat(buf, event); + if (is_kprobe || is_kretprobe) { + strcat(buf, "events/kprobes/"); + strcat(buf, event); + } else { + strcat(buf, "events/"); + strcat(buf, subsys_name); + strcat(buf, "/"); + strcat(buf, event_name); + } strcat(buf, "/id"); efd = open(buf, O_RDONLY, 0); @@ -300,6 +334,7 @@ int load_bpf_file(char *path) if (memcmp(shname_prog, "kprobe/", 7) == 0 || memcmp(shname_prog, "kretprobe/", 10) == 0 || + memcmp(shname_prog, "event/", 6) == 0 || memcmp(shname_prog, "socket", 6) == 0) load_and_attach(shname_prog, insns, data_prog->d_size); } @@ -316,6 +351,7 @@ int load_bpf_file(char *path) if (memcmp(shname, "kprobe/", 7) == 0 || memcmp(shname, "kretprobe/", 10) == 0 || + memcmp(shname, "event/", 6) == 0 || memcmp(shname, "socket", 6) == 0) load_and_attach(shname, data->d_buf, data->d_size); } -- 1.9.3
| |