[RFC PATCH 04/22] perf tools: Add new 'perf bpf' command.

Wang Nan
2015-04-30T11:01:00Z

Adding new 'perf bpf' command to provide eBPF program loading and
management support.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
---
tools/perf/Build | 1 +
tools/perf/Documentation/perf-bpf.txt | 18 ++++++++++
tools/perf/builtin-bpf.c | 63 +++++++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1 +
tools/perf/perf.c | 1 +
tools/perf/util/Build | 1 +
tools/perf/util/bpf-loader.c | 35 +++++++++++++++++++
tools/perf/util/bpf-loader.h | 21 ++++++++++++
8 files changed, 141 insertions(+)
create mode 100644 tools/perf/Documentation/perf-bpf.txt
create mode 100644 tools/perf/builtin-bpf.c
create mode 100644 tools/perf/util/bpf-loader.c
create mode 100644 tools/perf/util/bpf-loader.h

diff --git a/tools/perf/Build b/tools/perf/Build
index b77370e..c69f0c1 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-y += 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..634d588
--- /dev/null
+++ b/tools/perf/Documentation/perf-bpf.txt
@@ -0,0 +1,18 @@
+perf-bpf(1)
+==============
+
+NAME
+----
+perf-bpf - loads eBPF programs into kernel.
+
+SYNOPSIS
+--------
+[verse]
+'perf bpf' [<common options>] <bpfprogram.o>",
+
+DESCRIPTION
+-----------
+Loading eBPF programs into kernel.
+
+OPTIONS
+-------
diff --git a/tools/perf/builtin-bpf.c b/tools/perf/builtin-bpf.c
new file mode 100644
index 0000000..0fc7a82
--- /dev/null
+++ b/tools/perf/builtin-bpf.c
@@ -0,0 +1,63 @@
+/*
+ * buildin-bpf.c
+ *
+ * Buildin bpf command: Load bpf and attach bpf programs onto kprobes.
+ */
+#include "builtin.h"
+#include "perf.h"
+#include "debug.h"
+#include "parse-options.h"
+#include "bpf-loader.h"
+
+static const char *bpf_usage[] = {
+ "perf bpf [<options>] <bpfobj>",
+ NULL
+};
+
+static void print_usage(void)
+{
+ printf("Usage:\n");
+ printf("\t%s\n\n", bpf_usage[0]);
+}
+
+struct option __bpf_options[] = {
+ OPT_INCR('v', "verbose", &verbose, "be more verbose"),
+ OPT_END()
+};
+
+struct option *bpf_options = __bpf_options;
+
+int cmd_bpf(int argc, const char **argv,
+ const char *prefix __maybe_unused)
+{
+ int err;
+ const char **pfn;
+
+ if (argc < 2)
+ goto usage;
+
+ argc = parse_options(argc, argv, bpf_options, bpf_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+ if (argc < 1)
+ goto usage;
+
+ pfn = argv;
+ while (*pfn != NULL) {
+ const char *fn = *pfn++;
+
+ err = bpf__load(fn);
+ if (err) {
+ pr_err("bpf: load bpf program from %s: result: %d\n",
+ fn, err);
+ break;
+ }
+ }
+
+ if (!err)
+ bpf__run();
+ return err;
+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/perf.c b/tools/perf/perf.c
index b857fcb..779f2fb 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -64,6 +64,7 @@ static struct cmd_struct commands[] = {
{ "inject", cmd_inject, 0 },
{ "mem", cmd_mem, 0 },
{ "data", cmd_data, 0 },
+ { "bpf", cmd_bpf, 0 },
};

struct pager_config {
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index dfba2f0..39287a5 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -75,6 +75,7 @@ libperf-$(CONFIG_X86) += tsc.o
libperf-y += cloexec.o
libperf-y += thread-stack.o
libperf-y += bpf.o
+libperf-y += bpf-loader.o

libperf-$(CONFIG_LIBELF) += symbol-elf.o
libperf-$(CONFIG_LIBELF) += probe-event.o
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
new file mode 100644
index 0000000..84d3cc3
--- /dev/null
+++ b/tools/perf/util/bpf-loader.c
@@ -0,0 +1,35 @@
+/*
+ * BPF loader support.
+ *
+ * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
+ * Copyright (C) 2015, Huawei Inc.
+ *
+ * Released under the GPL v2. (and only v2, not any later version)
+ */
+#include <stdio.h>
+#include <errno.h>
+
+#include "perf.h"
+#include "debug.h"
+#include "symbol.h"
+#include "bpf-loader.h"
+#include "probe-event.h"
+#include "probe-finder.h" // for MAX_PROBES
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/bpf.h>
+
+int bpf__load(const char *path)
+{
+ pr_debug("bpf: loading %s\n", path);
+ return 0;
+}
+
+int bpf__run(void)
+{
+ pr_info("BPF is running. Use Ctrl-c to stop.\n");
+ while(1)
+ sleep(1);
+ return 0;
+}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
new file mode 100644
index 0000000..122b178
--- /dev/null
+++ b/tools/perf/util/bpf-loader.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
+ * Copyright (C) 2015, Huawei Inc.
+ *
+ * Released under the GPL v2. (and only v2, not any later version)
+ */
+#ifndef __BPF_LOADER_H
+#define __BPF_LOADER_H
+
+#include <linux/unistd.h>
+#include <unistd.h>
+#include <linux/bpf.h>
+
+#include "perf.h"
+#include "symbol.h"
+#include "probe-event.h"
+
+int bpf__load(const char *path);
+int bpf__run(void);
+
+#endif
--
1.8.3.4