[v4,12/18] perf clang jit: Retrive fd of BPF map from its offset

Message ID 20161206071356.5312-13-wangnan0@huawei.com
State New
Headers show

Commit Message

Wang Nan Dec. 6, 2016, 7:13 a.m.
bpf__map_fd() is introduced to retrive fd of a BPF map through its
offset in BPF object. This function is going be used in further
commits which allow scripts jitted by builtin clang access BPF maps.

Signed-off-by: Wang Nan <wangnan0@huawei.com>

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@fb.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/bpf-loader.c | 37 +++++++++++++++++++++++++++++++++++++
 tools/perf/util/bpf-loader.h | 19 +++++++++++++++++++
 2 files changed, 56 insertions(+)

-- 
2.10.1

Patch

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 9a0c33d..3eb420e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -19,6 +19,7 @@ 
 #include "parse-events.h"
 #include "llvm-utils.h"
 #include "c++/clang-c.h"
+#include "asm/bug.h"	// for WARN_ONCE
 
 #define DEFINE_PRINT_FN(name, level) \
 static int libbpf_##name(const char *fmt, ...)	\
@@ -1644,6 +1645,28 @@  int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 	return 0;
 }
 
+int bpf__map_fd(struct bpf_object *obj, void *jit_map)
+{
+	struct bpf_obj_priv *priv = bpf_object__priv(obj);
+	struct bpf_map *map;
+	size_t map_offset;
+	void *map_base;
+
+	if (IS_ERR(priv))
+		return PTR_ERR(priv);
+	if (!priv)
+		return -EINVAL;
+
+	map_base = priv->map_base;
+	map_offset = jit_map - map_base;
+	map = bpf_object__find_map_by_offset(obj, map_offset);
+	WARN_ONCE(IS_ERR(map), "can't find map offset %zu from '%s'\n",
+		  map_offset, bpf_object__name(obj));
+	if (IS_ERR(map))
+		return -ENOENT;
+	return bpf_map__fd(map);
+}
+
 #define ERRNO_OFFSET(e)		((e) - __BPF_LOADER_ERRNO__START)
 #define ERRCODE_OFFSET(c)	ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
 #define NR_ERRNO	(__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
@@ -1825,3 +1848,17 @@  int bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
 	bpf__strerror_end(buf, size);
 	return 0;
 }
+
+int bpf__strerror_map_fd(struct bpf_object *obj, void *jit_map,
+			 int err, char *buf, size_t size)
+{
+	struct bpf_obj_priv *priv = bpf_object__priv(obj);
+	ptrdiff_t offset = priv ? jit_map - priv->map_base : jit_map - NULL;
+
+	bpf__strerror_head(err, buf, size);
+	bpf__strerror_entry(EINVAL, "No map in BPF object %s", bpf_object__name(obj));
+	bpf__strerror_entry(ENOENT, "Can't find map offset %lx in BPF object %s",
+			    (unsigned long)offset, bpf_object__name(obj));
+	bpf__strerror_end(buf, size);
+	return 0;
+}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index f2b737b..c40812b 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -84,6 +84,9 @@  int bpf__setup_stdout(struct perf_evlist *evlist);
 int bpf__strerror_setup_stdout(struct perf_evlist *evlist, int err,
 			       char *buf, size_t size);
 
+int bpf__map_fd(struct bpf_object *obj, void *jit_map);
+int bpf__strerror_map_fd(struct bpf_object *obj, void *jit_map,
+			 int err, char *buf, size_t size);
 #else
 static inline struct bpf_object *
 bpf__prepare_load(const char *filename __maybe_unused,
@@ -136,6 +139,13 @@  bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 }
 
 static inline int
+bpf__map_fd(struct bpf_object *obj __maybe_unused,
+	    void *map_ptr __maybe_unused)
+{
+	return -ENOTSUP;
+}
+
+static inline int
 __bpf_strerror(char *buf, size_t size)
 {
 	if (!size)
@@ -196,5 +206,14 @@  bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
 {
 	return __bpf_strerror(buf, size);
 }
+
+static inline int
+bpf__strerror_map_fd(struct bpf_object *obj __maybe_unused,
+		     void *jit_map __maybe_unused,
+		     int err __maybe_unused,
+		     char *buf, size_t size);
+{
+	return __bpf_strerror(buf, size);
+}
 #endif
 #endif