From: Wang Nan <wangnan0@huawei.com>
To: <acme@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <joe@ovn.org>,
Wang Nan <wangnan0@huawei.com>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
He Kuang <hekuang@huawei.com>, Jiri Olsa <jolsa@kernel.org>,
Zefan Li <lizefan@huawei.com>, <pi3orama@163.com>
Subject: [PATCH v4 13/18] perf clang jit: Allow jitted perf hook access BPF maps
Date: Tue, 6 Dec 2016 07:13:51 +0000 [thread overview]
Message-ID: <20161206071356.5312-14-wangnan0@huawei.com> (raw)
In-Reply-To: <20161206071356.5312-1-wangnan0@huawei.com>
Newly introduced jit-helpers.[ch] defines a series of helpers which helps
jitted perf hook functions accessing BPF maps defined in their BPF scripts.
The helpers fetches fd of 'struct bpf_map' from 'struct bpf_object' and the
address of 'struct bpf_map_def' in jitted file. 'struct bpf_object' is the
context passed to hooks.
Jit helpers added in this commits are all leading with 'perf_'. We don't use
'bpf_' prefix because in following commits 'bpf_' prefix is going to be assigned
to kernel side BPF map operations. Same operation has different protocol for
kernel and user.
Example:
$ cat ./test.c
/*******************************************************/
#define SEC(name) __attribute__((section(name), used))
#define BPF_MAP_TYPE_ARRAY 2
#define BPF_MAP_TYPE_PERF_EVENT_ARRAY 4
#define BPF_FUNC_map_lookup_elem 1
static void *(*bpf_map_lookup_elem)(void *map, void *key) =
(void *) BPF_FUNC_map_lookup_elem;
struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
};
struct bpf_map_def SEC("maps") counter = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 1,
};
extern int perf_map_update_elem(void *ctx, struct bpf_map_def *map,
void *key, void *value, unsigned long flags);
extern int perf_map_lookup_elem(void *ctx, struct bpf_map_def *map,
void *key, void *value);
SEC("sys_close=SyS_close")
int sys_close(void *ctx)
{
int key = 0;
int *value;
value = bpf_map_lookup_elem(&counter, &key);
if (!value)
return 0;
__sync_fetch_and_add(value, 1);
return 0;
}
extern int printf(const char *fmt, ...);
SEC("perfhook:record_start")
void record_start(void *ctx)
{
int key = 0;
int value = 100000000;
printf("Welcom to perf record\n");
perf_map_update_elem(ctx, &counter, &key, &value, 0);
}
SEC("perfhook:record_end")
void record_end(void *ctx)
{
int key = 0;
int value;
perf_map_lookup_elem(ctx, &counter, &key, &value);
printf("Goodbye, perf record, value=%d\n", value);
}
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;
/*******************************************************/
$ sudo perf record -e ./test.c echo Hehe
Welcom to perf record
Hehe
[ perf record: Woken up 1 times to write data ]
Goodbye, perf record, value=100000644
[ perf record: Captured and wrote 0.014 MB perf.data ]
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Alexei Starovoitov <ast@fb.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
---
tools/perf/util/Build | 1 +
tools/perf/util/c++/clang.cpp | 9 ++++++-
tools/perf/util/jit-helpers.c | 57 +++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/jit-helpers.h | 28 +++++++++++++++++++++
4 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 tools/perf/util/jit-helpers.c
create mode 100644 tools/perf/util/jit-helpers.h
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 3840e3a..e42ae4f 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -125,6 +125,7 @@ libperf-$(CONFIG_DWARF) += genelf_debug.o
endif
libperf-y += perf-hooks.o
+libperf-y += jit-helpers.o
libperf-$(CONFIG_CXX) += c++/
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 684855c..1bd92ea 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -38,6 +38,7 @@
#include "llvm-utils.h"
#include "util-cxx.h"
#include "perf-hooks.h"
+#include "jit-helpers.h"
namespace perf {
@@ -199,12 +200,18 @@ PerfModule::toBPFObject(void)
return std::move(Buffer);
}
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
static std::map<const std::string, const void *> exported_funcs =
{
-#define EXPORT(f) {#f, (const void *)&f}
+#define EXPORT(f) {__stringify(f), (const void *)&f}
EXPORT(test__clang_callback),
EXPORT(printf),
EXPORT(puts),
+ EXPORT(JIT_HELPER_FUNC_NAME(map_update_elem)),
+ EXPORT(JIT_HELPER_FUNC_NAME(map_lookup_elem)),
+ EXPORT(JIT_HELPER_FUNC_NAME(map_get_next_key)),
+ EXPORT(JIT_HELPER_FUNC_NAME(map_pin)),
#undef EXPORT
};
diff --git a/tools/perf/util/jit-helpers.c b/tools/perf/util/jit-helpers.c
new file mode 100644
index 0000000..1a37a20
--- /dev/null
+++ b/tools/perf/util/jit-helpers.c
@@ -0,0 +1,57 @@
+/*
+ * jit-helper.c
+ *
+ * Copyright (C) 2016 Wang Nan <wangnan0@huawei.com>
+ * Copyright (C) 2016 Huawei Inc.
+ *
+ * Provide helpers which can be invoked by jit scripts attached to
+ * perf hooks.
+ */
+
+#include <util/jit-helpers.h>
+#include <util/bpf-loader.h>
+#include <bpf/libbpf.h>
+#include <bpf/bpf.h>
+
+#include "asm/bug.h"
+
+static int get_bpf_map_fd(struct bpf_object *obj, void *map)
+{
+ int fd;
+ char errbuf[BUFSIZ];
+
+ fd = bpf__map_fd(obj, map);
+ if (fd < 0) {
+ bpf__strerror_map_fd(obj, map, fd, errbuf, sizeof(errbuf));
+ WARN_ONCE(fd < 0, "Failed to get map fd: %s\n", errbuf);
+ }
+ return fd;
+}
+
+#define PARAMS(args...) args
+#define DEFINE_JIT_BPF_MAP_HELPER(name, proto, args) \
+ JIT_BPF_MAP_HELPER(name, proto) { \
+ int map_fd = get_bpf_map_fd(ctx, map); \
+ \
+ if (map_fd < 0) \
+ return map_fd; \
+ return bpf_map_##name(map_fd, args); \
+ }
+
+DEFINE_JIT_BPF_MAP_HELPER(update_elem,
+ PARAMS(void *key, void *value, u64 flags),
+ PARAMS(key, value, flags))
+
+DEFINE_JIT_BPF_MAP_HELPER(lookup_elem,
+ PARAMS(void *key, void *value),
+ PARAMS(key, value))
+
+DEFINE_JIT_BPF_MAP_HELPER(get_next_key,
+ PARAMS(void *key, void *next_key),
+ PARAMS(key, next_key))
+
+#define bpf_map_pin bpf_obj_pin
+DEFINE_JIT_BPF_MAP_HELPER(pin,
+ PARAMS(const char *pathname),
+ PARAMS(pathname));
+#undef bpf_map_pin
diff --git a/tools/perf/util/jit-helpers.h b/tools/perf/util/jit-helpers.h
new file mode 100644
index 0000000..b1f7479
--- /dev/null
+++ b/tools/perf/util/jit-helpers.h
@@ -0,0 +1,28 @@
+#ifndef JIT_HELPERS_H
+#define JIT_HELPERS_H
+
+#include <stdint.h>
+#include <util/perf-hooks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define JIT_HELPER_FUNC_NAME(name) perf_##name
+
+#define JIT_HELPER(type, name, ...) \
+type JIT_HELPER_FUNC_NAME(name)(__VA_ARGS__)
+
+#define JIT_BPF_MAP_HELPER(name, ...) \
+ JIT_HELPER(int, map_##name, void *ctx, void *map, ##__VA_ARGS__)
+
+extern JIT_BPF_MAP_HELPER(update_elem, void *key, void *value, uint64_t flags);
+extern JIT_BPF_MAP_HELPER(lookup_elem, void *key, void *value);
+extern JIT_BPF_MAP_HELPER(get_next_key, void *key, void *next_key);
+extern JIT_BPF_MAP_HELPER(pin, const char *pathname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--
2.10.1
next prev parent reply other threads:[~2016-12-06 7:14 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-06 7:13 [PATCH v4 00/18] perf clang: Builtin clang and perfhook support Wang Nan
2016-12-06 7:13 ` [PATCH v4 01/18] perf build: Check LLVM version in feature check Wang Nan
2016-12-06 7:20 ` Wangnan (F)
2016-12-06 7:22 ` [PATCH v4 01/18 -cleanup] " Wang Nan
2016-12-06 14:02 ` Arnaldo Carvalho de Melo
2016-12-07 18:22 ` [tip:perf/core] " tip-bot for Wang Nan
2016-12-06 7:13 ` [PATCH v4 02/18] perf build: Support dynamic linking clang libraries Wang Nan
2016-12-06 7:13 ` [PATCH v4 03/18] perf clang: Cleanup clang options Wang Nan
2016-12-06 7:13 ` [PATCH v4 04/18] perf clang: Pass full path to builtin clang Wang Nan
2016-12-06 7:13 ` [PATCH v4 05/18] perf clang: Pass CFLAGS " Wang Nan
2016-12-06 7:13 ` [PATCH v4 06/18] perf clang jit: Wrap llvm::Module using PerfModule Wang Nan
2016-12-06 7:13 ` [PATCH v4 07/18] perf clang jit: Insignt BPF and JIT functions in a Module Wang Nan
2016-12-06 7:13 ` [PATCH v4 08/18] perf clang jit: add PerfModule::doJIT to JIT perfhook functions Wang Nan
2016-12-06 7:13 ` [PATCH v4 09/18] perf clang jit: Export functions for jitted code Wang Nan
2016-12-06 7:13 ` [PATCH v4 10/18] perf clang jit: Actually JIT and hook in bpf loader Wang Nan
2016-12-06 7:13 ` [PATCH v4 11/18] perf clang jit: Collect the lowest address in maps section as map_base Wang Nan
2016-12-06 7:13 ` [PATCH v4 12/18] perf clang jit: Retrive fd of BPF map from its offset Wang Nan
2016-12-06 7:13 ` Wang Nan [this message]
2016-12-06 7:13 ` [PATCH v4 14/18] perf clang: Link BPF functions declaration into perf Wang Nan
2016-12-06 7:13 ` [PATCH v4 15/18] perf clang: Declare BPF functions for BPF scripts automatically Wang Nan
2016-12-06 7:13 ` [PATCH v4 16/18] perf clang: Include helpers to BPF scripts Wang Nan
2016-12-06 7:13 ` [PATCH v4 17/18] perf clang builtin: Define hook helpers by default Wang Nan
2016-12-06 7:13 ` [PATCH v4 18/18] perf clang jit: Export getpid() to perf hook Wang Nan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161206071356.5312-14-wangnan0@huawei.com \
--to=wangnan0@huawei.com \
--cc=acme@kernel.org \
--cc=acme@redhat.com \
--cc=hekuang@huawei.com \
--cc=joe@ovn.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@huawei.com \
--cc=pi3orama@163.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome