linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Wang Nan <wangnan0@huawei.com>
To: <acme@redhat.com>, <ast@fb.com>
Cc: <lizefan@huawei.com>, <hekuang@huawei.com>,
	<linux-kernel@vger.kernel.org>, <pi3orama@163.com>,
	Wang Nan <wangnan0@huawei.com>, Jiri Olsa <jolsa@kernel.org>
Subject: [PATCH 29/34] perf clang jit: Allow jitted perf hook access BPF maps
Date: Tue, 15 Nov 2016 04:06:12 +0000	[thread overview]
Message-ID: <20161115040617.69788-30-wangnan0@huawei.com> (raw)
In-Reply-To: <20161115040617.69788-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.

 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 jit_helper__map_update_elem(void *ctx, struct bpf_map_def *map,
                         void *key, void *value, unsigned long flags);
  extern int jit_helper__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");
      jit_helper__map_update_elem(ctx, &counter, &key, &value, 0);
  }

  SEC("perfhook:record_end")
  void record_end(void *ctx)
  {
      int key = 0;
      int value;
      jit_helper__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>
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/Build         |  1 +
 tools/perf/util/c++/clang.cpp | 10 +++++++-
 tools/perf/util/jit-helpers.c | 60 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/jit-helpers.h | 30 ++++++++++++++++++++++
 4 files changed, 100 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 743a889..33773cb 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -124,6 +124,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 f8ea9bd..e500525 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 {
 
@@ -196,12 +197,19 @@ 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)),
+	EXPORT(JIT_HELPER_FUNC_NAME(map_get)),
 #undef EXPORT
 };
 
