From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752957AbbEQLAL (ORCPT ); Sun, 17 May 2015 07:00:11 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:61498 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753315AbbEQK6O (ORCPT ); Sun, 17 May 2015 06:58:14 -0400 From: Wang Nan To: , , , , , , , , , , CC: , , Subject: [RFC PATCH v3 29/37] perf bpf: Add 'perf bpf record' subcommand Date: Sun, 17 May 2015 10:56:54 +0000 Message-ID: <1431860222-61636-30-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1431860222-61636-1-git-send-email-wangnan0@huawei.com> References: <1431860222-61636-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.200] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 'perf bpf record' will be implemented to load eBPF object file then start recording on events defined in it. This patch only adds a '--object' option for selecting object file. Other arguments are directly passed to cmd_record. Example: # perf bpf --object obj1.o --object obj2.o -- -a command-to-record Signed-off-by: Wang Nan --- tools/perf/builtin-bpf.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-bpf.c b/tools/perf/builtin-bpf.c index a8858e2..b5c613f 100644 --- a/tools/perf/builtin-bpf.c +++ b/tools/perf/builtin-bpf.c @@ -48,14 +48,121 @@ static void print_usage(void) exit(129); } -static const char * const bpf_subcommands[] = { NULL }; +static const char * const bpf_record_usage[] = { + "perf bpf record [] -- [options passed to record]", + NULL +}; + +struct param { + struct strlist *object_file_names; +} param; + +static int add_bpf_object_file(const struct option *opt, + const char *str, + int unset __maybe_unused) +{ + struct strlist **filenames = (struct strlist **)opt->value; + + if (!*filenames) + *filenames = strlist__new(true, NULL); + + if (!*filenames) { + pr_err("alloc strlist failed\n"); + return -ENOMEM; + } + + strlist__add(*filenames, str); + return 0; +} + +static int start_bpf_record(int argc, const char **argv) +{ + int i, new_argc, err, pos = 0; + const char **new_argv; + + new_argc = argc + 1; + new_argv = malloc((new_argc + 1) * sizeof(const char *)); + if (!new_argv) { + pr_err("malloc failed\n"); + return -ENOMEM; + } + bzero(new_argv, sizeof(const char *) * (new_argc + 1)); + + new_argv[pos++] = strdup("bpf record --"); + + for (i = 0; i < argc; i++) { + new_argv[pos++] = strdup(argv[i]); + if (!new_argv[pos - 1]) { + pr_err("strdup failed\n"); + err = -ENOMEM; + goto errout; + } + } + + return cmd_record(new_argc, new_argv, NULL); + +errout: + if (new_argv) { + for (i = 0; i < pos; i++) + free((void *)new_argv[i]); + free(new_argv); + } + return err; +} + +static int cmd_bpf_record(int argc, const char **argv, + const char *prefix __maybe_unused) +{ + /* + * Options in perf-record may be mirrored here. This command + * should add '-e' options to cmd_record. + */ + static const struct option options[] = { + OPT_CALLBACK(0, "object", ¶m.object_file_names, + "file", "eBPF object file name", + add_bpf_object_file), + OPT_END() + }; + struct str_node *str_node; + + argc = parse_options(argc, argv, options, + bpf_record_usage, PARSE_OPT_KEEP_DASHDASH); + + if (!param.object_file_names) { + pr_err("At least one '--object' option is needed to " + "select an eBPF object file\n"); + goto usage; + } + + if (!argv || strcmp(argv[0], "--")) { + pr_err("Should use '--' to pass options to perf " + "record\n"); + goto usage; + } + + /* skip "--" */ + argc--; + argv++; + + strlist__for_each(str_node, param.object_file_names) + pr_debug("loading %s\n", str_node->s); + + return start_bpf_record(argc, argv); +usage: + usage_with_options(bpf_record_usage, options); + return -1; +} + + +static const char * const bpf_subcommands[] = { "record", NULL }; static struct bpf_cmd bpf_cmds[] = { + { "record", "load eBPF program into kernel then start record on events in it", cmd_bpf_record }, { .name = NULL, }, }; int cmd_bpf(int argc, const char **argv, - const char *prefix __maybe_unused) + const char *prefix) { struct bpf_cmd *cmd; const char *cmdstr; -- 1.8.3.4