Adding new 'perf bpf' command to provide eBPF program management operations. This patch only creates basic 'perf bpf'. Subcommands will be introduced in following patches.
To utilize existing code of usage_with_options() while enable subcommand list get output after 'Usage ...' indicator, this patch add a usage_with_options_noexit() function, which does similar thing except exiting, allows caller print more information before quit. In this patch, 'perf bpf' command won't be built if doesn't find libelf. Signed-off-by: Wang Nan <wangn...@huawei.com> --- tools/perf/Build | 1 + tools/perf/Documentation/perf-bpf.txt | 18 ++++++++ tools/perf/builtin-bpf.c | 85 +++++++++++++++++++++++++++++++++++ tools/perf/builtin.h | 1 + tools/perf/command-list.txt | 1 + tools/perf/perf.c | 3 ++ tools/perf/util/parse-options.c | 8 +++- tools/perf/util/parse-options.h | 2 + 8 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 tools/perf/Documentation/perf-bpf.txt create mode 100644 tools/perf/builtin-bpf.c diff --git a/tools/perf/Build b/tools/perf/Build index b77370e..c3c6cc3 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -19,6 +19,7 @@ perf-y += builtin-kvm.o perf-y += builtin-inject.o perf-y += builtin-mem.o perf-y += builtin-data.o +perf-$(CONFIG_LIBELF) += builtin-bpf.o perf-$(CONFIG_AUDIT) += builtin-trace.o perf-$(CONFIG_LIBELF) += builtin-probe.o diff --git a/tools/perf/Documentation/perf-bpf.txt b/tools/perf/Documentation/perf-bpf.txt new file mode 100644 index 0000000..0e8b590 --- /dev/null +++ b/tools/perf/Documentation/perf-bpf.txt @@ -0,0 +1,18 @@ +perf-bpf(1) +============== + +NAME +---- +perf-bpf - Management of eBPF programs. + +SYNOPSIS +-------- +[verse] +'perf bpf' [<common options>] <command> [<options>]", + +DESCRIPTION +----------- +Management of eBPF programs. + +OPTIONS +------- diff --git a/tools/perf/builtin-bpf.c b/tools/perf/builtin-bpf.c new file mode 100644 index 0000000..a8858e2 --- /dev/null +++ b/tools/perf/builtin-bpf.c @@ -0,0 +1,85 @@ +/* + * builtin-bpf.c + * + * Copyright (C) 2015, Wang Nan <wangn...@huawei.com> + * Copyright (C) 2015, Huawei Inc. + * + * Released under the GPL v2. (and only v2, not any later version) + * + * Builtin bpf command: management of bpf programs. + */ +#include "builtin.h" +#include "perf.h" +#include "debug.h" +#include "parse-options.h" + +typedef int (*bpf_cmd_fn_t)(int argc, const char **argv, const char *prefix); + +struct bpf_cmd { + const char *name; + const char *summary; + bpf_cmd_fn_t fn; +}; + +static struct bpf_cmd bpf_cmds[]; + +#define for_each_cmd(cmd) \ + for (cmd = bpf_cmds; cmd && cmd->name; cmd++) + +struct option bpf_options[] = { + OPT_INCR('v', "verbose", &verbose, "be more verbose " + "(show debug information)"), + OPT_END() +}; + +static const char *bpf_usage[] = { + "perf bpf [<command options>] <command> [<options>]", + NULL +}; + +static void print_usage(void) +{ + struct bpf_cmd *cmd; + + usage_with_options_noexit(bpf_usage, bpf_options); + printf("\tAvailable commands:\n"); + for_each_cmd(cmd) + printf("\t %s\t- %s\n", cmd->name, cmd->summary); + exit(129); +} + +static const char * const bpf_subcommands[] = { NULL }; + +static struct bpf_cmd bpf_cmds[] = { + { .name = NULL, }, +}; + +int cmd_bpf(int argc, const char **argv, + const char *prefix __maybe_unused) +{ + struct bpf_cmd *cmd; + const char *cmdstr; + + /* No command specified. */ + if (argc < 2) + goto usage; + + argc = parse_options_subcommand(argc, argv, bpf_options, bpf_subcommands, bpf_usage, + PARSE_OPT_STOP_AT_NON_OPTION); + if (argc < 1) + goto usage; + + cmdstr = argv[0]; + + for_each_cmd(cmd) { + if (strcmp(cmd->name, cmdstr)) + continue; + + return cmd->fn(argc, argv, prefix); + } + + pr_err("Unknown command %s\n", cmdstr); +usage: + print_usage(); + return -1; +} diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h index 3688ad2..c2c4a0d 100644 --- a/tools/perf/builtin.h +++ b/tools/perf/builtin.h @@ -38,6 +38,7 @@ extern int cmd_trace(int argc, const char **argv, const char *prefix); extern int cmd_inject(int argc, const char **argv, const char *prefix); extern int cmd_mem(int argc, const char **argv, const char *prefix); extern int cmd_data(int argc, const char **argv, const char *prefix); +extern int cmd_bpf(int argc, const char **argv, const char *prefix); extern int find_scripts(char **scripts_array, char **scripts_path_array); #endif diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt index 00fcaf8..1000463 100644 --- a/tools/perf/command-list.txt +++ b/tools/perf/command-list.txt @@ -5,6 +5,7 @@ perf-annotate mainporcelain common perf-archive mainporcelain common perf-bench mainporcelain common +perf-bpf mainporcelain full perf-buildid-cache mainporcelain common perf-buildid-list mainporcelain common perf-data mainporcelain common diff --git a/tools/perf/perf.c b/tools/perf/perf.c index b857fcb..eff1a55 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -64,6 +64,9 @@ static struct cmd_struct commands[] = { { "inject", cmd_inject, 0 }, { "mem", cmd_mem, 0 }, { "data", cmd_data, 0 }, +#ifdef HAVE_LIBELF_SUPPORT + { "bpf", cmd_bpf, 0 }, +#endif }; struct pager_config { diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 01626be..09e48a2 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c @@ -672,9 +672,15 @@ int usage_with_options_internal(const char * const *usagestr, void usage_with_options(const char * const *usagestr, const struct option *opts) { + usage_with_options_noexit(usagestr, opts); + exit(129); +} + +void usage_with_options_noexit(const char * const *usagestr, + const struct option *opts) +{ exit_browser(false); usage_with_options_internal(usagestr, opts, 0); - exit(129); } int parse_options_usage(const char * const *usagestr, diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h index 59561fd..41194db 100644 --- a/tools/perf/util/parse-options.h +++ b/tools/perf/util/parse-options.h @@ -156,6 +156,8 @@ extern int parse_options_subcommand(int argc, const char **argv, extern NORETURN void usage_with_options(const char * const *usagestr, const struct option *options); +extern void usage_with_options_noexit(const char * const *usagestr, + const struct option *options); /*----- incremantal advanced APIs -----*/ -- 1.8.3.4 -- 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/