diff --git a/tools/perf/util/jit-helpers.c b/tools/perf/util/jit-helpers.c
new file mode 100644
index 0000000..993de14
--- /dev/null
+++ b/tools/perf/util/jit-helpers.c
@@ -0,0 +1,60 @@
+/*
+ * 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_JIT_BPF_MAP_HELPER(pin,
+			  PARAMS(const char *pathname),
+			  PARAMS(pathname));
+
+JIT_HELPER(int, map_get, const char *pathname)
+{
+	return bpf_map_get(pathname);
+}
diff --git a/tools/perf/util/jit-helpers.h b/tools/perf/util/jit-helpers.h
new file mode 100644
index 0000000..49e0578
--- /dev/null
+++ b/tools/perf/util/jit-helpers.h
@@ -0,0 +1,30 @@
+#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) jit_helper__##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);
+
+extern JIT_HELPER(int, map_get, const char *pathname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
2.10.1

  parent reply	other threads:[~2016-11-15  4:10 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-15  4:05 [PATCH 00/34] perf clang: Builtin clang and perfhook support Wang Nan
2016-11-15  4:05 ` [PATCH 01/34] perf tools: Fix kernel version error in ubuntu Wang Nan
2016-11-25 17:20   ` [tip:perf/core] " tip-bot for Wang Nan
2016-11-15  4:05 ` [PATCH 02/34] perf record: Fix segfault when running with suid and kptr_restrict is 1 Wang Nan
2016-11-25 17:21   ` [tip:perf/core] " tip-bot for Wang Nan
2016-11-15  4:05 ` [PATCH 03/34] tools perf: Add missing struct defeinition in probe_event.h Wang Nan
2016-11-25 17:21   ` [tip:perf/core] perf tools: Add missing struct definition " tip-bot for Wang Nan
2016-11-15  4:05 ` [PATCH 04/34] tools lib bpf: fix maps resolution Wang Nan
2016-11-25 17:22   ` [tip:perf/core] tools lib bpf: Fix " tip-bot for Eric Leblond
2016-11-15  4:05 ` [PATCH 05/34] tools lib bpf: Add missing bpf map functions Wang Nan
2016-11-17  3:23   ` Wangnan (F)
2016-11-25 14:31     ` Arnaldo Carvalho de Melo
2016-11-15  4:05 ` [PATCH 06/34] tools lib bpf: Add private field for bpf_object Wang Nan
2016-11-15  4:05 ` [PATCH 07/34] tools lib bpf: Retrive bpf_map through offset of bpf_map_def Wang Nan
2016-11-15  4:05 ` [PATCH 08/34] perf tools: Introduce perf hooks Wang Nan
2016-11-15  4:05 ` [PATCH 09/34] perf tools: Pass context to perf hook functions Wang Nan
2016-11-15  4:05 ` [PATCH 10/34] perf llvm: Extract helpers in llvm-utils.c Wang Nan
2016-11-15  4:05 ` [PATCH 11/34] tools build: Add feature detection for LLVM Wang Nan
2016-11-15  4:05 ` [PATCH 12/34] tools build: Add feature detection for clang Wang Nan
2016-11-15  4:05 ` [PATCH 13/34] perf build: Add clang and llvm compile and linking support Wang Nan
2016-11-15  4:05 ` [PATCH 14/34] perf clang: Add builtin clang support ant test case Wang Nan
2016-11-15  4:05 ` [PATCH 15/34] perf clang: Use real file system for #include Wang Nan
2016-11-15  4:05 ` [PATCH 16/34] perf clang: Allow passing CFLAGS to builtin clang Wang Nan
2016-11-15  4:06 ` [PATCH 17/34] perf clang: Update test case to use real BPF script Wang Nan
2016-11-15  4:06 ` [PATCH 18/34] perf clang: Support compile IR to BPF object and add testcase Wang Nan
2016-11-15  4:06 ` [PATCH 19/34] perf clang: Compile BPF script use builtin clang support Wang Nan
2016-11-15  4:06 ` [PATCH 20/34] perf clang: Pass full path to builtin clang Wang Nan
2016-11-15  4:06 ` [PATCH 21/34] perf clang: Pass CFLAGS " Wang Nan
2016-11-15  4:06 ` [PATCH 22/34] perf clang jit: Wrap llvm::Module using PerfModule Wang Nan
2016-11-15  4:06 ` [PATCH 23/34] perf clang jit: Insignt BPF and JIT functions in a Module Wang Nan
2016-11-15  4:06 ` [PATCH 24/34] perf clang jit: add PerfModule::doJIT to JIT perfhook functions Wang Nan
2016-11-15  4:06 ` [PATCH 25/34] perf clang jit: Export functions for jitted code Wang Nan
2016-11-15  4:06 ` [PATCH 26/34] perf clang jit: Actually JIT and hook in bpf loader Wang Nan
2016-11-15  4:06 ` [PATCH 27/34] perf clang jit: Collect the lowest address in maps section as map_base Wang Nan
2016-11-15  4:06 ` [PATCH 28/34] perf clang jit: Access BPF map Wang Nan
2016-11-15  4:06 ` Wang Nan [this message]
2016-11-15  4:06 ` [PATCH 30/34] perf clang: Link BPF functions declaration into perf Wang Nan
2016-11-15  4:06 ` [PATCH 31/34] perf clang: Declare BPF functions for BPF scripts automatically Wang Nan
2016-11-15  4:06 ` [PATCH 32/34] perf clang: Include helpers to BPF scripts Wang Nan
2016-11-15  4:06 ` [PATCH 33/34] perf clang builtin: Define hook helpers by default Wang Nan
2016-11-15  4:06 ` [PATCH 34/34] perf clang git: Export getpid() to perf hook Wang Nan
2016-11-15  4:32 ` [PATCH 00/34] perf clang: Builtin clang and perfhook support Wangnan (F)

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=20161115040617.69788-30-wangnan0@huawei.com \
    --to=wangnan0@huawei.com \
    --cc=acme@redhat.com \
    --cc=ast@fb.com \
    --cc=hekuang@huawei.com \
    --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;
as well as URLs for NNTP newsgroup(s).