From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751847AbcBLQMN (ORCPT ); Fri, 12 Feb 2016 11:12:13 -0500 Received: from mga14.intel.com ([192.55.52.115]:52188 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750902AbcBLQMJ (ORCPT ); Fri, 12 Feb 2016 11:12:09 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,436,1449561600"; d="scan'208";a="744969987" From: Tom Zanussi To: ast@plumgrid.com, rostedt@goodmis.org Cc: masami.hiramatsu.pt@hitachi.com, namhyung@kernel.org, peterz@infradead.org, linux-kernel@vger.kernel.org, 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 Message-Id: <80456b6e0752ab709f36c57845b4b5d257bbcf32.1455291671.git.tom.zanussi@linux.intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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