net: stmmac: Meson GXBB: attempting to execute userspace memory

2016-11-25 Thread Heinrich Schuchardt
For Odroid C2 I have compiled kernel
4.9.0-rc6-next-20161124-1-gbf7e142
with one additional patch
https://github.com/xypron/kernel-odroid-c2/blob/master/patch/0001-stmmac-RTL8211F-Meson-GXBB-TX-throughput-problems.patch

I repeatedly see faults like the one below:

[ 2557.400796] Unhandled fault: synchronous external abort (0x9210)
at 0x40001e8ee4b0
[ 2557.952413] CPU: 0 PID: 22837 Comm: cc1 Tainted: G  D
4.9.0-rc6-next-20161124-1-gbf7e142 #1
[ 2557.962062] Hardware name: Hardkernel ODROID-C2 (DT)
[ 2557.966980] task: 80006ddb7080 task.stack: 80006dd9c000
[ 2557.972846] PC is at 0x6a0d98
[ 2557.975776] LR is at 0x6a0e54
[ 2557.978709] pc : [<006a0d98>] lr : [<006a0e54>]
pstate: 8000
[ 2557.986040] sp : f3ee5f80
[ 2557.989318] x29: f3ee5f80 x28: 4b3f1240
[ 2557.994578] x27: 012a7000 x26: 4b3f1288
[ 2557.999840] x25: 00f58f88 x24: 4b3f1240
[ 2558.005101] x23:  x22: 0001
[ 2558.010362] x21: 0001 x20: 4b3f1250
[ 2558.015623] x19: 0054 x18: 0001
[ 2558.020885] x17: 48acaa10 x16: 01285050
[ 2558.026146] x15: 4ad96dc8 x14: 001f
[ 2558.031407] x13: 4b3f1270 x12: 4b3f1258
[ 2558.036668] x11: 01347000 x10: 0661
[ 2558.041930] x9 : 0005 x8 : 0003
[ 2558.047191] x7 : 4b3f1240 x6 : 20020033
[ 2558.052452] x5 : 4b402020 x4 : 4b3e1aa0
[ 2558.057713] x3 : 000c x2 : 0020
[ 2558.062974] x1 : 00f45000 x0 : 0065
[ 2558.068235]
[ 2558.069712] Internal error: Attempting to execute userspace memory:
860f [#7] PREEMPT SMP
[ 2558.078155] Modules linked in: meson_rng rng_core meson_gxbb_wdt
ip_tables x_tables ipv6 dwmac_generic realtek dwmac_meson8b
stmmac_platform stmmac
[ 2558.091267] CPU: 0 PID: 22837 Comm: cc1 Tainted: G  D
4.9.0-rc6-next-20161124-1-gbf7e142 #1
[ 2558.100925] Hardware name: Hardkernel ODROID-C2 (DT)
[ 2558.105841] task: 80006ddb7080 task.stack: 80006dd9c000
[ 2558.111706] PC is at 0x6a0e54
[ 2558.114638] LR is at 0x6a0e54
[ 2558.117571] pc : [<006a0e54>] lr : [<006a0e54>]
pstate: 63c5
[ 2558.124902] sp : 80006dd9fec0
[ 2558.128179] x29:  x28: 80006ddb7080
[ 2558.133441] x27: 012a7000 x26: 4b3f1288
[ 2558.138702] x25: 00f58f88 x24: 4b3f1240
[ 2558.143963] x23: 8000 x22: 006a0d98
[ 2558.149225] x21:  x20: 80006e223000
[ 2558.154486] x19:  x18: 0010
[ 2558.159747] x17: 48acaa10 x16: 01285050
[ 2558.165008] x15: 88e91f07 x14: 0006
[ 2558.170270] x13: 08e91f15 x12: 000f
[ 2558.175531] x11: 0002 x10: 02ea
[ 2558.180792] x9 : 80006dd9fb40 x8 : 00010a8b
[ 2558.186053] x7 :  x6 : 020e
[ 2558.191315] x5 : 020f020e x4 : 
[ 2558.196576] x3 :  x2 : 020f
[ 2558.201837] x1 : 80006ddb7080 x0 : 
[ 2558.207098]
[ 2558.208565] Process cc1 (pid: 22837, stack limit = 0x80006dd9c000)
[ 2558.215035] Stack: (0x80006dd9fec0 to 0x80006dda)
[ 2558.220728] fec0: 0065 00f45000 0020
000c
[ 2558.228490] fee0: 4b3e1aa0 4b402020 20020033
4b3f1240
[ 2558.236253] ff00: 0003 0005 0661
01347000
[ 2558.244015] ff20: 4b3f1258 4b3f1270 001f
4ad96dc8
[ 2558.251778] ff40: 01285050 48acaa10 0001
0054
[ 2558.259540] ff60: 4b3f1250 0001 0001

[ 2558.267303] ff80: 4b3f1240 00f58f88 4b3f1288
012a7000
[ 2558.275065] ffa0: 4b3f1240 f3ee5f80 006a0e54
f3ee5f80
[ 2558.282828] ffc0: 006a0d98 8000 0003

[ 2558.290590] ffe0:   

[ 2558.298351] Call trace:
[ 2558.300769] Exception stack(0x80006dd9fcf0 to 0x80006dd9fe20)
[ 2558.307149] fce0:   
0001
[ 2558.314913] fd00: 80006dd9fec0 006a0e54 800073acf500
0004
[ 2558.322675] fd20:  08dbbc18 80006ddb7080
6dd9fdd0
[ 2558.330438] fd40: 80006dd9fd90 080ca878 80006dd9fe40
80006ddb7080
[ 2558.338200] fd60: 0004 03c0 80006dd9fe40
4b3f1240
[ 2558.345963] fd80: 00f58f88 4b3f1288 
80006ddb7080
[ 2558.353725] fda0: 020f  
020f020e
[ 

net: stmmac: Meson GXBB: attempting to execute userspace memory

2016-11-25 Thread Heinrich Schuchardt
For Odroid C2 I have compiled kernel
4.9.0-rc6-next-20161124-1-gbf7e142
with one additional patch
https://github.com/xypron/kernel-odroid-c2/blob/master/patch/0001-stmmac-RTL8211F-Meson-GXBB-TX-throughput-problems.patch

I repeatedly see faults like the one below:

[ 2557.400796] Unhandled fault: synchronous external abort (0x9210)
at 0x40001e8ee4b0
[ 2557.952413] CPU: 0 PID: 22837 Comm: cc1 Tainted: G  D
4.9.0-rc6-next-20161124-1-gbf7e142 #1
[ 2557.962062] Hardware name: Hardkernel ODROID-C2 (DT)
[ 2557.966980] task: 80006ddb7080 task.stack: 80006dd9c000
[ 2557.972846] PC is at 0x6a0d98
[ 2557.975776] LR is at 0x6a0e54
[ 2557.978709] pc : [<006a0d98>] lr : [<006a0e54>]
pstate: 8000
[ 2557.986040] sp : f3ee5f80
[ 2557.989318] x29: f3ee5f80 x28: 4b3f1240
[ 2557.994578] x27: 012a7000 x26: 4b3f1288
[ 2557.999840] x25: 00f58f88 x24: 4b3f1240
[ 2558.005101] x23:  x22: 0001
[ 2558.010362] x21: 0001 x20: 4b3f1250
[ 2558.015623] x19: 0054 x18: 0001
[ 2558.020885] x17: 48acaa10 x16: 01285050
[ 2558.026146] x15: 4ad96dc8 x14: 001f
[ 2558.031407] x13: 4b3f1270 x12: 4b3f1258
[ 2558.036668] x11: 01347000 x10: 0661
[ 2558.041930] x9 : 0005 x8 : 0003
[ 2558.047191] x7 : 4b3f1240 x6 : 20020033
[ 2558.052452] x5 : 4b402020 x4 : 4b3e1aa0
[ 2558.057713] x3 : 000c x2 : 0020
[ 2558.062974] x1 : 00f45000 x0 : 0065
[ 2558.068235]
[ 2558.069712] Internal error: Attempting to execute userspace memory:
860f [#7] PREEMPT SMP
[ 2558.078155] Modules linked in: meson_rng rng_core meson_gxbb_wdt
ip_tables x_tables ipv6 dwmac_generic realtek dwmac_meson8b
stmmac_platform stmmac
[ 2558.091267] CPU: 0 PID: 22837 Comm: cc1 Tainted: G  D
4.9.0-rc6-next-20161124-1-gbf7e142 #1
[ 2558.100925] Hardware name: Hardkernel ODROID-C2 (DT)
[ 2558.105841] task: 80006ddb7080 task.stack: 80006dd9c000
[ 2558.111706] PC is at 0x6a0e54
[ 2558.114638] LR is at 0x6a0e54
[ 2558.117571] pc : [<006a0e54>] lr : [<006a0e54>]
pstate: 63c5
[ 2558.124902] sp : 80006dd9fec0
[ 2558.128179] x29:  x28: 80006ddb7080
[ 2558.133441] x27: 012a7000 x26: 4b3f1288
[ 2558.138702] x25: 00f58f88 x24: 4b3f1240
[ 2558.143963] x23: 8000 x22: 006a0d98
[ 2558.149225] x21:  x20: 80006e223000
[ 2558.154486] x19:  x18: 0010
[ 2558.159747] x17: 48acaa10 x16: 01285050
[ 2558.165008] x15: 88e91f07 x14: 0006
[ 2558.170270] x13: 08e91f15 x12: 000f
[ 2558.175531] x11: 0002 x10: 02ea
[ 2558.180792] x9 : 80006dd9fb40 x8 : 00010a8b
[ 2558.186053] x7 :  x6 : 020e
[ 2558.191315] x5 : 020f020e x4 : 
[ 2558.196576] x3 :  x2 : 020f
[ 2558.201837] x1 : 80006ddb7080 x0 : 
[ 2558.207098]
[ 2558.208565] Process cc1 (pid: 22837, stack limit = 0x80006dd9c000)
[ 2558.215035] Stack: (0x80006dd9fec0 to 0x80006dda)
[ 2558.220728] fec0: 0065 00f45000 0020
000c
[ 2558.228490] fee0: 4b3e1aa0 4b402020 20020033
4b3f1240
[ 2558.236253] ff00: 0003 0005 0661
01347000
[ 2558.244015] ff20: 4b3f1258 4b3f1270 001f
4ad96dc8
[ 2558.251778] ff40: 01285050 48acaa10 0001
0054
[ 2558.259540] ff60: 4b3f1250 0001 0001

[ 2558.267303] ff80: 4b3f1240 00f58f88 4b3f1288
012a7000
[ 2558.275065] ffa0: 4b3f1240 f3ee5f80 006a0e54
f3ee5f80
[ 2558.282828] ffc0: 006a0d98 8000 0003

[ 2558.290590] ffe0:   

[ 2558.298351] Call trace:
[ 2558.300769] Exception stack(0x80006dd9fcf0 to 0x80006dd9fe20)
[ 2558.307149] fce0:   
0001
[ 2558.314913] fd00: 80006dd9fec0 006a0e54 800073acf500
0004
[ 2558.322675] fd20:  08dbbc18 80006ddb7080
6dd9fdd0
[ 2558.330438] fd40: 80006dd9fd90 080ca878 80006dd9fe40
80006ddb7080
[ 2558.338200] fd60: 0004 03c0 80006dd9fe40
4b3f1240
[ 2558.345963] fd80: 00f58f88 4b3f1288 
80006ddb7080
[ 2558.353725] fda0: 020f  
020f020e
[ 

[PATCH v3 08/30] tools build: Add feature detection for clang

2016-11-25 Thread Wang Nan
Check if basic clang compiling environment is ready.

Doesn't like 'llvm-config --libs' which can returns llvm libraries in
right order and duplicates some libraries if necessary, there's no
correspondence for clang libraries (-lclangxxx). to avoid extra
complexity and to avoid new clang breaking libraries ordering, use
--start-group and --end-group.

In this test case, manually identify required clang libs and hope it to
be stable. Putting all clang libraries here is possible (use make's
wildcard), but then feature checking becomes very slow.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-5-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/build/feature/Makefile   | 10 ++
 tools/build/feature/test-clang.cpp | 21 +
 2 files changed, 31 insertions(+)
 create mode 100644 tools/build/feature/test-clang.cpp

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index c09de59..871d553 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -237,6 +237,16 @@ $(OUTPUT)test-llvm.bin:
$(shell $(LLVM_CONFIG) --libs Core BPF) \
$(shell $(LLVM_CONFIG) --system-libs)
 
+$(OUTPUT)test-clang.bin:
+   $(BUILDXX) -std=gnu++11 \
+   -I$(shell $(LLVM_CONFIG) --includedir)  \
+   -L$(shell $(LLVM_CONFIG) --libdir)  \
+   -Wl,--start-group -lclangBasic -lclangDriver\
+ -lclangFrontend -lclangEdit -lclangLex\
+ -lclangAST -Wl,--end-group\
+   $(shell $(LLVM_CONFIG) --libs Core option)  \
+   $(shell $(LLVM_CONFIG) --system-libs)
+
 -include $(OUTPUT)*.d
 
 ###
diff --git a/tools/build/feature/test-clang.cpp 
b/tools/build/feature/test-clang.cpp
new file mode 100644
index 000..e23c1b1
--- /dev/null
+++ b/tools/build/feature/test-clang.cpp
@@ -0,0 +1,21 @@
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::driver;
+
+int main()
+{
+   IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
+   IntrusiveRefCntPtr DiagOpts = new 
DiagnosticOptions();
+
+   DiagnosticsEngine Diags(DiagID, &*DiagOpts);
+   Driver TheDriver("test", "bpf-pc-linux", Diags);
+
+   llvm::llvm_shutdown();
+   return 0;
+}
-- 
2.10.1



[PATCH v3 05/30] perf tools: Pass context to perf hook functions

2016-11-25 Thread Wang Nan
Pass a pointer to perf hook functions so they receive context
information created durnig setup.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/perf-hooks.c | 14 +-
 tools/perf/util/perf-hooks.c  | 10 +++---
 tools/perf/util/perf-hooks.h  |  6 --
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
index 9338cb2..665ecc1 100644
--- a/tools/perf/tests/perf-hooks.c
+++ b/tools/perf/tests/perf-hooks.c
@@ -15,13 +15,13 @@ static void sigsegv_handler(int sig __maybe_unused)
exit(-1);
 }
 
-static int hook_flags;
 
-static void the_hook(void)
+static void the_hook(void *_hook_flags)
 {
+   int *hook_flags = _hook_flags;
int *p = NULL;
 
-   hook_flags = 1234;
+   *hook_flags = 1234;
 
/* Generate a segfault, test perf_hooks__recover */
*p = 0;
@@ -29,13 +29,17 @@ static void the_hook(void)
 
 int test__perf_hooks(int subtest __maybe_unused)
 {
+   int hook_flags = 0;
+
signal(SIGSEGV, sigsegv_handler);
-   perf_hooks__set_hook("test", the_hook);
+   perf_hooks__set_hook("test", the_hook, _flags);
perf_hooks__invoke_test();
 
/* hook is triggered? */
-   if (hook_flags != 1234)
+   if (hook_flags != 1234) {
+   pr_debug("Setting failed: %d (%p)\n", hook_flags, _flags);
return TEST_FAIL;
+   }
 
/* the buggy hook is removed? */
if (perf_hooks__get_hook("test"))
diff --git a/tools/perf/util/perf-hooks.c b/tools/perf/util/perf-hooks.c
index 4ce88e3..cb36830 100644
--- a/tools/perf/util/perf-hooks.c
+++ b/tools/perf/util/perf-hooks.c
@@ -27,7 +27,7 @@ void perf_hooks__invoke(const struct perf_hook_desc *desc)
*(current_perf_hook->p_hook_func) = NULL;
} else {
current_perf_hook = desc;
-   (**desc->p_hook_func)();
+   (**desc->p_hook_func)(desc->hook_ctx);
}
current_perf_hook = NULL;
 }
@@ -41,7 +41,9 @@ void perf_hooks__recover(void)
 #define PERF_HOOK(name)\
 perf_hook_func_t __perf_hook_func_##name = NULL;   \
 struct perf_hook_desc __perf_hook_desc_##name =\
-   {.hook_name = #name, .p_hook_func = &__perf_hook_func_##name};
+   {.hook_name = #name,\
+.p_hook_func = &__perf_hook_func_##name,   \
+.hook_ctx = NULL};
 #include "perf-hooks-list.h"
 #undef PERF_HOOK
 
@@ -54,7 +56,8 @@ static struct perf_hook_desc *perf_hooks[] = {
 #undef PERF_HOOK
 
 int perf_hooks__set_hook(const char *hook_name,
-perf_hook_func_t hook_func)
+perf_hook_func_t hook_func,
+void *hook_ctx)
 {
unsigned int i;
 
@@ -65,6 +68,7 @@ int perf_hooks__set_hook(const char *hook_name,
if (*(perf_hooks[i]->p_hook_func))
pr_warning("Overwrite existing hook: %s\n", hook_name);
*(perf_hooks[i]->p_hook_func) = hook_func;
+   perf_hooks[i]->hook_ctx = hook_ctx;
return 0;
}
return -ENOENT;
diff --git a/tools/perf/util/perf-hooks.h b/tools/perf/util/perf-hooks.h
index 1d482b2..838d579 100644
--- a/tools/perf/util/perf-hooks.h
+++ b/tools/perf/util/perf-hooks.h
@@ -5,10 +5,11 @@
 extern "C" {
 #endif
 
-typedef void (*perf_hook_func_t)(void);
+typedef void (*perf_hook_func_t)(void *ctx);
 struct perf_hook_desc {
const char * const hook_name;
perf_hook_func_t * const p_hook_func;
+   void *hook_ctx;
 };
 
 extern void perf_hooks__invoke(const struct perf_hook_desc *);
@@ -26,7 +27,8 @@ static inline void perf_hooks__invoke_##name(void)\
 
 extern int
 perf_hooks__set_hook(const char *hook_name,
-perf_hook_func_t hook_func);
+perf_hook_func_t hook_func,
+void *hook_ctx);
 
 extern perf_hook_func_t
 perf_hooks__get_hook(const char *hook_name);
-- 
2.10.1



[PATCH v3 15/30] perf clang: Compile BPF script use builtin clang support

2016-11-25 Thread Wang Nan
After this patch, perf utilizes builtin clang support to build BPF
script, no longer depend on external clang.

Test:

  $ type clang
  -bash: type: clang: not found
  $ cat ~/.perfconfig
  $ echo '#define LINUX_VERSION_CODE 0x040700' > ./test.c
  $ cat ./tools/perf/tests/bpf-script-example.c >> ./test.c
  $ ./perf record -v --dry-run -e ./test.c 2>&1 | grep builtin
  bpf: builtin compiling successful

Can't pass cflags so unable to include kernel headers now. Will be fixed
by following commits.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-13-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/bpf-loader.c  | 15 +++
 tools/perf/util/c++/clang-c.h | 26 ++
 tools/perf/util/c++/clang.cpp | 29 +
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index cf16b941..a0ea334f 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -14,11 +14,11 @@
 #include "debug.h"
 #include "bpf-loader.h"
 #include "bpf-prologue.h"
-#include "llvm-utils.h"
 #include "probe-event.h"
 #include "probe-finder.h" // for MAX_PROBES
 #include "parse-events.h"
 #include "llvm-utils.h"
+#include "c++/clang-c.h"
 
 #define DEFINE_PRINT_FN(name, level) \
 static int libbpf_##name(const char *fmt, ...) \
@@ -86,9 +86,16 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
void *obj_buf;
size_t obj_buf_sz;
 
-   err = llvm__compile_bpf(filename, _buf, _buf_sz);
-   if (err)
-   return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
+   perf_clang__init();
+   err = perf_clang__compile_bpf(filename, _buf, _buf_sz);
+   perf_clang__cleanup();
+   if (err) {
+   pr_warning("bpf: builtin compiling failed: %d, try 
external compiler\n", err);
+   err = llvm__compile_bpf(filename, _buf, 
_buf_sz);
+   if (err)
+   return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
+   } else
+   pr_debug("bpf: builtin compiling successful\n");
obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
 
if (!IS_ERR(obj) && llvm_param.dump_obj)
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 22b3936..0eadd79 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -1,16 +1,42 @@
 #ifndef PERF_UTIL_CLANG_C_H
 #define PERF_UTIL_CLANG_C_H
 
+#include /* for size_t */
+#include   /* for __maybe_unused */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#ifdef HAVE_LIBCLANGLLVM_SUPPORT
 extern void perf_clang__init(void);
 extern void perf_clang__cleanup(void);
 
 extern int test__clang_to_IR(void);
 extern int test__clang_to_obj(void);
 
+extern int perf_clang__compile_bpf(const char *filename,
+  void **p_obj_buf,
+  size_t *p_obj_buf_sz);
+#else
+
+
+static inline void perf_clang__init(void) { }
+static inline void perf_clang__cleanup(void) { }
+
+static inline int test__clang_to_IR(void) { return -1; }
+static inline int test__clang_to_obj(void) { return -1;}
+
+static inline int
+perf_clang__compile_bpf(const char *filename __maybe_unused,
+   void **p_obj_buf __maybe_unused,
+   size_t *p_obj_buf_sz __maybe_unused)
+{
+   return -ENOTSUP;
+}
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 2a1a75d..1e97415 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -163,4 +163,33 @@ void perf_clang__cleanup(void)
perf::LLVMCtx.reset(nullptr);
llvm::llvm_shutdown();
 }
+
+int perf_clang__compile_bpf(const char *filename,
+   void **p_obj_buf,
+   size_t *p_obj_buf_sz)
+{
+   using namespace perf;
+
+   if (!p_obj_buf || !p_obj_buf_sz)
+   return -EINVAL;
+
+   llvm::opt::ArgStringList CFlags;
+   auto M = getModuleFromSource(std::move(CFlags), filename);
+   if (!M)
+   return  -EINVAL;
+   auto O = getBPFObjectFromModule(&*M);
+   if (!O)
+   return -EINVAL;
+
+   size_t size = O->size_in_bytes();
+   void *buffer;
+
+   buffer = malloc(size);
+   if (!buffer)
+   return -ENOMEM;
+   memcpy(buffer, O->data(), size);
+   *p_obj_buf = buffer;
+   *p_obj_buf_sz = size;
+   return 0;
+}
 }
-- 
2.10.1



[PATCH v3 00/30] perf clang: Builtin clang and perfhook support

2016-11-25 Thread Wang Nan
This is version 3 of perf builtin clang and perfhook patch series.
Compare to v2 there is only minor changes:
 1. BPF map helpers in perf hooks now called 'perf_map_...',
instead of 'jit_helper_map_...'.
(Alexei Starovoitov)
 2. Rename bpf_map_{pin,get} to bpf_obj_{pin,get}, make them consist
with kernel.
(Joe Stringer).

Example in v2 should be changed accordingly:

  $ cat ./count_syscalls.c
  typedef unsigned long u64;
  
  #define BPF_MAP_TYPE_HASH 1
  #define BPF_MAP_TYPE_ARRAY 2
  
  enum GVAL {
  G_perf_pid,
  NR_GVALS
  };
  
  struct bpf_map_def SEC("maps") GVALS = {
  .type = BPF_MAP_TYPE_ARRAY,
  .key_size = sizeof(int),
  .value_size = sizeof(u64),
  .max_entries = NR_GVALS,
  };
  
  struct bpf_map_def SEC("maps") syscall_counter = {
  .type = BPF_MAP_TYPE_HASH,
  .key_size = sizeof(u64),
  .value_size = sizeof(u64),
  .max_entries = 512,
  };
  
  SEC("raw_syscalls:sys_enter")
  int func(void *ctx)
  {
  int key = G_perf_pid;
  u64 id = *((u64 *)(ctx + 8));
  int self_pid = bpf_get_current_pid_tgid() & 0x;
  int *perf_pid = bpf_map_lookup_elem(, );
  u64 *counter;
  
  if (!perf_pid)
  return 0;
  if (*perf_pid == self_pid)
  return 0;
  counter = bpf_map_lookup_elem(_counter, );
  if (!counter) {
  u64 value = 1;
  bpf_map_update_elem(_counter, , , 0);
  return 0;
  }
  __sync_fetch_and_add(counter, 1);
  return 0;
  }
  
  SEC("perfhook:record_start")
  void record_start(void *ctx)
  {
  int perf_pid = getpid(), key = G_perf_pid;
  printf("Start count, perfpid=%d\n", perf_pid);
  perf_map_update_elem(ctx, , , _pid, 0);
  }
  
  SEC("perfhook:record_end")
  void record_end(void *ctx)
  {
  u64 key = -1, value;
  while (!perf_map_get_next_key(ctx, _counter, , )) {
  perf_map_lookup_elem(ctx, _counter, , );
  printf("syscall %ld\tcount: %ld\n", (long)key, (long)value);
  }
  }
  char _license[] SEC("license") = "GPL";
  int _version SEC("version") = LINUX_VERSION_CODE;
  $ sudo -s
  # ulimit -l unlimited
  # perf record -e ./count_syscalls.c echo "Haha"
  Start count, perfpid=25209
  Haha
  [ perf record: Woken up 1 times to write data ]
  syscall 293   count: 2
  syscall 8 count: 7
  syscall 11count: 763
  syscall 4 count: 43
  syscall 21count: 48
  syscall 86count: 1
  syscall 5 count: 791
  ...

Wang Nan (30):
  tools lib bpf: Add missing BPF functions
  tools lib bpf: Add private field for bpf_object
  tools lib bpf: Retrive bpf_map through offset of bpf_map_def
  perf tools: Introduce perf hooks
  perf tools: Pass context to perf hook functions
  perf llvm: Extract helpers in llvm-utils.c
  tools build: Add feature detection for LLVM
  tools build: Add feature detection for clang
  perf build: Add clang and llvm compile and linking support
  perf clang: Add builtin clang support ant test case
  perf clang: Use real file system for #include
  perf clang: Allow passing CFLAGS to builtin clang
  perf clang: Update test case to use real BPF script
  perf clang: Support compile IR to BPF object and add testcase
  perf clang: Compile BPF script use builtin clang support
  perf clang: Pass full path to builtin clang
  perf clang: Pass CFLAGS to builtin clang
  perf clang jit: Wrap llvm::Module using PerfModule
  perf clang jit: Insignt BPF and JIT functions in a Module
  perf clang jit: add PerfModule::doJIT to JIT perfhook functions
  perf clang jit: Export functions for jitted code
  perf clang jit: Actually JIT and hook in bpf loader
  perf clang jit: Collect the lowest address in maps section as map_base
  perf clang jit: Retrive fd of BPF map from its offset
  perf clang jit: Allow jitted perf hook access BPF maps
  perf clang: Link BPF functions declaration into perf
  perf clang: Declare BPF functions for BPF scripts automatically
  perf clang: Include helpers to BPF scripts
  perf clang builtin: Define hook helpers by default
  perf clang jit: Export getpid() to perf hook

 tools/build/feature/Makefile  |  18 +
 tools/build/feature/test-clang.cpp|  21 ++
 tools/build/feature/test-llvm.cpp |   8 +
 tools/lib/bpf/bpf.c   |  56 +++
 tools/lib/bpf/bpf.h   |   7 +
 tools/lib/bpf/libbpf.c|  35 ++
 tools/lib/bpf/libbpf.h|  13 +
 tools/perf/Makefile.config|  62 +++-
 tools/perf/Makefile.perf  |  23 +-
 tools/perf/builtin-record.c   |  11 +
 tools/perf/tests/Build|   4 +-
 tools/perf/tests/bpf-script-example.c |  30 +-
 tools/perf/tests/bpf-script-test-kbuild.c |   2 +
 tools/perf/tests/bpf-script-test-prologue.c   |   6 +-
 tools/perf/tests/bpf-script-test-relocation.c |  17 +-
 tools/perf/tests/builtin-test.c   |  13 +
 tools/perf/tests/clang.c   

[PATCH v3 22/30] perf clang jit: Actually JIT and hook in bpf loader

2016-11-25 Thread Wang Nan
Makes perf_clang__compile_bpf() actually uses clang jit to compile perf
hooks. Returns a map through perf_clang__compile_bpf(), and set hooks
after bpf_object is created.

After this path jitting takes actions for bpf loader. For example:
  $ cat ./test.c
  /**/
  #define SEC(name) __attribute__((section(name), used))
  SEC("dofork=_do_fork")
  int dofork(void *ctx)
  {
  return 0;
  }
  extern int printf(const char *fmt, ...);
  SEC("perfhook:record_start")
  void record_start(void)
  {
  printf("Welcom to perf record\n");
  }
  SEC("perfhook:record_end")
  void record_end(void)
  {
  printf("Goodbye, perf record\n");
  }
  char _license[] SEC("license") = "GPL";
  int _version SEC("version") = LINUX_VERSION_CODE;
  /**/
  $ perf record -e ./test.c sleep 1
  Welcom to perf record
  [ perf record: Woken up 1 times to write data ]
  Goodbye, perf record
  [ perf record: Captured and wrote 0.014 MB perf.data ]

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c  | 11 ++-
 tools/perf/util/c++/clang-c.h | 18 --
 tools/perf/util/c++/clang.cpp | 28 +++-
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a0ea334f..e50045f 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -85,9 +85,11 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
int err;
void *obj_buf;
size_t obj_buf_sz;
+   jitted_funcs_map_t jitted_funcs_map;
 
perf_clang__init();
-   err = perf_clang__compile_bpf(filename, _buf, _buf_sz);
+   err = perf_clang__compile_bpf(filename, _buf,
+ _buf_sz, _funcs_map);
perf_clang__cleanup();
if (err) {
pr_warning("bpf: builtin compiling failed: %d, try 
external compiler\n", err);
@@ -101,6 +103,13 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
if (!IS_ERR(obj) && llvm_param.dump_obj)
llvm__dump_obj(filename, obj_buf, obj_buf_sz);
 
+   /*
+* Call perf_clang__hook_jitted_func even IS_ERR(obj) to make 
sure
+* the C++ map pointer is deleted.
+*/
+   if (jitted_funcs_map)
+   perf_clang__hook_jitted_func(jitted_funcs_map, obj, 
IS_ERR(obj));
+
free(obj_buf);
} else
obj = bpf_object__open(filename);
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 9f75e41..021b1ad 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -8,6 +8,7 @@
 extern "C" {
 #endif
 
+typedef void *jitted_funcs_map_t;
 #ifdef HAVE_LIBCLANGLLVM_SUPPORT
 extern void perf_clang__init(void);
 extern void perf_clang__cleanup(void);
@@ -20,7 +21,11 @@ extern void test__clang_callback(int x);
 
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
-  size_t *p_obj_buf_sz);
+  size_t *p_obj_buf_sz,
+  jitted_funcs_map_t *p_funcs_map);
+
+extern int
+perf_clang__hook_jitted_func(jitted_funcs_map_t map, void *ctx, bool is_err);
 #else
 
 
@@ -34,7 +39,16 @@ static inline int test__clang_jit(void) { return -1;}
 static inline int
 perf_clang__compile_bpf(const char *filename __maybe_unused,
void **p_obj_buf __maybe_unused,
-   size_t *p_obj_buf_sz __maybe_unused)
+   size_t *p_obj_buf_sz __maybe_unused,
+   jitted_funcs_map_t *p_funcs_map __maybe_unused)
+{
+   return -ENOTSUP;
+}
+
+static inline int
+perf_clang__hook_jitted_func(jitted_funcs_map_t map __maybe_unused,
+void *ctx __maybe_unused,
+bool is_err __maybe_unused)
 {
return -ENOTSUP;
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 325fbe4..f2608f5 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -388,7 +388,8 @@ void perf_clang__cleanup(void)
 
 int perf_clang__compile_bpf(const char *_filename,
void **p_obj_buf,
-   size_t *p_obj_buf_sz)
+   size_t *p_obj_buf_sz,
+   jitted_funcs_map_t *p_funcs_map)
 {
using namespace perf;
 
@@ -415,6 +416,31 @@ 

[PATCH v3 15/30] perf clang: Compile BPF script use builtin clang support

2016-11-25 Thread Wang Nan
After this patch, perf utilizes builtin clang support to build BPF
script, no longer depend on external clang.

Test:

  $ type clang
  -bash: type: clang: not found
  $ cat ~/.perfconfig
  $ echo '#define LINUX_VERSION_CODE 0x040700' > ./test.c
  $ cat ./tools/perf/tests/bpf-script-example.c >> ./test.c
  $ ./perf record -v --dry-run -e ./test.c 2>&1 | grep builtin
  bpf: builtin compiling successful

Can't pass cflags so unable to include kernel headers now. Will be fixed
by following commits.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-13-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/bpf-loader.c  | 15 +++
 tools/perf/util/c++/clang-c.h | 26 ++
 tools/perf/util/c++/clang.cpp | 29 +
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index cf16b941..a0ea334f 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -14,11 +14,11 @@
 #include "debug.h"
 #include "bpf-loader.h"
 #include "bpf-prologue.h"
-#include "llvm-utils.h"
 #include "probe-event.h"
 #include "probe-finder.h" // for MAX_PROBES
 #include "parse-events.h"
 #include "llvm-utils.h"
+#include "c++/clang-c.h"
 
 #define DEFINE_PRINT_FN(name, level) \
 static int libbpf_##name(const char *fmt, ...) \
@@ -86,9 +86,16 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
void *obj_buf;
size_t obj_buf_sz;
 
-   err = llvm__compile_bpf(filename, _buf, _buf_sz);
-   if (err)
-   return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
+   perf_clang__init();
+   err = perf_clang__compile_bpf(filename, _buf, _buf_sz);
+   perf_clang__cleanup();
+   if (err) {
+   pr_warning("bpf: builtin compiling failed: %d, try 
external compiler\n", err);
+   err = llvm__compile_bpf(filename, _buf, 
_buf_sz);
+   if (err)
+   return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
+   } else
+   pr_debug("bpf: builtin compiling successful\n");
obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
 
if (!IS_ERR(obj) && llvm_param.dump_obj)
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 22b3936..0eadd79 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -1,16 +1,42 @@
 #ifndef PERF_UTIL_CLANG_C_H
 #define PERF_UTIL_CLANG_C_H
 
+#include /* for size_t */
+#include   /* for __maybe_unused */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#ifdef HAVE_LIBCLANGLLVM_SUPPORT
 extern void perf_clang__init(void);
 extern void perf_clang__cleanup(void);
 
 extern int test__clang_to_IR(void);
 extern int test__clang_to_obj(void);
 
+extern int perf_clang__compile_bpf(const char *filename,
+  void **p_obj_buf,
+  size_t *p_obj_buf_sz);
+#else
+
+
+static inline void perf_clang__init(void) { }
+static inline void perf_clang__cleanup(void) { }
+
+static inline int test__clang_to_IR(void) { return -1; }
+static inline int test__clang_to_obj(void) { return -1;}
+
+static inline int
+perf_clang__compile_bpf(const char *filename __maybe_unused,
+   void **p_obj_buf __maybe_unused,
+   size_t *p_obj_buf_sz __maybe_unused)
+{
+   return -ENOTSUP;
+}
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 2a1a75d..1e97415 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -163,4 +163,33 @@ void perf_clang__cleanup(void)
perf::LLVMCtx.reset(nullptr);
llvm::llvm_shutdown();
 }
+
+int perf_clang__compile_bpf(const char *filename,
+   void **p_obj_buf,
+   size_t *p_obj_buf_sz)
+{
+   using namespace perf;
+
+   if (!p_obj_buf || !p_obj_buf_sz)
+   return -EINVAL;
+
+   llvm::opt::ArgStringList CFlags;
+   auto M = getModuleFromSource(std::move(CFlags), filename);
+   if (!M)
+   return  -EINVAL;
+   auto O = getBPFObjectFromModule(&*M);
+   if (!O)
+   return -EINVAL;
+
+   size_t size = O->size_in_bytes();
+   void *buffer;
+
+   buffer = malloc(size);
+   if (!buffer)
+   return -ENOMEM;
+   memcpy(buffer, O->data(), size);
+   *p_obj_buf = buffer;
+   *p_obj_buf_sz = size;
+   return 0;
+}
 }
-- 
2.10.1



[PATCH v3 00/30] perf clang: Builtin clang and perfhook support

2016-11-25 Thread Wang Nan
This is version 3 of perf builtin clang and perfhook patch series.
Compare to v2 there is only minor changes:
 1. BPF map helpers in perf hooks now called 'perf_map_...',
instead of 'jit_helper_map_...'.
(Alexei Starovoitov)
 2. Rename bpf_map_{pin,get} to bpf_obj_{pin,get}, make them consist
with kernel.
(Joe Stringer).

Example in v2 should be changed accordingly:

  $ cat ./count_syscalls.c
  typedef unsigned long u64;
  
  #define BPF_MAP_TYPE_HASH 1
  #define BPF_MAP_TYPE_ARRAY 2
  
  enum GVAL {
  G_perf_pid,
  NR_GVALS
  };
  
  struct bpf_map_def SEC("maps") GVALS = {
  .type = BPF_MAP_TYPE_ARRAY,
  .key_size = sizeof(int),
  .value_size = sizeof(u64),
  .max_entries = NR_GVALS,
  };
  
  struct bpf_map_def SEC("maps") syscall_counter = {
  .type = BPF_MAP_TYPE_HASH,
  .key_size = sizeof(u64),
  .value_size = sizeof(u64),
  .max_entries = 512,
  };
  
  SEC("raw_syscalls:sys_enter")
  int func(void *ctx)
  {
  int key = G_perf_pid;
  u64 id = *((u64 *)(ctx + 8));
  int self_pid = bpf_get_current_pid_tgid() & 0x;
  int *perf_pid = bpf_map_lookup_elem(, );
  u64 *counter;
  
  if (!perf_pid)
  return 0;
  if (*perf_pid == self_pid)
  return 0;
  counter = bpf_map_lookup_elem(_counter, );
  if (!counter) {
  u64 value = 1;
  bpf_map_update_elem(_counter, , , 0);
  return 0;
  }
  __sync_fetch_and_add(counter, 1);
  return 0;
  }
  
  SEC("perfhook:record_start")
  void record_start(void *ctx)
  {
  int perf_pid = getpid(), key = G_perf_pid;
  printf("Start count, perfpid=%d\n", perf_pid);
  perf_map_update_elem(ctx, , , _pid, 0);
  }
  
  SEC("perfhook:record_end")
  void record_end(void *ctx)
  {
  u64 key = -1, value;
  while (!perf_map_get_next_key(ctx, _counter, , )) {
  perf_map_lookup_elem(ctx, _counter, , );
  printf("syscall %ld\tcount: %ld\n", (long)key, (long)value);
  }
  }
  char _license[] SEC("license") = "GPL";
  int _version SEC("version") = LINUX_VERSION_CODE;
  $ sudo -s
  # ulimit -l unlimited
  # perf record -e ./count_syscalls.c echo "Haha"
  Start count, perfpid=25209
  Haha
  [ perf record: Woken up 1 times to write data ]
  syscall 293   count: 2
  syscall 8 count: 7
  syscall 11count: 763
  syscall 4 count: 43
  syscall 21count: 48
  syscall 86count: 1
  syscall 5 count: 791
  ...

Wang Nan (30):
  tools lib bpf: Add missing BPF functions
  tools lib bpf: Add private field for bpf_object
  tools lib bpf: Retrive bpf_map through offset of bpf_map_def
  perf tools: Introduce perf hooks
  perf tools: Pass context to perf hook functions
  perf llvm: Extract helpers in llvm-utils.c
  tools build: Add feature detection for LLVM
  tools build: Add feature detection for clang
  perf build: Add clang and llvm compile and linking support
  perf clang: Add builtin clang support ant test case
  perf clang: Use real file system for #include
  perf clang: Allow passing CFLAGS to builtin clang
  perf clang: Update test case to use real BPF script
  perf clang: Support compile IR to BPF object and add testcase
  perf clang: Compile BPF script use builtin clang support
  perf clang: Pass full path to builtin clang
  perf clang: Pass CFLAGS to builtin clang
  perf clang jit: Wrap llvm::Module using PerfModule
  perf clang jit: Insignt BPF and JIT functions in a Module
  perf clang jit: add PerfModule::doJIT to JIT perfhook functions
  perf clang jit: Export functions for jitted code
  perf clang jit: Actually JIT and hook in bpf loader
  perf clang jit: Collect the lowest address in maps section as map_base
  perf clang jit: Retrive fd of BPF map from its offset
  perf clang jit: Allow jitted perf hook access BPF maps
  perf clang: Link BPF functions declaration into perf
  perf clang: Declare BPF functions for BPF scripts automatically
  perf clang: Include helpers to BPF scripts
  perf clang builtin: Define hook helpers by default
  perf clang jit: Export getpid() to perf hook

 tools/build/feature/Makefile  |  18 +
 tools/build/feature/test-clang.cpp|  21 ++
 tools/build/feature/test-llvm.cpp |   8 +
 tools/lib/bpf/bpf.c   |  56 +++
 tools/lib/bpf/bpf.h   |   7 +
 tools/lib/bpf/libbpf.c|  35 ++
 tools/lib/bpf/libbpf.h|  13 +
 tools/perf/Makefile.config|  62 +++-
 tools/perf/Makefile.perf  |  23 +-
 tools/perf/builtin-record.c   |  11 +
 tools/perf/tests/Build|   4 +-
 tools/perf/tests/bpf-script-example.c |  30 +-
 tools/perf/tests/bpf-script-test-kbuild.c |   2 +
 tools/perf/tests/bpf-script-test-prologue.c   |   6 +-
 tools/perf/tests/bpf-script-test-relocation.c |  17 +-
 tools/perf/tests/builtin-test.c   |  13 +
 tools/perf/tests/clang.c   

[PATCH v3 22/30] perf clang jit: Actually JIT and hook in bpf loader

2016-11-25 Thread Wang Nan
Makes perf_clang__compile_bpf() actually uses clang jit to compile perf
hooks. Returns a map through perf_clang__compile_bpf(), and set hooks
after bpf_object is created.

After this path jitting takes actions for bpf loader. For example:
  $ cat ./test.c
  /**/
  #define SEC(name) __attribute__((section(name), used))
  SEC("dofork=_do_fork")
  int dofork(void *ctx)
  {
  return 0;
  }
  extern int printf(const char *fmt, ...);
  SEC("perfhook:record_start")
  void record_start(void)
  {
  printf("Welcom to perf record\n");
  }
  SEC("perfhook:record_end")
  void record_end(void)
  {
  printf("Goodbye, perf record\n");
  }
  char _license[] SEC("license") = "GPL";
  int _version SEC("version") = LINUX_VERSION_CODE;
  /**/
  $ perf record -e ./test.c sleep 1
  Welcom to perf record
  [ perf record: Woken up 1 times to write data ]
  Goodbye, perf record
  [ perf record: Captured and wrote 0.014 MB perf.data ]

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c  | 11 ++-
 tools/perf/util/c++/clang-c.h | 18 --
 tools/perf/util/c++/clang.cpp | 28 +++-
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a0ea334f..e50045f 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -85,9 +85,11 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
int err;
void *obj_buf;
size_t obj_buf_sz;
+   jitted_funcs_map_t jitted_funcs_map;
 
perf_clang__init();
-   err = perf_clang__compile_bpf(filename, _buf, _buf_sz);
+   err = perf_clang__compile_bpf(filename, _buf,
+ _buf_sz, _funcs_map);
perf_clang__cleanup();
if (err) {
pr_warning("bpf: builtin compiling failed: %d, try 
external compiler\n", err);
@@ -101,6 +103,13 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
if (!IS_ERR(obj) && llvm_param.dump_obj)
llvm__dump_obj(filename, obj_buf, obj_buf_sz);
 
+   /*
+* Call perf_clang__hook_jitted_func even IS_ERR(obj) to make 
sure
+* the C++ map pointer is deleted.
+*/
+   if (jitted_funcs_map)
+   perf_clang__hook_jitted_func(jitted_funcs_map, obj, 
IS_ERR(obj));
+
free(obj_buf);
} else
obj = bpf_object__open(filename);
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 9f75e41..021b1ad 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -8,6 +8,7 @@
 extern "C" {
 #endif
 
+typedef void *jitted_funcs_map_t;
 #ifdef HAVE_LIBCLANGLLVM_SUPPORT
 extern void perf_clang__init(void);
 extern void perf_clang__cleanup(void);
@@ -20,7 +21,11 @@ extern void test__clang_callback(int x);
 
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
-  size_t *p_obj_buf_sz);
+  size_t *p_obj_buf_sz,
+  jitted_funcs_map_t *p_funcs_map);
+
+extern int
+perf_clang__hook_jitted_func(jitted_funcs_map_t map, void *ctx, bool is_err);
 #else
 
 
@@ -34,7 +39,16 @@ static inline int test__clang_jit(void) { return -1;}
 static inline int
 perf_clang__compile_bpf(const char *filename __maybe_unused,
void **p_obj_buf __maybe_unused,
-   size_t *p_obj_buf_sz __maybe_unused)
+   size_t *p_obj_buf_sz __maybe_unused,
+   jitted_funcs_map_t *p_funcs_map __maybe_unused)
+{
+   return -ENOTSUP;
+}
+
+static inline int
+perf_clang__hook_jitted_func(jitted_funcs_map_t map __maybe_unused,
+void *ctx __maybe_unused,
+bool is_err __maybe_unused)
 {
return -ENOTSUP;
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 325fbe4..f2608f5 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -388,7 +388,8 @@ void perf_clang__cleanup(void)
 
 int perf_clang__compile_bpf(const char *_filename,
void **p_obj_buf,
-   size_t *p_obj_buf_sz)
+   size_t *p_obj_buf_sz,
+   jitted_funcs_map_t *p_funcs_map)
 {
using namespace perf;
 
@@ -415,6 +416,31 @@ int perf_clang__compile_bpf(const char *_filename,
memcpy(buffer, O->data(), size);

[PATCH v3 08/30] tools build: Add feature detection for clang

2016-11-25 Thread Wang Nan
Check if basic clang compiling environment is ready.

Doesn't like 'llvm-config --libs' which can returns llvm libraries in
right order and duplicates some libraries if necessary, there's no
correspondence for clang libraries (-lclangxxx). to avoid extra
complexity and to avoid new clang breaking libraries ordering, use
--start-group and --end-group.

In this test case, manually identify required clang libs and hope it to
be stable. Putting all clang libraries here is possible (use make's
wildcard), but then feature checking becomes very slow.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-5-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/build/feature/Makefile   | 10 ++
 tools/build/feature/test-clang.cpp | 21 +
 2 files changed, 31 insertions(+)
 create mode 100644 tools/build/feature/test-clang.cpp

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index c09de59..871d553 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -237,6 +237,16 @@ $(OUTPUT)test-llvm.bin:
$(shell $(LLVM_CONFIG) --libs Core BPF) \
$(shell $(LLVM_CONFIG) --system-libs)
 
+$(OUTPUT)test-clang.bin:
+   $(BUILDXX) -std=gnu++11 \
+   -I$(shell $(LLVM_CONFIG) --includedir)  \
+   -L$(shell $(LLVM_CONFIG) --libdir)  \
+   -Wl,--start-group -lclangBasic -lclangDriver\
+ -lclangFrontend -lclangEdit -lclangLex\
+ -lclangAST -Wl,--end-group\
+   $(shell $(LLVM_CONFIG) --libs Core option)  \
+   $(shell $(LLVM_CONFIG) --system-libs)
+
 -include $(OUTPUT)*.d
 
 ###
diff --git a/tools/build/feature/test-clang.cpp 
b/tools/build/feature/test-clang.cpp
new file mode 100644
index 000..e23c1b1
--- /dev/null
+++ b/tools/build/feature/test-clang.cpp
@@ -0,0 +1,21 @@
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::driver;
+
+int main()
+{
+   IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
+   IntrusiveRefCntPtr DiagOpts = new 
DiagnosticOptions();
+
+   DiagnosticsEngine Diags(DiagID, &*DiagOpts);
+   Driver TheDriver("test", "bpf-pc-linux", Diags);
+
+   llvm::llvm_shutdown();
+   return 0;
+}
-- 
2.10.1



[PATCH v3 05/30] perf tools: Pass context to perf hook functions

2016-11-25 Thread Wang Nan
Pass a pointer to perf hook functions so they receive context
information created durnig setup.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/perf-hooks.c | 14 +-
 tools/perf/util/perf-hooks.c  | 10 +++---
 tools/perf/util/perf-hooks.h  |  6 --
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
index 9338cb2..665ecc1 100644
--- a/tools/perf/tests/perf-hooks.c
+++ b/tools/perf/tests/perf-hooks.c
@@ -15,13 +15,13 @@ static void sigsegv_handler(int sig __maybe_unused)
exit(-1);
 }
 
-static int hook_flags;
 
-static void the_hook(void)
+static void the_hook(void *_hook_flags)
 {
+   int *hook_flags = _hook_flags;
int *p = NULL;
 
-   hook_flags = 1234;
+   *hook_flags = 1234;
 
/* Generate a segfault, test perf_hooks__recover */
*p = 0;
@@ -29,13 +29,17 @@ static void the_hook(void)
 
 int test__perf_hooks(int subtest __maybe_unused)
 {
+   int hook_flags = 0;
+
signal(SIGSEGV, sigsegv_handler);
-   perf_hooks__set_hook("test", the_hook);
+   perf_hooks__set_hook("test", the_hook, _flags);
perf_hooks__invoke_test();
 
/* hook is triggered? */
-   if (hook_flags != 1234)
+   if (hook_flags != 1234) {
+   pr_debug("Setting failed: %d (%p)\n", hook_flags, _flags);
return TEST_FAIL;
+   }
 
/* the buggy hook is removed? */
if (perf_hooks__get_hook("test"))
diff --git a/tools/perf/util/perf-hooks.c b/tools/perf/util/perf-hooks.c
index 4ce88e3..cb36830 100644
--- a/tools/perf/util/perf-hooks.c
+++ b/tools/perf/util/perf-hooks.c
@@ -27,7 +27,7 @@ void perf_hooks__invoke(const struct perf_hook_desc *desc)
*(current_perf_hook->p_hook_func) = NULL;
} else {
current_perf_hook = desc;
-   (**desc->p_hook_func)();
+   (**desc->p_hook_func)(desc->hook_ctx);
}
current_perf_hook = NULL;
 }
@@ -41,7 +41,9 @@ void perf_hooks__recover(void)
 #define PERF_HOOK(name)\
 perf_hook_func_t __perf_hook_func_##name = NULL;   \
 struct perf_hook_desc __perf_hook_desc_##name =\
-   {.hook_name = #name, .p_hook_func = &__perf_hook_func_##name};
+   {.hook_name = #name,\
+.p_hook_func = &__perf_hook_func_##name,   \
+.hook_ctx = NULL};
 #include "perf-hooks-list.h"
 #undef PERF_HOOK
 
@@ -54,7 +56,8 @@ static struct perf_hook_desc *perf_hooks[] = {
 #undef PERF_HOOK
 
 int perf_hooks__set_hook(const char *hook_name,
-perf_hook_func_t hook_func)
+perf_hook_func_t hook_func,
+void *hook_ctx)
 {
unsigned int i;
 
@@ -65,6 +68,7 @@ int perf_hooks__set_hook(const char *hook_name,
if (*(perf_hooks[i]->p_hook_func))
pr_warning("Overwrite existing hook: %s\n", hook_name);
*(perf_hooks[i]->p_hook_func) = hook_func;
+   perf_hooks[i]->hook_ctx = hook_ctx;
return 0;
}
return -ENOENT;
diff --git a/tools/perf/util/perf-hooks.h b/tools/perf/util/perf-hooks.h
index 1d482b2..838d579 100644
--- a/tools/perf/util/perf-hooks.h
+++ b/tools/perf/util/perf-hooks.h
@@ -5,10 +5,11 @@
 extern "C" {
 #endif
 
-typedef void (*perf_hook_func_t)(void);
+typedef void (*perf_hook_func_t)(void *ctx);
 struct perf_hook_desc {
const char * const hook_name;
perf_hook_func_t * const p_hook_func;
+   void *hook_ctx;
 };
 
 extern void perf_hooks__invoke(const struct perf_hook_desc *);
@@ -26,7 +27,8 @@ static inline void perf_hooks__invoke_##name(void)\
 
 extern int
 perf_hooks__set_hook(const char *hook_name,
-perf_hook_func_t hook_func);
+perf_hook_func_t hook_func,
+void *hook_ctx);
 
 extern perf_hook_func_t
 perf_hooks__get_hook(const char *hook_name);
-- 
2.10.1



[PATCH v3 10/30] perf clang: Add builtin clang support ant test case

2016-11-25 Thread Wang Nan
Add basic clang support in clang.cpp and test__clang() testcase. The
first testcase checks if builtin clang is able to generate LLVM IR.

tests/clang.c is a proxy. Real testcase resides in
utils/c++/clang-test.cpp in c++ and exports C interface to perf test
subsystem.

Test result:

   $ perf test -v clang
   51: Test builtin clang support   :
   51.1: Test builtin clang compile C source to IR  :
   --- start ---
   test child forked, pid 13215
   test child finished with 0
    end 
   Test builtin clang support subtest 0: Ok

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/Build |  1 +
 tools/perf/tests/builtin-test.c|  9 
 tools/perf/tests/clang.c   | 42 +
 tools/perf/tests/tests.h   |  3 ++
 tools/perf/util/Build  |  2 +
 tools/perf/util/c++/Build  |  2 +
 tools/perf/util/c++/clang-c.h  | 16 +++
 tools/perf/util/c++/clang-test.cpp | 31 
 tools/perf/util/c++/clang.cpp  | 96 ++
 tools/perf/util/c++/clang.h| 16 +++
 10 files changed, 218 insertions(+)
 create mode 100644 tools/perf/tests/clang.c
 create mode 100644 tools/perf/util/c++/Build
 create mode 100644 tools/perf/util/c++/clang-c.h
 create mode 100644 tools/perf/util/c++/clang-test.cpp
 create mode 100644 tools/perf/util/c++/clang.cpp
 create mode 100644 tools/perf/util/c++/clang.h

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index af3ec94..6676c2d 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -43,6 +43,7 @@ perf-y += sdt.o
 perf-y += is_printable_array.o
 perf-y += bitmap.o
 perf-y += perf-hooks.o
+perf-y += clang.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index dab83f7..33aaa52 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -234,6 +234,15 @@ static struct test generic_tests[] = {
.func = test__perf_hooks,
},
{
+   .desc = "Test builtin clang support",
+   .func = test__clang,
+   .subtest = {
+   .skip_if_fail   = true,
+   .get_nr = test__clang_subtest_get_nr,
+   .get_desc   = test__clang_subtest_get_desc,
+   }
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
new file mode 100644
index 000..57ee160
--- /dev/null
+++ b/tools/perf/tests/clang.c
@@ -0,0 +1,42 @@
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "c++/clang-c.h"
+
+static struct {
+   int (*func)(void);
+   const char *desc;
+} clang_testcase_table[] = {
+#ifdef HAVE_LIBCLANGLLVM_SUPPORT
+   {
+   .func = test__clang_to_IR,
+   .desc = "Test builtin clang compile C source to IR",
+   },
+#endif
+};
+
+int test__clang_subtest_get_nr(void)
+{
+   return (int)ARRAY_SIZE(clang_testcase_table);
+}
+
+const char *test__clang_subtest_get_desc(int i)
+{
+   if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
+   return NULL;
+   return clang_testcase_table[i].desc;
+}
+
+#ifndef HAVE_LIBCLANGLLVM_SUPPORT
+int test__clang(int i __maybe_unused)
+{
+   return TEST_SKIP;
+}
+#else
+int test__clang(int i __maybe_unused)
+{
+   if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
+   return TEST_FAIL;
+   return clang_testcase_table[i].func();
+}
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 3a1f98f..0d7b251 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -92,6 +92,9 @@ int test__sdt_event(int subtest);
 int test__is_printable_array(int subtest);
 int test__bitmap_print(int subtest);
 int test__perf_hooks(int subtest);
+int test__clang(int subtest);
+const char *test__clang_subtest_get_desc(int subtest);
+int test__clang_subtest_get_nr(void);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index b2a47aa..743a889 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -125,6 +125,8 @@ endif
 
 libperf-y += perf-hooks.o
 
+libperf-$(CONFIG_CXX) += c++/
+
 CFLAGS_config.o   += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
 # avoid compiler warnings in 32-bit mode
 CFLAGS_genelf_debug.o  += -Wno-packed
diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
new file mode 100644
index 000..988fef1
--- /dev/null
+++ b/tools/perf/util/c++/Build
@@ -0,0 

[PATCH v3 10/30] perf clang: Add builtin clang support ant test case

2016-11-25 Thread Wang Nan
Add basic clang support in clang.cpp and test__clang() testcase. The
first testcase checks if builtin clang is able to generate LLVM IR.

tests/clang.c is a proxy. Real testcase resides in
utils/c++/clang-test.cpp in c++ and exports C interface to perf test
subsystem.

Test result:

   $ perf test -v clang
   51: Test builtin clang support   :
   51.1: Test builtin clang compile C source to IR  :
   --- start ---
   test child forked, pid 13215
   test child finished with 0
    end 
   Test builtin clang support subtest 0: Ok

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/Build |  1 +
 tools/perf/tests/builtin-test.c|  9 
 tools/perf/tests/clang.c   | 42 +
 tools/perf/tests/tests.h   |  3 ++
 tools/perf/util/Build  |  2 +
 tools/perf/util/c++/Build  |  2 +
 tools/perf/util/c++/clang-c.h  | 16 +++
 tools/perf/util/c++/clang-test.cpp | 31 
 tools/perf/util/c++/clang.cpp  | 96 ++
 tools/perf/util/c++/clang.h| 16 +++
 10 files changed, 218 insertions(+)
 create mode 100644 tools/perf/tests/clang.c
 create mode 100644 tools/perf/util/c++/Build
 create mode 100644 tools/perf/util/c++/clang-c.h
 create mode 100644 tools/perf/util/c++/clang-test.cpp
 create mode 100644 tools/perf/util/c++/clang.cpp
 create mode 100644 tools/perf/util/c++/clang.h

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index af3ec94..6676c2d 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -43,6 +43,7 @@ perf-y += sdt.o
 perf-y += is_printable_array.o
 perf-y += bitmap.o
 perf-y += perf-hooks.o
+perf-y += clang.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index dab83f7..33aaa52 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -234,6 +234,15 @@ static struct test generic_tests[] = {
.func = test__perf_hooks,
},
{
+   .desc = "Test builtin clang support",
+   .func = test__clang,
+   .subtest = {
+   .skip_if_fail   = true,
+   .get_nr = test__clang_subtest_get_nr,
+   .get_desc   = test__clang_subtest_get_desc,
+   }
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
new file mode 100644
index 000..57ee160
--- /dev/null
+++ b/tools/perf/tests/clang.c
@@ -0,0 +1,42 @@
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "c++/clang-c.h"
+
+static struct {
+   int (*func)(void);
+   const char *desc;
+} clang_testcase_table[] = {
+#ifdef HAVE_LIBCLANGLLVM_SUPPORT
+   {
+   .func = test__clang_to_IR,
+   .desc = "Test builtin clang compile C source to IR",
+   },
+#endif
+};
+
+int test__clang_subtest_get_nr(void)
+{
+   return (int)ARRAY_SIZE(clang_testcase_table);
+}
+
+const char *test__clang_subtest_get_desc(int i)
+{
+   if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
+   return NULL;
+   return clang_testcase_table[i].desc;
+}
+
+#ifndef HAVE_LIBCLANGLLVM_SUPPORT
+int test__clang(int i __maybe_unused)
+{
+   return TEST_SKIP;
+}
+#else
+int test__clang(int i __maybe_unused)
+{
+   if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
+   return TEST_FAIL;
+   return clang_testcase_table[i].func();
+}
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 3a1f98f..0d7b251 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -92,6 +92,9 @@ int test__sdt_event(int subtest);
 int test__is_printable_array(int subtest);
 int test__bitmap_print(int subtest);
 int test__perf_hooks(int subtest);
+int test__clang(int subtest);
+const char *test__clang_subtest_get_desc(int subtest);
+int test__clang_subtest_get_nr(void);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index b2a47aa..743a889 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -125,6 +125,8 @@ endif
 
 libperf-y += perf-hooks.o
 
+libperf-$(CONFIG_CXX) += c++/
+
 CFLAGS_config.o   += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
 # avoid compiler warnings in 32-bit mode
 CFLAGS_genelf_debug.o  += -Wno-packed
diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
new file mode 100644
index 000..988fef1
--- /dev/null
+++ b/tools/perf/util/c++/Build
@@ -0,0 +1,2 @@
+libperf-$(CONFIG_CLANGLLVM) += clang.o
+libperf-$(CONFIG_CLANGLLVM) += clang-test.o
diff --git 

[PATCH v3 25/30] perf clang jit: Allow jitted perf hook access BPF maps

2016-11-25 Thread Wang Nan
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(, );
  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 = 1;
  printf("Welcom to perf record\n");
  perf_map_update_elem(ctx, , , , 0);
  }

  SEC("perfhook:record_end")
  void record_end(void *ctx)
  {
  int key = 0;
  int value;
  perf_map_lookup_elem(ctx, , , );
  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=10644
  [ perf record: Captured and wrote 0.014 MB perf.data ]

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@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 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..48bd3ee 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,18 @@ PerfModule::toBPFObject(void)
return std::move(Buffer);
 }
 
+#define __stringify_1(x)   #x
+#define __stringify(x) __stringify_1(x)
 static std::map exported_funcs =
 {
-#define EXPORT(f) {#f, (const void *)}
+#define EXPORT(f) {__stringify(f), (const void *)}
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 000..1a37a20
--- /dev/null
+++ b/tools/perf/util/jit-helpers.c
@@ -0,0 +1,57 @@
+/*
+ * jit-helper.c
+ *
+ * Copyright (C) 2016 Wang Nan 
+ * Copyright (C) 2016 Huawei Inc.
+ *
+ * Provide helpers which can be invoked by jit scripts attached to
+ * perf hooks.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "asm/bug.h"
+
+static int get_bpf_map_fd(struct bpf_object *obj, void *map)
+{
+   int fd;
+   char 

[PATCH v3 25/30] perf clang jit: Allow jitted perf hook access BPF maps

2016-11-25 Thread Wang Nan
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(, );
  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 = 1;
  printf("Welcom to perf record\n");
  perf_map_update_elem(ctx, , , , 0);
  }

  SEC("perfhook:record_end")
  void record_end(void *ctx)
  {
  int key = 0;
  int value;
  perf_map_lookup_elem(ctx, , , );
  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=10644
  [ perf record: Captured and wrote 0.014 MB perf.data ]

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@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 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..48bd3ee 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,18 @@ PerfModule::toBPFObject(void)
return std::move(Buffer);
 }
 
+#define __stringify_1(x)   #x
+#define __stringify(x) __stringify_1(x)
 static std::map exported_funcs =
 {
-#define EXPORT(f) {#f, (const void *)}
+#define EXPORT(f) {__stringify(f), (const void *)}
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 000..1a37a20
--- /dev/null
+++ b/tools/perf/util/jit-helpers.c
@@ -0,0 +1,57 @@
+/*
+ * jit-helper.c
+ *
+ * Copyright (C) 2016 Wang Nan 
+ * Copyright (C) 2016 Huawei Inc.
+ *
+ * Provide helpers which can be invoked by jit scripts attached to
+ * perf hooks.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#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, 

[PATCH v3 29/30] perf clang builtin: Define hook helpers by default

2016-11-25 Thread Wang Nan
Append declarations of helpers to default include file. All functions
appear in exported_funcs array should be declared here except
test__clang_callback, because it is used for perf test only.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/bpf-helper-str.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/tools/perf/util/c++/bpf-helper-str.c 
b/tools/perf/util/c++/bpf-helper-str.c
index 17f915c..f4d6d57 100644
--- a/tools/perf/util/c++/bpf-helper-str.c
+++ b/tools/perf/util/c++/bpf-helper-str.c
@@ -10,6 +10,13 @@ const char clang_builtin_bpf_helper_str[] =
 "  unsigned int max_entries;\n"
 "};\n"
 "#define SEC(NAME) __attribute__((section(NAME), used))\n"
+"extern int printf(const char *, ...);\n"
+"extern int puts(const char *);\n"
+"extern int perf_map_update_elem(void *, void *, void *, void *, unsigned 
long);\n"
+"extern int perf_map_lookup_elem(void *, void *, void *, void *);\n"
+"extern int perf_map_get_next_key(void *, void *, void *, void *);\n"
+"extern int perf_map_pin(void *, void *, const char *);\n"
+"extern int perf_map_get(const char *);\n"
 "#endif\n"
 "#endif"
 ;
-- 
2.10.1



[PATCH v3 18/30] perf clang jit: Wrap llvm::Module using PerfModule

2016-11-25 Thread Wang Nan
Use PerfModule wrap llvm::Module and return perf::PerfModule in APIs to
replace llvm::Module. Following commits are going to add new functions
to PerfModule.

getBPFObjectFromModule is merged to a method of perf::PerfModule.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang-test.cpp | 10 +-
 tools/perf/util/c++/clang.cpp  | 20 +---
 tools/perf/util/c++/clang.h| 22 --
 3 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 9b11e8c..fb05e56 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -13,18 +13,18 @@ public:
~perf_clang_scope() {perf_clang__cleanup();}
 };
 
-static std::unique_ptr
+static std::unique_ptr
 __test__clang_to_IR(void)
 {
unsigned int kernel_version;
 
if (fetch_kernel_version(_version, NULL, 0))
-   return std::unique_ptr(nullptr);
+   return std::unique_ptr(nullptr);
 
std::string cflag_kver("-DLINUX_VERSION_CODE=" +
std::to_string(kernel_version));
 
-   std::unique_ptr M =
+   std::unique_ptr M =
perf::getModuleFromSource({cflag_kver.c_str()},
  "perf-test.c",
  test_llvm__bpf_base_prog);
@@ -39,7 +39,7 @@ int test__clang_to_IR(void)
auto M = __test__clang_to_IR();
if (!M)
return -1;
-   for (llvm::Function& F : *M)
+   for (llvm::Function& F : *(M->getModule()))
if (F.getName() == "bpf_func__SyS_epoll_wait")
return 0;
return -1;
@@ -53,7 +53,7 @@ int test__clang_to_obj(void)
if (!M)
return -1;
 
-   auto Buffer = perf::getBPFObjectFromModule(&*M);
+   auto Buffer = M->toBPFObject();
if (!Buffer)
return -1;
return 0;
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 3a3b9791..d31b0a5 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -64,7 +64,7 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, 
StringRef& Path,
return CI;
 }
 
-static std::unique_ptr
+static std::unique_ptr
 getModuleFromSource(llvm::opt::ArgStringList CFlags,
StringRef Path, IntrusiveRefCntPtr VFS)
 {
@@ -80,12 +80,12 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags,
 
std::unique_ptr Act(new EmitLLVMOnlyAction(&*LLVMCtx));
if (!Clang.ExecuteAction(*Act))
-   return std::unique_ptr(nullptr);
+   return std::unique_ptr(nullptr);
 
-   return Act->takeModule();
+   return std::unique_ptr(new 
PerfModule(std::move(Act->takeModule(;
 }
 
-std::unique_ptr
+std::unique_ptr
 getModuleFromSource(llvm::opt::ArgStringList CFlags,
StringRef Name, StringRef Content)
 {
@@ -106,15 +106,21 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags,
return getModuleFromSource(std::move(CFlags), Name, OverlayFS);
 }
 
-std::unique_ptr
+std::unique_ptr
 getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path)
 {
IntrusiveRefCntPtr VFS(vfs::getRealFileSystem());
return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
+PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M))
+{
+
+}
+
+
 std::unique_ptr
-getBPFObjectFromModule(llvm::Module *Module)
+PerfModule::toBPFObject(void)
 {
using namespace llvm;
 
@@ -278,7 +284,7 @@ int perf_clang__compile_bpf(const char *_filename,
auto M = getModuleFromSource(std::move(CFlags), Opts.getFileName());
if (!M)
return  -EINVAL;
-   auto O = getBPFObjectFromModule(&*M);
+   auto O = M->toBPFObject();
if (!O)
return -EINVAL;
 
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index dd8b042..cbb291b 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -11,16 +11,26 @@ namespace perf {
 
 using namespace llvm;
 
-std::unique_ptr
+class PerfModule {
+private:
+   std::unique_ptr Module;
+public:
+   inline llvm::Module *getModule(void)
+   {
+   return Module.get();
+   }
+
+   PerfModule(std::unique_ptr&& M);
+
+   std::unique_ptr toBPFObject(void);
+};
+
+std::unique_ptr
 getModuleFromSource(opt::ArgStringList CFlags,
StringRef Name, StringRef Content);
 
-std::unique_ptr
+std::unique_ptr
 getModuleFromSource(opt::ArgStringList CFlags,
StringRef Path);
-

[PATCH v3 12/30] perf clang: Allow passing CFLAGS to builtin clang

2016-11-25 Thread Wang Nan
Improve getModuleFromSource() API to accept a cflags list. This feature
will be used to pass LINUX_VERSION_CODE and -I flags.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-9-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/c++/clang-test.cpp |  5 +++--
 tools/perf/util/c++/clang.cpp  | 21 +
 tools/perf/util/c++/clang.h|  8 ++--
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 3da6bfa..0f484fb 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -16,8 +16,9 @@ int test__clang_to_IR(void)
perf_clang_scope _scope;
 
std::unique_ptr M =
-   perf::getModuleFromSource("perf-test.c",
- "int myfunc(void) {return 1;}");
+   perf::getModuleFromSource({"-DRESULT=1"},
+ "perf-test.c",
+ "int myfunc(void) {return RESULT;}");
 
if (!M)
return -1;
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index cf96199..715ca0a 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -29,7 +29,8 @@ static std::unique_ptr LLVMCtx;
 using namespace clang;
 
 static CompilerInvocation *
-createCompilerInvocation(StringRef& Path, DiagnosticsEngine& Diags)
+createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path,
+DiagnosticsEngine& Diags)
 {
llvm::opt::ArgStringList CCArgs {
"-cc1",
@@ -45,6 +46,8 @@ createCompilerInvocation(StringRef& Path, DiagnosticsEngine& 
Diags)
"-Wno-unused-value",
"-Wno-pointer-sign",
"-x", "c"};
+
+   CCArgs.append(CFlags.begin(), CFlags.end());
CompilerInvocation *CI = tooling::newInvocation(, CCArgs);
 
FrontendOptions& Opts = CI->getFrontendOpts();
@@ -54,8 +57,8 @@ createCompilerInvocation(StringRef& Path, DiagnosticsEngine& 
Diags)
 }
 
 static std::unique_ptr
-getModuleFromSource(StringRef Path,
-   IntrusiveRefCntPtr VFS)
+getModuleFromSource(llvm::opt::ArgStringList CFlags,
+   StringRef Path, IntrusiveRefCntPtr VFS)
 {
CompilerInstance Clang;
Clang.createDiagnostics();
@@ -63,7 +66,8 @@ getModuleFromSource(StringRef Path,
Clang.setVirtualFileSystem(&*VFS);
 
IntrusiveRefCntPtr CI =
-   createCompilerInvocation(Path, Clang.getDiagnostics());
+   createCompilerInvocation(std::move(CFlags), Path,
+Clang.getDiagnostics());
Clang.setInvocation(&*CI);
 
std::unique_ptr Act(new EmitLLVMOnlyAction(&*LLVMCtx));
@@ -74,7 +78,8 @@ getModuleFromSource(StringRef Path,
 }
 
 std::unique_ptr
-getModuleFromSource(StringRef Name, StringRef Content)
+getModuleFromSource(llvm::opt::ArgStringList CFlags,
+   StringRef Name, StringRef Content)
 {
using namespace vfs;
 
@@ -90,14 +95,14 @@ getModuleFromSource(StringRef Name, StringRef Content)
OverlayFS->pushOverlay(MemFS);
MemFS->addFile(Twine(Name), 0, 
llvm::MemoryBuffer::getMemBuffer(Content));
 
-   return getModuleFromSource(Name, OverlayFS);
+   return getModuleFromSource(std::move(CFlags), Name, OverlayFS);
 }
 
 std::unique_ptr
-getModuleFromSource(StringRef Path)
+getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path)
 {
IntrusiveRefCntPtr VFS(vfs::getRealFileSystem());
-   return getModuleFromSource(Path, VFS);
+   return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
 }
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index 90aff01..b4fc2a9 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -4,16 +4,20 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#include "llvm/Option/Option.h"
 #include 
+
 namespace perf {
 
 using namespace llvm;
 
 std::unique_ptr
-getModuleFromSource(StringRef Name, StringRef Content);
+getModuleFromSource(opt::ArgStringList CFlags,
+   StringRef Name, StringRef Content);
 
 std::unique_ptr
-getModuleFromSource(StringRef Path);
+getModuleFromSource(opt::ArgStringList CFlags,
+   StringRef Path);
 
 }
 #endif
-- 
2.10.1



[PATCH v3 28/30] perf clang: Include helpers to BPF scripts

2016-11-25 Thread Wang Nan
Automatically include some commonly used macros and struct definitions
into BPF scripts. Script writers are no longer required to define
'SEC' and 'struct bpf_map_def' in each of their scripts.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/bpf-script-example.c |  2 +-
 tools/perf/tests/bpf-script-test-kbuild.c |  2 ++
 tools/perf/tests/bpf-script-test-prologue.c   |  4 +++-
 tools/perf/tests/bpf-script-test-relocation.c |  3 +--
 tools/perf/util/c++/Build |  1 +
 tools/perf/util/c++/bpf-helper-str.c  | 15 +++
 tools/perf/util/c++/clang-bpf-includes.h  |  1 +
 tools/perf/util/c++/clang.cpp |  1 +
 8 files changed, 25 insertions(+), 4 deletions(-)
 create mode 100644 tools/perf/util/c++/bpf-helper-str.c

diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index 42dc341..e60bebf 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -9,6 +9,7 @@
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
 
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 struct bpf_map_def {
unsigned int type;
unsigned int key_size;
@@ -18,7 +19,6 @@ struct bpf_map_def {
 
 #define SEC(NAME) __attribute__((section(NAME), used))
 
-#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 #define BPF_FUNC_map_lookup_elem 1
 #define BPF_FUNC_map_update_elem 2
 
diff --git a/tools/perf/tests/bpf-script-test-kbuild.c 
b/tools/perf/tests/bpf-script-test-kbuild.c
index 3626924..f1b48a4 100644
--- a/tools/perf/tests/bpf-script-test-kbuild.c
+++ b/tools/perf/tests/bpf-script-test-kbuild.c
@@ -6,7 +6,9 @@
 # error Need LINUX_VERSION_CODE
 # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" 
into llvm section of ~/.perfconfig'
 #endif
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 #define SEC(NAME) __attribute__((section(NAME), used))
+#endif
 
 #include 
 #include 
diff --git a/tools/perf/tests/bpf-script-test-prologue.c 
b/tools/perf/tests/bpf-script-test-prologue.c
index ada812b..e2176c9 100644
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ b/tools/perf/tests/bpf-script-test-prologue.c
@@ -6,7 +6,6 @@
 # error Need LINUX_VERSION_CODE
 # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" 
into llvm section of ~/.perfconfig'
 #endif
-#define SEC(NAME) __attribute__((section(NAME), used))
 
 #include 
 
@@ -14,6 +13,9 @@
 #define FMODE_WRITE0x2
 
 #ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
+
+#define SEC(NAME) __attribute__((section(NAME), used))
+
 static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
(void *) 6;
 #endif
diff --git a/tools/perf/tests/bpf-script-test-relocation.c 
b/tools/perf/tests/bpf-script-test-relocation.c
index 57c96a3..bb54926 100644
--- a/tools/perf/tests/bpf-script-test-relocation.c
+++ b/tools/perf/tests/bpf-script-test-relocation.c
@@ -9,6 +9,7 @@
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
 
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 struct bpf_map_def {
unsigned int type;
unsigned int key_size;
@@ -17,8 +18,6 @@ struct bpf_map_def {
 };
 
 #define SEC(NAME) __attribute__((section(NAME), used))
-
-#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 #define BPF_FUNC_map_lookup_elem 1
 #define BPF_FUNC_map_update_elem 2
 
diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
index bd71abf..faa0268 100644
--- a/tools/perf/util/c++/Build
+++ b/tools/perf/util/c++/Build
@@ -1,3 +1,4 @@
 libperf-$(CONFIG_CLANGLLVM) += clang.o
 libperf-$(CONFIG_CLANGLLVM) += clang-test.o
 libperf-$(CONFIG_CLANGLLVM) += bpf-funcs-str.o
+libperf-$(CONFIG_CLANGLLVM) += bpf-helper-str.o
diff --git a/tools/perf/util/c++/bpf-helper-str.c 
b/tools/perf/util/c++/bpf-helper-str.c
new file mode 100644
index 000..17f915c
--- /dev/null
+++ b/tools/perf/util/c++/bpf-helper-str.c
@@ -0,0 +1,15 @@
+#include "clang-bpf-includes.h"
+const char clang_builtin_bpf_helper_str[] =
+"#ifdef BUILTIN_CLANG_DEFAULT_INCLUDE\n"
+"#ifndef BPF_HELPER_DEFINED\n"
+"#define BPF_HELPER_DEFINED\n"
+"struct bpf_map_def {\n"
+"  unsigned int type;\n"
+"  unsigned int key_size;\n"
+"  unsigned int value_size;\n"
+"  unsigned int max_entries;\n"
+"};\n"
+"#define SEC(NAME) __attribute__((section(NAME), used))\n"
+"#endif\n"
+"#endif"
+;
diff --git a/tools/perf/util/c++/clang-bpf-includes.h 
b/tools/perf/util/c++/clang-bpf-includes.h
index 385a5bb..577b40c 100644
--- a/tools/perf/util/c++/clang-bpf-includes.h
+++ b/tools/perf/util/c++/clang-bpf-includes.h
@@ -5,6 +5,7 @@ extern "C" {
 #endif
 
 extern const char clang_builtin_bpf_funcs_str[];
+extern const char clang_builtin_bpf_helper_str[];
 
 #ifdef __cplusplus
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp

[PATCH v3 20/30] perf clang jit: add PerfModule::doJIT to JIT perfhook functions

2016-11-25 Thread Wang Nan
PerfModule::doJIT JIT compile perfhook functions and saves result into
a map. Add a test case for it.

At this stage perfhook functions can do no useful things because they
can't invoke external functions and can't return value. Following
commits are going to make improvment.

Don't hook functions right after jitted because bpf_object is unavailable
during jitting but it should be the context of jitted functions.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/bpf-script-example.c |  8 
 tools/perf/tests/clang.c  |  4 ++
 tools/perf/util/c++/clang-c.h |  2 +
 tools/perf/util/c++/clang-test.cpp| 32 +++-
 tools/perf/util/c++/clang.cpp | 71 +++
 tools/perf/util/c++/clang.h   | 13 +++
 6 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index 268e5f8..265036e 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -46,3 +46,11 @@ int bpf_func__SyS_epoll_wait(void *ctx)
 }
 char _license[] SEC("license") = "GPL";
 int _version SEC("version") = LINUX_VERSION_CODE;
+
+#ifdef TEST_PERF_HOOK
+SEC("perfhook:test")
+void hook_test(void)
+{
+   return;
+}
+#endif
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
index 2964c06..f274e62 100644
--- a/tools/perf/tests/clang.c
+++ b/tools/perf/tests/clang.c
@@ -16,6 +16,10 @@ static struct {
.func = test__clang_to_obj,
.desc = "Test builtin clang compile C source to ELF object",
},
+   {
+   .func = test__clang_jit,
+   .desc = "Test builtin clang compile mixed BPF and native code",
+   },
 #endif
 };
 
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 0eadd79..5ebcb41 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -14,6 +14,7 @@ extern void perf_clang__cleanup(void);
 
 extern int test__clang_to_IR(void);
 extern int test__clang_to_obj(void);
+extern int test__clang_jit(void);
 
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
@@ -26,6 +27,7 @@ static inline void perf_clang__cleanup(void) { }
 
 static inline int test__clang_to_IR(void) { return -1; }
 static inline int test__clang_to_obj(void) { return -1;}
+static inline int test__clang_jit(void) { return -1;}
 
 static inline int
 perf_clang__compile_bpf(const char *filename __maybe_unused,
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index fb05e56..2b4aa8d 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 class perf_clang_scope {
@@ -14,7 +15,7 @@ public:
 };
 
 static std::unique_ptr
-__test__clang_to_IR(void)
+__test__clang_to_IR(bool perfhook)
 {
unsigned int kernel_version;
 
@@ -23,14 +24,22 @@ __test__clang_to_IR(void)
 
std::string cflag_kver("-DLINUX_VERSION_CODE=" +
std::to_string(kernel_version));
+   std::string cflag_perfhook(perfhook ? "-DTEST_PERF_HOOK=1" : "");
 
std::unique_ptr M =
-   perf::getModuleFromSource({cflag_kver.c_str()},
+   perf::getModuleFromSource({cflag_kver.c_str(),
+  cflag_perfhook.c_str()},
  "perf-test.c",
  test_llvm__bpf_base_prog);
return M;
 }
 
+static std::unique_ptr
+__test__clang_to_IR(void)
+{
+   return __test__clang_to_IR(false);
+}
+
 extern "C" {
 int test__clang_to_IR(void)
 {
@@ -59,4 +68,23 @@ int test__clang_to_obj(void)
return 0;
 }
 
+int test__clang_jit(void)
+{
+   perf_clang_scope _scope;
+
+   auto M = __test__clang_to_IR(true);
+   if (!M)
+   return -1;
+
+   if (M->doJIT())
+   return -1;
+
+   std::unique_ptr hooks(M->copyJITResult());
+   for (auto i : *hooks)
+   perf_hooks__set_hook(i.first.c_str(), i.second, NULL);
+
+   perf_hooks__invoke_test();
+   return 0;
+}
+
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 98d05e2..03012b2 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -14,9 +14,14 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include 

[PATCH v3 26/30] perf clang: Link BPF functions declaration into perf

2016-11-25 Thread Wang Nan
Use a shell script to generate BPF functions declarations from kernel
source code, embed the generated header into a C string. Following
commits will utilizes clang's virtual file system to automatically
include this header to all BPF scripts.

The generated header is wrapped by a BUILTIN_CLANG_NO_DEFAULT_INCLUDE.
This macro will be used by following commits to allow user disable this
and other builtin includes.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/Build|   1 +
 tools/perf/util/c++/bpf-funcs-str.c  | 228 +++
 tools/perf/util/c++/clang-bpf-includes.h |  12 ++
 3 files changed, 241 insertions(+)
 create mode 100644 tools/perf/util/c++/bpf-funcs-str.c
 create mode 100644 tools/perf/util/c++/clang-bpf-includes.h

diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
index 988fef1..bd71abf 100644
--- a/tools/perf/util/c++/Build
+++ b/tools/perf/util/c++/Build
@@ -1,2 +1,3 @@
 libperf-$(CONFIG_CLANGLLVM) += clang.o
 libperf-$(CONFIG_CLANGLLVM) += clang-test.o
+libperf-$(CONFIG_CLANGLLVM) += bpf-funcs-str.o
diff --git a/tools/perf/util/c++/bpf-funcs-str.c 
b/tools/perf/util/c++/bpf-funcs-str.c
new file mode 100644
index 000..f6bcf76
--- /dev/null
+++ b/tools/perf/util/c++/bpf-funcs-str.c
@@ -0,0 +1,228 @@
+/*
+ * This file is generated by following script:
+ *
+ * #!/bin/bash
+ * TEMP_KBUILD=$(mktemp -d)
+ * KERNEL_DIR=$(pwd)
+ * OUTPUT=tools/perf/util/c++/bpf-funcs-str.c
+ * rm -rf $OUTPUT
+ * echo "Use temp dir: $TEMP_KBUILD"
+ * function finish()
+ * {
+ * rm -rf $TEMP_KBUILD
+ * }
+ * trap finish EXIT
+ * SRCLIST=$(find -name "*.c" | xargs grep bpf_func_proto -l)
+ * cd $TEMP_KBUILD
+ * yes '' | make -C $KERNEL_DIR O=`pwd` oldconfig
+ * cat << EOF >> ./.config
+ * CONFIG_BPF=y
+ * CONFIG_BPF_SYSCALL=y
+ * CONFIG_PERF_EVENTS=y
+ * CONFIG_SOCK_CGROUP_DATA=y
+ * EOF
+ * yes '' | make -C $KERNEL_DIR O=`pwd` oldconfig
+ * FIXOBJLIST=""
+ * for src in ${SRCLIST}
+ * do
+ * mkdir -p $(dirname $src)
+ * cat << EOF > "${src}-fix.c"
+ * #include 
+ * #undef __init
+ * #define __init __attribute__((constructor))
+ * #include "`basename $src`"
+ * EOF
+ * if [ $(basename $src) == "syscall.c" ]
+ * then
+ * cat << EOF >> "${src}-fix.c"
+ * const struct bpf_verifier_ops *
+ * find_prog_type_export(enum bpf_prog_type type)
+ * {
+ * struct bpf_prog_aux aux;
+ * struct bpf_prog p = {.aux =  };
+ * if (find_prog_type(type, ))
+ * return NULL;
+ * return p.aux->ops;
+ * }
+ * EOF
+ * fi
+ * FIXOBJLIST="$FIXOBJLIST ${src}-fix.o"
+ * done
+ * function dolink()
+ * {
+ * touch ./syms.c
+ * echo gcc kernel/bpf/main.o ./syms.c $FIXOBJLIST -o ./gen
+ * gcc kernel/bpf/main.o ./syms.c $FIXOBJLIST -o ./gen
+ * }
+ * MAIN=kernel/bpf/main.c
+ * cat << EOF > $MAIN
+ * #include 
+ * #include 
+ * struct bpf_func {
+ *   const char *name;
+ *   int id;
+ * } bpf_funcs[] = {
+ * EOF
+ * grep '^[[:space:]]BPF_FUNC_[^ ]*,' $KERNEL_DIR/include/uapi/linux/bpf.h | \
+ * sed -e 's/.*BPF_FUNC_\([^,]*\),.*$/\1/g' | \
+ * xargs -n 1 sh -c 'echo {.name = \"$1\", .id = BPF_FUNC_$1}, >> '"$MAIN" 
sh
+ * cat << EOF >> $MAIN
+ * {NULL, -1},
+ * };
+ * int capable(int x) {return 1;}
+ * int trace_printk_init_buffers(void) {return 0;}
+ * static int x;
+ * void *metadata_dst_alloc_percpu(int a, int b) {return }
+ * int ___ratelimit(void *a, const void *func) {return 0;}
+ * extern const struct bpf_verifier_ops *
+ * find_prog_type_export(enum bpf_prog_type type);
+ * extern int printf(const char *fmt, ...);
+ * int main(int argc, char *argv[])
+ * {
+ * struct bpf_func *f = _funcs[0];
+ * printf("#ifndef BPF_FUNCS_DEFINED\n");
+ * printf("#define BPF_FUNCS_DEFINED\n");
+ * while (f->id != -1) {
+ * enum bpf_prog_type t;
+ * const enum bpf_arg_type *argt;
+ * const struct bpf_verifier_ops *ops = NULL;
+ * const struct bpf_func_proto *proto = NULL;
+ * if (f->id == 0)
+ * goto skip;
+ * for (t = BPF_PROG_TYPE_UNSPEC + 1; ; t++) {
+ * ops = find_prog_type_export(t);
+ * if (!ops)
+ * break;
+ * proto = ops->get_func_proto(f->id);
+ * if (proto)
+ * break;
+ * }
+ * if (!proto) {
+ * printf("static void (*%s)(void) = (void *)-1;\n", 
f->name);
+ * continue;
+ * }
+ * printf("static ");
+ * switch (proto->ret_type) {
+ * case RET_INTEGER:
+ * printf("long ");
+ * break;
+ * 

[PATCH v3 29/30] perf clang builtin: Define hook helpers by default

2016-11-25 Thread Wang Nan
Append declarations of helpers to default include file. All functions
appear in exported_funcs array should be declared here except
test__clang_callback, because it is used for perf test only.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/bpf-helper-str.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/tools/perf/util/c++/bpf-helper-str.c 
b/tools/perf/util/c++/bpf-helper-str.c
index 17f915c..f4d6d57 100644
--- a/tools/perf/util/c++/bpf-helper-str.c
+++ b/tools/perf/util/c++/bpf-helper-str.c
@@ -10,6 +10,13 @@ const char clang_builtin_bpf_helper_str[] =
 "  unsigned int max_entries;\n"
 "};\n"
 "#define SEC(NAME) __attribute__((section(NAME), used))\n"
+"extern int printf(const char *, ...);\n"
+"extern int puts(const char *);\n"
+"extern int perf_map_update_elem(void *, void *, void *, void *, unsigned 
long);\n"
+"extern int perf_map_lookup_elem(void *, void *, void *, void *);\n"
+"extern int perf_map_get_next_key(void *, void *, void *, void *);\n"
+"extern int perf_map_pin(void *, void *, const char *);\n"
+"extern int perf_map_get(const char *);\n"
 "#endif\n"
 "#endif"
 ;
-- 
2.10.1



[PATCH v3 18/30] perf clang jit: Wrap llvm::Module using PerfModule

2016-11-25 Thread Wang Nan
Use PerfModule wrap llvm::Module and return perf::PerfModule in APIs to
replace llvm::Module. Following commits are going to add new functions
to PerfModule.

getBPFObjectFromModule is merged to a method of perf::PerfModule.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang-test.cpp | 10 +-
 tools/perf/util/c++/clang.cpp  | 20 +---
 tools/perf/util/c++/clang.h| 22 --
 3 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 9b11e8c..fb05e56 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -13,18 +13,18 @@ public:
~perf_clang_scope() {perf_clang__cleanup();}
 };
 
-static std::unique_ptr
+static std::unique_ptr
 __test__clang_to_IR(void)
 {
unsigned int kernel_version;
 
if (fetch_kernel_version(_version, NULL, 0))
-   return std::unique_ptr(nullptr);
+   return std::unique_ptr(nullptr);
 
std::string cflag_kver("-DLINUX_VERSION_CODE=" +
std::to_string(kernel_version));
 
-   std::unique_ptr M =
+   std::unique_ptr M =
perf::getModuleFromSource({cflag_kver.c_str()},
  "perf-test.c",
  test_llvm__bpf_base_prog);
@@ -39,7 +39,7 @@ int test__clang_to_IR(void)
auto M = __test__clang_to_IR();
if (!M)
return -1;
-   for (llvm::Function& F : *M)
+   for (llvm::Function& F : *(M->getModule()))
if (F.getName() == "bpf_func__SyS_epoll_wait")
return 0;
return -1;
@@ -53,7 +53,7 @@ int test__clang_to_obj(void)
if (!M)
return -1;
 
-   auto Buffer = perf::getBPFObjectFromModule(&*M);
+   auto Buffer = M->toBPFObject();
if (!Buffer)
return -1;
return 0;
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 3a3b9791..d31b0a5 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -64,7 +64,7 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, 
StringRef& Path,
return CI;
 }
 
-static std::unique_ptr
+static std::unique_ptr
 getModuleFromSource(llvm::opt::ArgStringList CFlags,
StringRef Path, IntrusiveRefCntPtr VFS)
 {
@@ -80,12 +80,12 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags,
 
std::unique_ptr Act(new EmitLLVMOnlyAction(&*LLVMCtx));
if (!Clang.ExecuteAction(*Act))
-   return std::unique_ptr(nullptr);
+   return std::unique_ptr(nullptr);
 
-   return Act->takeModule();
+   return std::unique_ptr(new 
PerfModule(std::move(Act->takeModule(;
 }
 
-std::unique_ptr
+std::unique_ptr
 getModuleFromSource(llvm::opt::ArgStringList CFlags,
StringRef Name, StringRef Content)
 {
@@ -106,15 +106,21 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags,
return getModuleFromSource(std::move(CFlags), Name, OverlayFS);
 }
 
-std::unique_ptr
+std::unique_ptr
 getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path)
 {
IntrusiveRefCntPtr VFS(vfs::getRealFileSystem());
return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
+PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M))
+{
+
+}
+
+
 std::unique_ptr>
-getBPFObjectFromModule(llvm::Module *Module)
+PerfModule::toBPFObject(void)
 {
using namespace llvm;
 
@@ -278,7 +284,7 @@ int perf_clang__compile_bpf(const char *_filename,
auto M = getModuleFromSource(std::move(CFlags), Opts.getFileName());
if (!M)
return  -EINVAL;
-   auto O = getBPFObjectFromModule(&*M);
+   auto O = M->toBPFObject();
if (!O)
return -EINVAL;
 
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index dd8b042..cbb291b 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -11,16 +11,26 @@ namespace perf {
 
 using namespace llvm;
 
-std::unique_ptr
+class PerfModule {
+private:
+   std::unique_ptr Module;
+public:
+   inline llvm::Module *getModule(void)
+   {
+   return Module.get();
+   }
+
+   PerfModule(std::unique_ptr&& M);
+
+   std::unique_ptr> toBPFObject(void);
+};
+
+std::unique_ptr
 getModuleFromSource(opt::ArgStringList CFlags,
StringRef Name, StringRef Content);
 
-std::unique_ptr
+std::unique_ptr
 getModuleFromSource(opt::ArgStringList CFlags,
StringRef Path);
-
-std::unique_ptr>
-getBPFObjectFromModule(llvm::Module *Module);
-
 }
 #endif
-- 
2.10.1



[PATCH v3 12/30] perf clang: Allow passing CFLAGS to builtin clang

2016-11-25 Thread Wang Nan
Improve getModuleFromSource() API to accept a cflags list. This feature
will be used to pass LINUX_VERSION_CODE and -I flags.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-9-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/c++/clang-test.cpp |  5 +++--
 tools/perf/util/c++/clang.cpp  | 21 +
 tools/perf/util/c++/clang.h|  8 ++--
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 3da6bfa..0f484fb 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -16,8 +16,9 @@ int test__clang_to_IR(void)
perf_clang_scope _scope;
 
std::unique_ptr M =
-   perf::getModuleFromSource("perf-test.c",
- "int myfunc(void) {return 1;}");
+   perf::getModuleFromSource({"-DRESULT=1"},
+ "perf-test.c",
+ "int myfunc(void) {return RESULT;}");
 
if (!M)
return -1;
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index cf96199..715ca0a 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -29,7 +29,8 @@ static std::unique_ptr LLVMCtx;
 using namespace clang;
 
 static CompilerInvocation *
-createCompilerInvocation(StringRef& Path, DiagnosticsEngine& Diags)
+createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path,
+DiagnosticsEngine& Diags)
 {
llvm::opt::ArgStringList CCArgs {
"-cc1",
@@ -45,6 +46,8 @@ createCompilerInvocation(StringRef& Path, DiagnosticsEngine& 
Diags)
"-Wno-unused-value",
"-Wno-pointer-sign",
"-x", "c"};
+
+   CCArgs.append(CFlags.begin(), CFlags.end());
CompilerInvocation *CI = tooling::newInvocation(, CCArgs);
 
FrontendOptions& Opts = CI->getFrontendOpts();
@@ -54,8 +57,8 @@ createCompilerInvocation(StringRef& Path, DiagnosticsEngine& 
Diags)
 }
 
 static std::unique_ptr
-getModuleFromSource(StringRef Path,
-   IntrusiveRefCntPtr VFS)
+getModuleFromSource(llvm::opt::ArgStringList CFlags,
+   StringRef Path, IntrusiveRefCntPtr VFS)
 {
CompilerInstance Clang;
Clang.createDiagnostics();
@@ -63,7 +66,8 @@ getModuleFromSource(StringRef Path,
Clang.setVirtualFileSystem(&*VFS);
 
IntrusiveRefCntPtr CI =
-   createCompilerInvocation(Path, Clang.getDiagnostics());
+   createCompilerInvocation(std::move(CFlags), Path,
+Clang.getDiagnostics());
Clang.setInvocation(&*CI);
 
std::unique_ptr Act(new EmitLLVMOnlyAction(&*LLVMCtx));
@@ -74,7 +78,8 @@ getModuleFromSource(StringRef Path,
 }
 
 std::unique_ptr
-getModuleFromSource(StringRef Name, StringRef Content)
+getModuleFromSource(llvm::opt::ArgStringList CFlags,
+   StringRef Name, StringRef Content)
 {
using namespace vfs;
 
@@ -90,14 +95,14 @@ getModuleFromSource(StringRef Name, StringRef Content)
OverlayFS->pushOverlay(MemFS);
MemFS->addFile(Twine(Name), 0, 
llvm::MemoryBuffer::getMemBuffer(Content));
 
-   return getModuleFromSource(Name, OverlayFS);
+   return getModuleFromSource(std::move(CFlags), Name, OverlayFS);
 }
 
 std::unique_ptr
-getModuleFromSource(StringRef Path)
+getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path)
 {
IntrusiveRefCntPtr VFS(vfs::getRealFileSystem());
-   return getModuleFromSource(Path, VFS);
+   return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
 }
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index 90aff01..b4fc2a9 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -4,16 +4,20 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#include "llvm/Option/Option.h"
 #include 
+
 namespace perf {
 
 using namespace llvm;
 
 std::unique_ptr
-getModuleFromSource(StringRef Name, StringRef Content);
+getModuleFromSource(opt::ArgStringList CFlags,
+   StringRef Name, StringRef Content);
 
 std::unique_ptr
-getModuleFromSource(StringRef Path);
+getModuleFromSource(opt::ArgStringList CFlags,
+   StringRef Path);
 
 }
 #endif
-- 
2.10.1



[PATCH v3 28/30] perf clang: Include helpers to BPF scripts

2016-11-25 Thread Wang Nan
Automatically include some commonly used macros and struct definitions
into BPF scripts. Script writers are no longer required to define
'SEC' and 'struct bpf_map_def' in each of their scripts.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/bpf-script-example.c |  2 +-
 tools/perf/tests/bpf-script-test-kbuild.c |  2 ++
 tools/perf/tests/bpf-script-test-prologue.c   |  4 +++-
 tools/perf/tests/bpf-script-test-relocation.c |  3 +--
 tools/perf/util/c++/Build |  1 +
 tools/perf/util/c++/bpf-helper-str.c  | 15 +++
 tools/perf/util/c++/clang-bpf-includes.h  |  1 +
 tools/perf/util/c++/clang.cpp |  1 +
 8 files changed, 25 insertions(+), 4 deletions(-)
 create mode 100644 tools/perf/util/c++/bpf-helper-str.c

diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index 42dc341..e60bebf 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -9,6 +9,7 @@
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
 
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 struct bpf_map_def {
unsigned int type;
unsigned int key_size;
@@ -18,7 +19,6 @@ struct bpf_map_def {
 
 #define SEC(NAME) __attribute__((section(NAME), used))
 
-#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 #define BPF_FUNC_map_lookup_elem 1
 #define BPF_FUNC_map_update_elem 2
 
diff --git a/tools/perf/tests/bpf-script-test-kbuild.c 
b/tools/perf/tests/bpf-script-test-kbuild.c
index 3626924..f1b48a4 100644
--- a/tools/perf/tests/bpf-script-test-kbuild.c
+++ b/tools/perf/tests/bpf-script-test-kbuild.c
@@ -6,7 +6,9 @@
 # error Need LINUX_VERSION_CODE
 # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" 
into llvm section of ~/.perfconfig'
 #endif
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 #define SEC(NAME) __attribute__((section(NAME), used))
+#endif
 
 #include 
 #include 
diff --git a/tools/perf/tests/bpf-script-test-prologue.c 
b/tools/perf/tests/bpf-script-test-prologue.c
index ada812b..e2176c9 100644
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ b/tools/perf/tests/bpf-script-test-prologue.c
@@ -6,7 +6,6 @@
 # error Need LINUX_VERSION_CODE
 # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" 
into llvm section of ~/.perfconfig'
 #endif
-#define SEC(NAME) __attribute__((section(NAME), used))
 
 #include 
 
@@ -14,6 +13,9 @@
 #define FMODE_WRITE0x2
 
 #ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
+
+#define SEC(NAME) __attribute__((section(NAME), used))
+
 static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
(void *) 6;
 #endif
diff --git a/tools/perf/tests/bpf-script-test-relocation.c 
b/tools/perf/tests/bpf-script-test-relocation.c
index 57c96a3..bb54926 100644
--- a/tools/perf/tests/bpf-script-test-relocation.c
+++ b/tools/perf/tests/bpf-script-test-relocation.c
@@ -9,6 +9,7 @@
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
 
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 struct bpf_map_def {
unsigned int type;
unsigned int key_size;
@@ -17,8 +18,6 @@ struct bpf_map_def {
 };
 
 #define SEC(NAME) __attribute__((section(NAME), used))
-
-#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 #define BPF_FUNC_map_lookup_elem 1
 #define BPF_FUNC_map_update_elem 2
 
diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
index bd71abf..faa0268 100644
--- a/tools/perf/util/c++/Build
+++ b/tools/perf/util/c++/Build
@@ -1,3 +1,4 @@
 libperf-$(CONFIG_CLANGLLVM) += clang.o
 libperf-$(CONFIG_CLANGLLVM) += clang-test.o
 libperf-$(CONFIG_CLANGLLVM) += bpf-funcs-str.o
+libperf-$(CONFIG_CLANGLLVM) += bpf-helper-str.o
diff --git a/tools/perf/util/c++/bpf-helper-str.c 
b/tools/perf/util/c++/bpf-helper-str.c
new file mode 100644
index 000..17f915c
--- /dev/null
+++ b/tools/perf/util/c++/bpf-helper-str.c
@@ -0,0 +1,15 @@
+#include "clang-bpf-includes.h"
+const char clang_builtin_bpf_helper_str[] =
+"#ifdef BUILTIN_CLANG_DEFAULT_INCLUDE\n"
+"#ifndef BPF_HELPER_DEFINED\n"
+"#define BPF_HELPER_DEFINED\n"
+"struct bpf_map_def {\n"
+"  unsigned int type;\n"
+"  unsigned int key_size;\n"
+"  unsigned int value_size;\n"
+"  unsigned int max_entries;\n"
+"};\n"
+"#define SEC(NAME) __attribute__((section(NAME), used))\n"
+"#endif\n"
+"#endif"
+;
diff --git a/tools/perf/util/c++/clang-bpf-includes.h 
b/tools/perf/util/c++/clang-bpf-includes.h
index 385a5bb..577b40c 100644
--- a/tools/perf/util/c++/clang-bpf-includes.h
+++ b/tools/perf/util/c++/clang-bpf-includes.h
@@ -5,6 +5,7 @@ extern "C" {
 #endif
 
 extern const char clang_builtin_bpf_funcs_str[];
+extern const char clang_builtin_bpf_helper_str[];
 
 #ifdef __cplusplus
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 926dae1..5c1efe8 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -48,6 

[PATCH v3 20/30] perf clang jit: add PerfModule::doJIT to JIT perfhook functions

2016-11-25 Thread Wang Nan
PerfModule::doJIT JIT compile perfhook functions and saves result into
a map. Add a test case for it.

At this stage perfhook functions can do no useful things because they
can't invoke external functions and can't return value. Following
commits are going to make improvment.

Don't hook functions right after jitted because bpf_object is unavailable
during jitting but it should be the context of jitted functions.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/bpf-script-example.c |  8 
 tools/perf/tests/clang.c  |  4 ++
 tools/perf/util/c++/clang-c.h |  2 +
 tools/perf/util/c++/clang-test.cpp| 32 +++-
 tools/perf/util/c++/clang.cpp | 71 +++
 tools/perf/util/c++/clang.h   | 13 +++
 6 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index 268e5f8..265036e 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -46,3 +46,11 @@ int bpf_func__SyS_epoll_wait(void *ctx)
 }
 char _license[] SEC("license") = "GPL";
 int _version SEC("version") = LINUX_VERSION_CODE;
+
+#ifdef TEST_PERF_HOOK
+SEC("perfhook:test")
+void hook_test(void)
+{
+   return;
+}
+#endif
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
index 2964c06..f274e62 100644
--- a/tools/perf/tests/clang.c
+++ b/tools/perf/tests/clang.c
@@ -16,6 +16,10 @@ static struct {
.func = test__clang_to_obj,
.desc = "Test builtin clang compile C source to ELF object",
},
+   {
+   .func = test__clang_jit,
+   .desc = "Test builtin clang compile mixed BPF and native code",
+   },
 #endif
 };
 
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 0eadd79..5ebcb41 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -14,6 +14,7 @@ extern void perf_clang__cleanup(void);
 
 extern int test__clang_to_IR(void);
 extern int test__clang_to_obj(void);
+extern int test__clang_jit(void);
 
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
@@ -26,6 +27,7 @@ static inline void perf_clang__cleanup(void) { }
 
 static inline int test__clang_to_IR(void) { return -1; }
 static inline int test__clang_to_obj(void) { return -1;}
+static inline int test__clang_jit(void) { return -1;}
 
 static inline int
 perf_clang__compile_bpf(const char *filename __maybe_unused,
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index fb05e56..2b4aa8d 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 class perf_clang_scope {
@@ -14,7 +15,7 @@ public:
 };
 
 static std::unique_ptr
-__test__clang_to_IR(void)
+__test__clang_to_IR(bool perfhook)
 {
unsigned int kernel_version;
 
@@ -23,14 +24,22 @@ __test__clang_to_IR(void)
 
std::string cflag_kver("-DLINUX_VERSION_CODE=" +
std::to_string(kernel_version));
+   std::string cflag_perfhook(perfhook ? "-DTEST_PERF_HOOK=1" : "");
 
std::unique_ptr M =
-   perf::getModuleFromSource({cflag_kver.c_str()},
+   perf::getModuleFromSource({cflag_kver.c_str(),
+  cflag_perfhook.c_str()},
  "perf-test.c",
  test_llvm__bpf_base_prog);
return M;
 }
 
+static std::unique_ptr
+__test__clang_to_IR(void)
+{
+   return __test__clang_to_IR(false);
+}
+
 extern "C" {
 int test__clang_to_IR(void)
 {
@@ -59,4 +68,23 @@ int test__clang_to_obj(void)
return 0;
 }
 
+int test__clang_jit(void)
+{
+   perf_clang_scope _scope;
+
+   auto M = __test__clang_to_IR(true);
+   if (!M)
+   return -1;
+
+   if (M->doJIT())
+   return -1;
+
+   std::unique_ptr hooks(M->copyJITResult());
+   for (auto i : *hooks)
+   perf_hooks__set_hook(i.first.c_str(), i.second, NULL);
+
+   perf_hooks__invoke_test();
+   return 0;
+}
+
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 98d05e2..03012b2 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -14,9 +14,14 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 

[PATCH v3 26/30] perf clang: Link BPF functions declaration into perf

2016-11-25 Thread Wang Nan
Use a shell script to generate BPF functions declarations from kernel
source code, embed the generated header into a C string. Following
commits will utilizes clang's virtual file system to automatically
include this header to all BPF scripts.

The generated header is wrapped by a BUILTIN_CLANG_NO_DEFAULT_INCLUDE.
This macro will be used by following commits to allow user disable this
and other builtin includes.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/Build|   1 +
 tools/perf/util/c++/bpf-funcs-str.c  | 228 +++
 tools/perf/util/c++/clang-bpf-includes.h |  12 ++
 3 files changed, 241 insertions(+)
 create mode 100644 tools/perf/util/c++/bpf-funcs-str.c
 create mode 100644 tools/perf/util/c++/clang-bpf-includes.h

diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
index 988fef1..bd71abf 100644
--- a/tools/perf/util/c++/Build
+++ b/tools/perf/util/c++/Build
@@ -1,2 +1,3 @@
 libperf-$(CONFIG_CLANGLLVM) += clang.o
 libperf-$(CONFIG_CLANGLLVM) += clang-test.o
+libperf-$(CONFIG_CLANGLLVM) += bpf-funcs-str.o
diff --git a/tools/perf/util/c++/bpf-funcs-str.c 
b/tools/perf/util/c++/bpf-funcs-str.c
new file mode 100644
index 000..f6bcf76
--- /dev/null
+++ b/tools/perf/util/c++/bpf-funcs-str.c
@@ -0,0 +1,228 @@
+/*
+ * This file is generated by following script:
+ *
+ * #!/bin/bash
+ * TEMP_KBUILD=$(mktemp -d)
+ * KERNEL_DIR=$(pwd)
+ * OUTPUT=tools/perf/util/c++/bpf-funcs-str.c
+ * rm -rf $OUTPUT
+ * echo "Use temp dir: $TEMP_KBUILD"
+ * function finish()
+ * {
+ * rm -rf $TEMP_KBUILD
+ * }
+ * trap finish EXIT
+ * SRCLIST=$(find -name "*.c" | xargs grep bpf_func_proto -l)
+ * cd $TEMP_KBUILD
+ * yes '' | make -C $KERNEL_DIR O=`pwd` oldconfig
+ * cat << EOF >> ./.config
+ * CONFIG_BPF=y
+ * CONFIG_BPF_SYSCALL=y
+ * CONFIG_PERF_EVENTS=y
+ * CONFIG_SOCK_CGROUP_DATA=y
+ * EOF
+ * yes '' | make -C $KERNEL_DIR O=`pwd` oldconfig
+ * FIXOBJLIST=""
+ * for src in ${SRCLIST}
+ * do
+ * mkdir -p $(dirname $src)
+ * cat << EOF > "${src}-fix.c"
+ * #include 
+ * #undef __init
+ * #define __init __attribute__((constructor))
+ * #include "`basename $src`"
+ * EOF
+ * if [ $(basename $src) == "syscall.c" ]
+ * then
+ * cat << EOF >> "${src}-fix.c"
+ * const struct bpf_verifier_ops *
+ * find_prog_type_export(enum bpf_prog_type type)
+ * {
+ * struct bpf_prog_aux aux;
+ * struct bpf_prog p = {.aux =  };
+ * if (find_prog_type(type, ))
+ * return NULL;
+ * return p.aux->ops;
+ * }
+ * EOF
+ * fi
+ * FIXOBJLIST="$FIXOBJLIST ${src}-fix.o"
+ * done
+ * function dolink()
+ * {
+ * touch ./syms.c
+ * echo gcc kernel/bpf/main.o ./syms.c $FIXOBJLIST -o ./gen
+ * gcc kernel/bpf/main.o ./syms.c $FIXOBJLIST -o ./gen
+ * }
+ * MAIN=kernel/bpf/main.c
+ * cat << EOF > $MAIN
+ * #include 
+ * #include 
+ * struct bpf_func {
+ *   const char *name;
+ *   int id;
+ * } bpf_funcs[] = {
+ * EOF
+ * grep '^[[:space:]]BPF_FUNC_[^ ]*,' $KERNEL_DIR/include/uapi/linux/bpf.h | \
+ * sed -e 's/.*BPF_FUNC_\([^,]*\),.*$/\1/g' | \
+ * xargs -n 1 sh -c 'echo {.name = \"$1\", .id = BPF_FUNC_$1}, >> '"$MAIN" 
sh
+ * cat << EOF >> $MAIN
+ * {NULL, -1},
+ * };
+ * int capable(int x) {return 1;}
+ * int trace_printk_init_buffers(void) {return 0;}
+ * static int x;
+ * void *metadata_dst_alloc_percpu(int a, int b) {return }
+ * int ___ratelimit(void *a, const void *func) {return 0;}
+ * extern const struct bpf_verifier_ops *
+ * find_prog_type_export(enum bpf_prog_type type);
+ * extern int printf(const char *fmt, ...);
+ * int main(int argc, char *argv[])
+ * {
+ * struct bpf_func *f = _funcs[0];
+ * printf("#ifndef BPF_FUNCS_DEFINED\n");
+ * printf("#define BPF_FUNCS_DEFINED\n");
+ * while (f->id != -1) {
+ * enum bpf_prog_type t;
+ * const enum bpf_arg_type *argt;
+ * const struct bpf_verifier_ops *ops = NULL;
+ * const struct bpf_func_proto *proto = NULL;
+ * if (f->id == 0)
+ * goto skip;
+ * for (t = BPF_PROG_TYPE_UNSPEC + 1; ; t++) {
+ * ops = find_prog_type_export(t);
+ * if (!ops)
+ * break;
+ * proto = ops->get_func_proto(f->id);
+ * if (proto)
+ * break;
+ * }
+ * if (!proto) {
+ * printf("static void (*%s)(void) = (void *)-1;\n", 
f->name);
+ * continue;
+ * }
+ * printf("static ");
+ * switch (proto->ret_type) {
+ * case RET_INTEGER:
+ * printf("long ");
+ * break;
+ * case RET_PTR_TO_MAP_VALUE_OR_NULL:
+ * printf("void *");
+ * break;
+ 

[PATCH v3 27/30] perf clang: Declare BPF functions for BPF scripts automatically

2016-11-25 Thread Wang Nan
Use Clang's OverlayFileSystem, add '-include' options to make builtin
clang define BPF functions. After this patch BPF script writer needn't
define BPF functions by their own.

Add -DBUILTIN_CLANG_DEFAULT_INCLUDE to builtin clang so when adopting
builtin clang BPF functions can be automatically defined, and keep
undefined when using external clang. Passing a
-UBUILTIN_CLANG_DEFAULT_INCLUDE to cancel this defaudefinition.

Test cases are updated to avoid redefinition of these functions.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/bpf-script-example.c | 18 +--
 tools/perf/tests/bpf-script-test-prologue.c   |  2 ++
 tools/perf/tests/bpf-script-test-relocation.c | 18 +--
 tools/perf/util/c++/clang.cpp | 33 ++-
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index ccbc19c..42dc341 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -8,13 +8,6 @@
 #endif
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
-#define BPF_FUNC_map_lookup_elem 1
-#define BPF_FUNC_map_update_elem 2
-
-static void *(*bpf_map_lookup_elem)(void *map, void *key) =
-   (void *) BPF_FUNC_map_lookup_elem;
-static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
-   (void *) BPF_FUNC_map_update_elem;
 
 struct bpf_map_def {
unsigned int type;
@@ -24,6 +17,17 @@ struct bpf_map_def {
 };
 
 #define SEC(NAME) __attribute__((section(NAME), used))
+
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
+#define BPF_FUNC_map_lookup_elem 1
+#define BPF_FUNC_map_update_elem 2
+
+static void *(*bpf_map_lookup_elem)(void *map, void *key) =
+   (void *) BPF_FUNC_map_lookup_elem;
+static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
+   (void *) BPF_FUNC_map_update_elem;
+#endif
+
 struct bpf_map_def SEC("maps") flip_table = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
diff --git a/tools/perf/tests/bpf-script-test-prologue.c 
b/tools/perf/tests/bpf-script-test-prologue.c
index 7230e62..ada812b 100644
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ b/tools/perf/tests/bpf-script-test-prologue.c
@@ -13,8 +13,10 @@
 #define FMODE_READ 0x1
 #define FMODE_WRITE0x2
 
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
(void *) 6;
+#endif
 
 SEC("func=null_lseek file->f_mode offset orig")
 int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode,
diff --git a/tools/perf/tests/bpf-script-test-relocation.c 
b/tools/perf/tests/bpf-script-test-relocation.c
index 93af774..57c96a3 100644
--- a/tools/perf/tests/bpf-script-test-relocation.c
+++ b/tools/perf/tests/bpf-script-test-relocation.c
@@ -8,13 +8,6 @@
 #endif
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
-#define BPF_FUNC_map_lookup_elem 1
-#define BPF_FUNC_map_update_elem 2
-
-static void *(*bpf_map_lookup_elem)(void *map, void *key) =
-   (void *) BPF_FUNC_map_lookup_elem;
-static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
-   (void *) BPF_FUNC_map_update_elem;
 
 struct bpf_map_def {
unsigned int type;
@@ -24,6 +17,17 @@ struct bpf_map_def {
 };
 
 #define SEC(NAME) __attribute__((section(NAME), used))
+
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
+#define BPF_FUNC_map_lookup_elem 1
+#define BPF_FUNC_map_update_elem 2
+
+static void *(*bpf_map_lookup_elem)(void *map, void *key) =
+   (void *) BPF_FUNC_map_lookup_elem;
+static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
+   (void *) BPF_FUNC_map_update_elem;
+#endif
+
 struct bpf_map_def SEC("maps") my_table = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 48bd3ee..926dae1 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -39,9 +39,17 @@
 #include "util-cxx.h"
 #include "perf-hooks.h"
 #include "jit-helpers.h"
+#include "clang-bpf-includes.h"
 
 namespace perf {
 
+static struct BPFHeader {
+   llvm::StringRef Path;
+   llvm::StringRef Content;
+} BPFHeaders[] = {
+   {"/virtual/bpf-funcs.h", clang_builtin_bpf_funcs_str},
+};
+
 static std::unique_ptr LLVMCtx;
 
 using namespace clang;
@@ -66,6 +74,11 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, 
StringRef& Path,
"-x", "c"};
 
CCArgs.append(CFlags.begin(), CFlags.end());
+   for (BPFHeader  : BPFHeaders) {
+   CCArgs.append(1, "-include");
+   CCArgs.append(1, h.Path.begin());

[PATCH v3 09/30] perf build: Add clang and llvm compile and linking support

2016-11-25 Thread Wang Nan
Add necessary c++ flags and link libraries to support builtin clang and
LLVM. Add all llvm and clang libraries, so don't need to worry about
clang changes its libraries setting. However, linking perf would take
much longer than usual.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-6-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/Makefile.config | 35 +++
 tools/perf/Makefile.perf   | 23 ++-
 tools/perf/tests/make  |  2 ++
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 8a493d4..b7c9c80 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -136,6 +136,7 @@ endif
 # Treat warnings as errors unless directed not to
 ifneq ($(WERROR),0)
   CFLAGS += -Werror
+  CXXFLAGS += -Werror
 endif
 
 ifndef DEBUG
@@ -182,6 +183,13 @@ CFLAGS += -Wall
 CFLAGS += -Wextra
 CFLAGS += -std=gnu99
 
+CXXFLAGS += -std=gnu++11 -fno-exceptions -fno-rtti
+CXXFLAGS += -Wall
+CXXFLAGS += -fno-omit-frame-pointer
+CXXFLAGS += -ggdb3
+CXXFLAGS += -funwind-tables
+CXXFLAGS += -Wno-strict-aliasing
+
 # Enforce a non-executable stack, as we may regress (again) in the future by
 # adding assembler files missing the .GNU-stack linker note.
 LDFLAGS += -Wl,-z,noexecstack
@@ -783,6 +791,33 @@ ifndef NO_JVMTI
   endif
 endif
 
+USE_CXX = 0
+USE_CLANGLLVM = 0
+ifdef LIBCLANGLLVM
+  $(call feature_check,cxx)
+  ifneq ($(feature-cxx), 1)
+msg := $(warning No g++ found, disable clang and llvm support. Please 
install g++)
+  else
+$(call feature_check,llvm)
+ifneq ($(feature-llvm), 1)
+  msg := $(warning No libLLVM found, disable clang and llvm support. 
Please install llvm-dev)
+else
+  $(call feature_check,clang)
+  ifneq ($(feature-clang), 1)
+msg := $(warning No libclang found, disable clang and llvm support. 
Please install libclang-dev)
+  else
+CFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT
+CXXFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT -I$(shell $(LLVM_CONFIG) 
--includedir)
+$(call detected,CONFIG_CXX)
+$(call detected,CONFIG_CLANGLLVM)
+   USE_CXX = 1
+   USE_LLVM = 1
+   USE_CLANG = 1
+  endif
+endif
+  endif
+endif
+
 # Among the variables below, these:
 #   perfexecdir
 #   template_dir
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 3cb1df4..dfb20dd 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -88,6 +88,10 @@ include ../scripts/utilities.mak
 # and bypass the feature detection
 #
 # Define NO_JVMTI if you do not want jvmti agent built
+#
+# Define LIBCLANGLLVM if you DO want builtin clang and llvm support.
+# When selected, pass LLVM_CONFIG=/path/to/llvm-config to `make' if
+# llvm-config is not in $PATH.
 
 # As per kernel Makefile, avoid funny character set dependencies
 unexport LC_ALL
@@ -143,6 +147,7 @@ endef
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
 $(call allow-override,AR,$(CROSS_COMPILE)ar)
 $(call allow-override,LD,$(CROSS_COMPILE)ld)
+$(call allow-override,CXX,$(CROSS_COMPILE)g++)
 
 LD += $(EXTRA_LDFLAGS)
 
@@ -151,6 +156,7 @@ HOSTLD  ?= ld
 HOSTAR  ?= ar
 
 PKG_CONFIG = $(CROSS_COMPILE)pkg-config
+LLVM_CONFIG ?= llvm-config
 
 RM  = rm -f
 LN  = ln -f
@@ -338,6 +344,21 @@ endif
 
 LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive 
-Wl,--start-group $(EXTLIBS) -Wl,--end-group
 
+ifeq ($(USE_CLANG), 1)
+  CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema 
Analysis Parse Serialization
+  LIBCLANG = $(foreach l,$(CLANGLIBS_LIST),$(wildcard $(shell $(LLVM_CONFIG) 
--libdir)/libclang$(l).a))
+  LIBS += -Wl,--start-group $(LIBCLANG) -Wl,--end-group
+endif
+
+ifeq ($(USE_LLVM), 1)
+  LIBLLVM = $(shell $(LLVM_CONFIG) --libs all) $(shell $(LLVM_CONFIG) 
--system-libs)
+  LIBS += -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM)
+endif
+
+ifeq ($(USE_CXX), 1)
+  LIBS += -lstdc++
+endif
+
 export INSTALL SHELL_PATH
 
 ### Build rules
@@ -356,7 +377,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf
 
 PERF_IN := $(OUTPUT)perf-in.o
 
-export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
+export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK
 export HOSTCC HOSTLD HOSTAR
 include $(srctree)/tools/build/Makefile.include
 
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 08ed7f1..aa49b66 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -83,6 +83,7 @@ make_no_libbpf:= NO_LIBBPF=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_no_sdt:= NO_SDT=1
+make_with_clangllvm := LIBCLANGLLVM=1
 make_tags   := tags
 make_cscope := cscope
 make_help  

[PATCH v3 03/30] tools lib bpf: Retrive bpf_map through offset of bpf_map_def

2016-11-25 Thread Wang Nan
Add a new API to libbpf, caller is able to get bpf_map through the
offset of bpf_map_def to 'maps' section.

The API will be used to help jitted perf hook code find fd of a map.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/lib/bpf/libbpf.c | 12 
 tools/lib/bpf/libbpf.h |  8 
 2 files changed, 20 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 866d5cd..2e97459 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1524,3 +1524,15 @@ bpf_object__find_map_by_name(struct bpf_object *obj, 
const char *name)
}
return NULL;
 }
+
+struct bpf_map *
+bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset)
+{
+   int i;
+
+   for (i = 0; i < obj->nr_maps; i++) {
+   if (obj->maps[i].offset == offset)
+   return >maps[i];
+   }
+   return ERR_PTR(-ENOENT);
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 0c0b012..a5a8b86 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include   // for size_t
 
 enum libbpf_errno {
__LIBBPF_ERRNO__START = 4000,
@@ -200,6 +201,13 @@ struct bpf_map;
 struct bpf_map *
 bpf_object__find_map_by_name(struct bpf_object *obj, const char *name);
 
+/*
+ * Get bpf_map through the offset of corresponding struct bpf_map_def
+ * in the bpf object file.
+ */
+struct bpf_map *
+bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset);
+
 struct bpf_map *
 bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
 #define bpf_map__for_each(pos, obj)\
-- 
2.10.1



[PATCH v3 11/30] perf clang: Use real file system for #include

2016-11-25 Thread Wang Nan
Utilize clang's OverlayFileSystem facility, allow CompilerInstance to
access real file system.

With this patch '#include' directive can be used.

Add a new getModuleFromSource for real file.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 44 +++
 tools/perf/util/c++/clang.h   |  3 +++
 2 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index c17b117..cf96199 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -15,6 +15,7 @@
 #include "clang/Tooling/Tooling.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/ManagedStatic.h"
 #include 
 
@@ -27,14 +28,6 @@ static std::unique_ptr LLVMCtx;
 
 using namespace clang;
 
-static vfs::InMemoryFileSystem *
-buildVFS(StringRef& Name, StringRef& Content)
-{
-   vfs::InMemoryFileSystem *VFS = new vfs::InMemoryFileSystem(true);
-   VFS->addFile(Twine(Name), 0, llvm::MemoryBuffer::getMemBuffer(Content));
-   return VFS;
-}
-
 static CompilerInvocation *
 createCompilerInvocation(StringRef& Path, DiagnosticsEngine& Diags)
 {
@@ -60,17 +53,17 @@ createCompilerInvocation(StringRef& Path, 
DiagnosticsEngine& Diags)
return CI;
 }
 
-std::unique_ptr
-getModuleFromSource(StringRef Name, StringRef Content)
+static std::unique_ptr
+getModuleFromSource(StringRef Path,
+   IntrusiveRefCntPtr VFS)
 {
CompilerInstance Clang;
Clang.createDiagnostics();
 
-   IntrusiveRefCntPtr VFS = buildVFS(Name, Content);
Clang.setVirtualFileSystem(&*VFS);
 
IntrusiveRefCntPtr CI =
-   createCompilerInvocation(Name, Clang.getDiagnostics());
+   createCompilerInvocation(Path, Clang.getDiagnostics());
Clang.setInvocation(&*CI);
 
std::unique_ptr Act(new EmitLLVMOnlyAction(&*LLVMCtx));
@@ -80,6 +73,33 @@ getModuleFromSource(StringRef Name, StringRef Content)
return Act->takeModule();
 }
 
+std::unique_ptr
+getModuleFromSource(StringRef Name, StringRef Content)
+{
+   using namespace vfs;
+
+   llvm::IntrusiveRefCntPtr OverlayFS(
+   new OverlayFileSystem(getRealFileSystem()));
+   llvm::IntrusiveRefCntPtr MemFS(
+   new InMemoryFileSystem(true));
+
+   /*
+* pushOverlay helps setting working dir for MemFS. Must call
+* before addFile.
+*/
+   OverlayFS->pushOverlay(MemFS);
+   MemFS->addFile(Twine(Name), 0, 
llvm::MemoryBuffer::getMemBuffer(Content));
+
+   return getModuleFromSource(Name, OverlayFS);
+}
+
+std::unique_ptr
+getModuleFromSource(StringRef Path)
+{
+   IntrusiveRefCntPtr VFS(vfs::getRealFileSystem());
+   return getModuleFromSource(Path, VFS);
+}
+
 }
 
 extern "C" {
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index f64483b..90aff01 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -12,5 +12,8 @@ using namespace llvm;
 std::unique_ptr
 getModuleFromSource(StringRef Name, StringRef Content);
 
+std::unique_ptr
+getModuleFromSource(StringRef Path);
+
 }
 #endif
-- 
2.10.1



[PATCH v3 27/30] perf clang: Declare BPF functions for BPF scripts automatically

2016-11-25 Thread Wang Nan
Use Clang's OverlayFileSystem, add '-include' options to make builtin
clang define BPF functions. After this patch BPF script writer needn't
define BPF functions by their own.

Add -DBUILTIN_CLANG_DEFAULT_INCLUDE to builtin clang so when adopting
builtin clang BPF functions can be automatically defined, and keep
undefined when using external clang. Passing a
-UBUILTIN_CLANG_DEFAULT_INCLUDE to cancel this defaudefinition.

Test cases are updated to avoid redefinition of these functions.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/bpf-script-example.c | 18 +--
 tools/perf/tests/bpf-script-test-prologue.c   |  2 ++
 tools/perf/tests/bpf-script-test-relocation.c | 18 +--
 tools/perf/util/c++/clang.cpp | 33 ++-
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index ccbc19c..42dc341 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -8,13 +8,6 @@
 #endif
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
-#define BPF_FUNC_map_lookup_elem 1
-#define BPF_FUNC_map_update_elem 2
-
-static void *(*bpf_map_lookup_elem)(void *map, void *key) =
-   (void *) BPF_FUNC_map_lookup_elem;
-static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
-   (void *) BPF_FUNC_map_update_elem;
 
 struct bpf_map_def {
unsigned int type;
@@ -24,6 +17,17 @@ struct bpf_map_def {
 };
 
 #define SEC(NAME) __attribute__((section(NAME), used))
+
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
+#define BPF_FUNC_map_lookup_elem 1
+#define BPF_FUNC_map_update_elem 2
+
+static void *(*bpf_map_lookup_elem)(void *map, void *key) =
+   (void *) BPF_FUNC_map_lookup_elem;
+static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
+   (void *) BPF_FUNC_map_update_elem;
+#endif
+
 struct bpf_map_def SEC("maps") flip_table = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
diff --git a/tools/perf/tests/bpf-script-test-prologue.c 
b/tools/perf/tests/bpf-script-test-prologue.c
index 7230e62..ada812b 100644
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ b/tools/perf/tests/bpf-script-test-prologue.c
@@ -13,8 +13,10 @@
 #define FMODE_READ 0x1
 #define FMODE_WRITE0x2
 
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
 static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
(void *) 6;
+#endif
 
 SEC("func=null_lseek file->f_mode offset orig")
 int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode,
diff --git a/tools/perf/tests/bpf-script-test-relocation.c 
b/tools/perf/tests/bpf-script-test-relocation.c
index 93af774..57c96a3 100644
--- a/tools/perf/tests/bpf-script-test-relocation.c
+++ b/tools/perf/tests/bpf-script-test-relocation.c
@@ -8,13 +8,6 @@
 #endif
 #define BPF_ANY 0
 #define BPF_MAP_TYPE_ARRAY 2
-#define BPF_FUNC_map_lookup_elem 1
-#define BPF_FUNC_map_update_elem 2
-
-static void *(*bpf_map_lookup_elem)(void *map, void *key) =
-   (void *) BPF_FUNC_map_lookup_elem;
-static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
-   (void *) BPF_FUNC_map_update_elem;
 
 struct bpf_map_def {
unsigned int type;
@@ -24,6 +17,17 @@ struct bpf_map_def {
 };
 
 #define SEC(NAME) __attribute__((section(NAME), used))
+
+#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE
+#define BPF_FUNC_map_lookup_elem 1
+#define BPF_FUNC_map_update_elem 2
+
+static void *(*bpf_map_lookup_elem)(void *map, void *key) =
+   (void *) BPF_FUNC_map_lookup_elem;
+static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int 
flags) =
+   (void *) BPF_FUNC_map_update_elem;
+#endif
+
 struct bpf_map_def SEC("maps") my_table = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 48bd3ee..926dae1 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -39,9 +39,17 @@
 #include "util-cxx.h"
 #include "perf-hooks.h"
 #include "jit-helpers.h"
+#include "clang-bpf-includes.h"
 
 namespace perf {
 
+static struct BPFHeader {
+   llvm::StringRef Path;
+   llvm::StringRef Content;
+} BPFHeaders[] = {
+   {"/virtual/bpf-funcs.h", clang_builtin_bpf_funcs_str},
+};
+
 static std::unique_ptr LLVMCtx;
 
 using namespace clang;
@@ -66,6 +74,11 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, 
StringRef& Path,
"-x", "c"};
 
CCArgs.append(CFlags.begin(), CFlags.end());
+   for (BPFHeader  : BPFHeaders) {
+   CCArgs.append(1, "-include");
+   CCArgs.append(1, h.Path.begin());
+   }
+
CompilerInvocation *CI = tooling::newInvocation(, CCArgs);
 
FrontendOptions& 

[PATCH v3 09/30] perf build: Add clang and llvm compile and linking support

2016-11-25 Thread Wang Nan
Add necessary c++ flags and link libraries to support builtin clang and
LLVM. Add all llvm and clang libraries, so don't need to worry about
clang changes its libraries setting. However, linking perf would take
much longer than usual.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-6-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/Makefile.config | 35 +++
 tools/perf/Makefile.perf   | 23 ++-
 tools/perf/tests/make  |  2 ++
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 8a493d4..b7c9c80 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -136,6 +136,7 @@ endif
 # Treat warnings as errors unless directed not to
 ifneq ($(WERROR),0)
   CFLAGS += -Werror
+  CXXFLAGS += -Werror
 endif
 
 ifndef DEBUG
@@ -182,6 +183,13 @@ CFLAGS += -Wall
 CFLAGS += -Wextra
 CFLAGS += -std=gnu99
 
+CXXFLAGS += -std=gnu++11 -fno-exceptions -fno-rtti
+CXXFLAGS += -Wall
+CXXFLAGS += -fno-omit-frame-pointer
+CXXFLAGS += -ggdb3
+CXXFLAGS += -funwind-tables
+CXXFLAGS += -Wno-strict-aliasing
+
 # Enforce a non-executable stack, as we may regress (again) in the future by
 # adding assembler files missing the .GNU-stack linker note.
 LDFLAGS += -Wl,-z,noexecstack
@@ -783,6 +791,33 @@ ifndef NO_JVMTI
   endif
 endif
 
+USE_CXX = 0
+USE_CLANGLLVM = 0
+ifdef LIBCLANGLLVM
+  $(call feature_check,cxx)
+  ifneq ($(feature-cxx), 1)
+msg := $(warning No g++ found, disable clang and llvm support. Please 
install g++)
+  else
+$(call feature_check,llvm)
+ifneq ($(feature-llvm), 1)
+  msg := $(warning No libLLVM found, disable clang and llvm support. 
Please install llvm-dev)
+else
+  $(call feature_check,clang)
+  ifneq ($(feature-clang), 1)
+msg := $(warning No libclang found, disable clang and llvm support. 
Please install libclang-dev)
+  else
+CFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT
+CXXFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT -I$(shell $(LLVM_CONFIG) 
--includedir)
+$(call detected,CONFIG_CXX)
+$(call detected,CONFIG_CLANGLLVM)
+   USE_CXX = 1
+   USE_LLVM = 1
+   USE_CLANG = 1
+  endif
+endif
+  endif
+endif
+
 # Among the variables below, these:
 #   perfexecdir
 #   template_dir
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 3cb1df4..dfb20dd 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -88,6 +88,10 @@ include ../scripts/utilities.mak
 # and bypass the feature detection
 #
 # Define NO_JVMTI if you do not want jvmti agent built
+#
+# Define LIBCLANGLLVM if you DO want builtin clang and llvm support.
+# When selected, pass LLVM_CONFIG=/path/to/llvm-config to `make' if
+# llvm-config is not in $PATH.
 
 # As per kernel Makefile, avoid funny character set dependencies
 unexport LC_ALL
@@ -143,6 +147,7 @@ endef
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
 $(call allow-override,AR,$(CROSS_COMPILE)ar)
 $(call allow-override,LD,$(CROSS_COMPILE)ld)
+$(call allow-override,CXX,$(CROSS_COMPILE)g++)
 
 LD += $(EXTRA_LDFLAGS)
 
@@ -151,6 +156,7 @@ HOSTLD  ?= ld
 HOSTAR  ?= ar
 
 PKG_CONFIG = $(CROSS_COMPILE)pkg-config
+LLVM_CONFIG ?= llvm-config
 
 RM  = rm -f
 LN  = ln -f
@@ -338,6 +344,21 @@ endif
 
 LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive 
-Wl,--start-group $(EXTLIBS) -Wl,--end-group
 
+ifeq ($(USE_CLANG), 1)
+  CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema 
Analysis Parse Serialization
+  LIBCLANG = $(foreach l,$(CLANGLIBS_LIST),$(wildcard $(shell $(LLVM_CONFIG) 
--libdir)/libclang$(l).a))
+  LIBS += -Wl,--start-group $(LIBCLANG) -Wl,--end-group
+endif
+
+ifeq ($(USE_LLVM), 1)
+  LIBLLVM = $(shell $(LLVM_CONFIG) --libs all) $(shell $(LLVM_CONFIG) 
--system-libs)
+  LIBS += -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM)
+endif
+
+ifeq ($(USE_CXX), 1)
+  LIBS += -lstdc++
+endif
+
 export INSTALL SHELL_PATH
 
 ### Build rules
@@ -356,7 +377,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf
 
 PERF_IN := $(OUTPUT)perf-in.o
 
-export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
+export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK
 export HOSTCC HOSTLD HOSTAR
 include $(srctree)/tools/build/Makefile.include
 
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 08ed7f1..aa49b66 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -83,6 +83,7 @@ make_no_libbpf:= NO_LIBBPF=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_no_sdt:= NO_SDT=1
+make_with_clangllvm := LIBCLANGLLVM=1
 make_tags   := tags
 make_cscope := cscope
 make_help   := help
@@ -139,6 +140,7 @@ run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
 

[PATCH v3 03/30] tools lib bpf: Retrive bpf_map through offset of bpf_map_def

2016-11-25 Thread Wang Nan
Add a new API to libbpf, caller is able to get bpf_map through the
offset of bpf_map_def to 'maps' section.

The API will be used to help jitted perf hook code find fd of a map.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/lib/bpf/libbpf.c | 12 
 tools/lib/bpf/libbpf.h |  8 
 2 files changed, 20 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 866d5cd..2e97459 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1524,3 +1524,15 @@ bpf_object__find_map_by_name(struct bpf_object *obj, 
const char *name)
}
return NULL;
 }
+
+struct bpf_map *
+bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset)
+{
+   int i;
+
+   for (i = 0; i < obj->nr_maps; i++) {
+   if (obj->maps[i].offset == offset)
+   return >maps[i];
+   }
+   return ERR_PTR(-ENOENT);
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 0c0b012..a5a8b86 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include   // for size_t
 
 enum libbpf_errno {
__LIBBPF_ERRNO__START = 4000,
@@ -200,6 +201,13 @@ struct bpf_map;
 struct bpf_map *
 bpf_object__find_map_by_name(struct bpf_object *obj, const char *name);
 
+/*
+ * Get bpf_map through the offset of corresponding struct bpf_map_def
+ * in the bpf object file.
+ */
+struct bpf_map *
+bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset);
+
 struct bpf_map *
 bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
 #define bpf_map__for_each(pos, obj)\
-- 
2.10.1



[PATCH v3 11/30] perf clang: Use real file system for #include

2016-11-25 Thread Wang Nan
Utilize clang's OverlayFileSystem facility, allow CompilerInstance to
access real file system.

With this patch '#include' directive can be used.

Add a new getModuleFromSource for real file.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 44 +++
 tools/perf/util/c++/clang.h   |  3 +++
 2 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index c17b117..cf96199 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -15,6 +15,7 @@
 #include "clang/Tooling/Tooling.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/ManagedStatic.h"
 #include 
 
@@ -27,14 +28,6 @@ static std::unique_ptr LLVMCtx;
 
 using namespace clang;
 
-static vfs::InMemoryFileSystem *
-buildVFS(StringRef& Name, StringRef& Content)
-{
-   vfs::InMemoryFileSystem *VFS = new vfs::InMemoryFileSystem(true);
-   VFS->addFile(Twine(Name), 0, llvm::MemoryBuffer::getMemBuffer(Content));
-   return VFS;
-}
-
 static CompilerInvocation *
 createCompilerInvocation(StringRef& Path, DiagnosticsEngine& Diags)
 {
@@ -60,17 +53,17 @@ createCompilerInvocation(StringRef& Path, 
DiagnosticsEngine& Diags)
return CI;
 }
 
-std::unique_ptr
-getModuleFromSource(StringRef Name, StringRef Content)
+static std::unique_ptr
+getModuleFromSource(StringRef Path,
+   IntrusiveRefCntPtr VFS)
 {
CompilerInstance Clang;
Clang.createDiagnostics();
 
-   IntrusiveRefCntPtr VFS = buildVFS(Name, Content);
Clang.setVirtualFileSystem(&*VFS);
 
IntrusiveRefCntPtr CI =
-   createCompilerInvocation(Name, Clang.getDiagnostics());
+   createCompilerInvocation(Path, Clang.getDiagnostics());
Clang.setInvocation(&*CI);
 
std::unique_ptr Act(new EmitLLVMOnlyAction(&*LLVMCtx));
@@ -80,6 +73,33 @@ getModuleFromSource(StringRef Name, StringRef Content)
return Act->takeModule();
 }
 
+std::unique_ptr
+getModuleFromSource(StringRef Name, StringRef Content)
+{
+   using namespace vfs;
+
+   llvm::IntrusiveRefCntPtr OverlayFS(
+   new OverlayFileSystem(getRealFileSystem()));
+   llvm::IntrusiveRefCntPtr MemFS(
+   new InMemoryFileSystem(true));
+
+   /*
+* pushOverlay helps setting working dir for MemFS. Must call
+* before addFile.
+*/
+   OverlayFS->pushOverlay(MemFS);
+   MemFS->addFile(Twine(Name), 0, 
llvm::MemoryBuffer::getMemBuffer(Content));
+
+   return getModuleFromSource(Name, OverlayFS);
+}
+
+std::unique_ptr
+getModuleFromSource(StringRef Path)
+{
+   IntrusiveRefCntPtr VFS(vfs::getRealFileSystem());
+   return getModuleFromSource(Path, VFS);
+}
+
 }
 
 extern "C" {
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index f64483b..90aff01 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -12,5 +12,8 @@ using namespace llvm;
 std::unique_ptr
 getModuleFromSource(StringRef Name, StringRef Content);
 
+std::unique_ptr
+getModuleFromSource(StringRef Path);
+
 }
 #endif
-- 
2.10.1



[PATCH v3 19/30] perf clang jit: Insignt BPF and JIT functions in a Module

2016-11-25 Thread Wang Nan
Identify BPF functions, JIT functions and maps during init. Functions in
section starting with "perfhook:" are JIT functions. They will be JIT
compiled and hooked at perfhooks.

During init of PerfModule, mark JIT functions as AvailableExternallyLinkage.
LLVM skips functions with linkage like this so they won't be compiled
into BPF objects.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 32 
 tools/perf/util/c++/clang.h   |  7 +++
 2 files changed, 39 insertions(+)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index d31b0a5..98d05e2 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -115,15 +115,47 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, 
StringRef Path)
 
 PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M))
 {
+   for (llvm::Function& F : *Module) {
+   if (F.getLinkage() != llvm::GlobalValue::ExternalLinkage)
+   continue;
+
+   if (StringRef(F.getSection()).startswith("perfhook:"))
+   JITFunctions.insert();
+   else
+   BPFFunctions.insert();
+   }
 
+   for (auto V = Module->global_begin(); V != Module->global_end(); V++) {
+   llvm::GlobalVariable *GV = &*V;
+   if (StringRef(GV->getSection()) == llvm::StringRef("maps"))
+   Maps.insert(GV);
+   }
 }
 
+void PerfModule::prepareBPF(void)
+{
+   for (llvm::Function *F : JITFunctions)
+   F->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
+   for (llvm::Function *F : BPFFunctions)
+   F->setLinkage(llvm::GlobalValue::ExternalLinkage);
+
+}
+
+void PerfModule::prepareJIT(void)
+{
+   for (llvm::Function *F : BPFFunctions)
+   F->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
+   for (llvm::Function *F : JITFunctions)
+   F->setLinkage(llvm::GlobalValue::ExternalLinkage);
+
+}
 
 std::unique_ptr
 PerfModule::toBPFObject(void)
 {
using namespace llvm;
 
+   prepareBPF();
std::string TargetTriple("bpf-pc-linux");
std::string Error;
const Target* Target = TargetRegistry::lookupTarget(TargetTriple, 
Error);
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index cbb291b..1eb71a6 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -6,6 +6,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
 #include 
+#include 
 
 namespace perf {
 
@@ -14,6 +15,12 @@ using namespace llvm;
 class PerfModule {
 private:
std::unique_ptr Module;
+
+   std::set Maps;
+   std::set BPFFunctions;
+   std::set JITFunctions;
+   void prepareBPF(void);
+   void prepareJIT(void);
 public:
inline llvm::Module *getModule(void)
{
-- 
2.10.1



[PATCH v3 06/30] perf llvm: Extract helpers in llvm-utils.c

2016-11-25 Thread Wang Nan
Following commits will use builtin clang to compile BPF script.
llvm__get_kbuild_opts() and llvm__get_nr_cpus() are extracted to help
building '-DKERNEL_VERSION_CODE' and '-D__NR_CPUS__' macros.

Doing object dumping in bpf loader, so futher builtin clang compiling
needn't consider it.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c |  4 +++
 tools/perf/util/llvm-utils.c | 76 +---
 tools/perf/util/llvm-utils.h |  6 
 3 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a5fd275..cf16b941 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -90,6 +90,10 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
if (err)
return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
+
+   if (!IS_ERR(obj) && llvm_param.dump_obj)
+   llvm__dump_obj(filename, obj_buf, obj_buf_sz);
+
free(obj_buf);
} else
obj = bpf_object__open(filename);
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 27b6f303..b23ff44 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "debug.h"
 #include "llvm-utils.h"
 #include "config.h"
@@ -282,9 +283,10 @@ static const char *kinc_fetch_script =
 "rm -rf $TMPDIR\n"
 "exit $RET\n";
 
-static inline void
-get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
+void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
 {
+   static char *saved_kbuild_dir;
+   static char *saved_kbuild_include_opts;
int err;
 
if (!kbuild_dir || !kbuild_include_opts)
@@ -293,10 +295,28 @@ get_kbuild_opts(char **kbuild_dir, char 
**kbuild_include_opts)
*kbuild_dir = NULL;
*kbuild_include_opts = NULL;
 
+   if (saved_kbuild_dir && saved_kbuild_include_opts &&
+   !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) {
+   *kbuild_dir = strdup(saved_kbuild_dir);
+   *kbuild_include_opts = strdup(saved_kbuild_include_opts);
+
+   if (*kbuild_dir && *kbuild_include_opts)
+   return;
+
+   zfree(kbuild_dir);
+   zfree(kbuild_include_opts);
+   /*
+* Don't fall through: it may breaks saved_kbuild_dir and
+* saved_kbuild_include_opts if detect them again when
+* memory is low.
+*/
+   return;
+   }
+
if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n");
pr_debug("Skip kbuild options detection.\n");
-   return;
+   goto errout;
}
 
err = detect_kbuild_dir(kbuild_dir);
@@ -306,7 +326,7 @@ get_kbuild_opts(char **kbuild_dir, char 
**kbuild_include_opts)
 "Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n"
 " \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n"
 " \tdetection.\n\n");
-   return;
+   goto errout;
}
 
pr_debug("Kernel build dir is set to %s\n", *kbuild_dir);
@@ -325,14 +345,43 @@ get_kbuild_opts(char **kbuild_dir, char 
**kbuild_include_opts)
 
free(*kbuild_dir);
*kbuild_dir = NULL;
-   return;
+   goto errout;
}
 
pr_debug("include option is set to %s\n", *kbuild_include_opts);
+
+   saved_kbuild_dir = strdup(*kbuild_dir);
+   saved_kbuild_include_opts = strdup(*kbuild_include_opts);
+
+   if (!saved_kbuild_dir || !saved_kbuild_include_opts) {
+   zfree(_kbuild_dir);
+   zfree(_kbuild_include_opts);
+   }
+   return;
+errout:
+   saved_kbuild_dir = ERR_PTR(-EINVAL);
+   saved_kbuild_include_opts = ERR_PTR(-EINVAL);
 }
 
-static void
-dump_obj(const char *path, void *obj_buf, size_t size)
+int llvm__get_nr_cpus(void)
+{
+   static int nr_cpus_avail = 0;
+   char serr[STRERR_BUFSIZE];
+
+   if (nr_cpus_avail > 0)
+   return nr_cpus_avail;
+
+   nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
+   if (nr_cpus_avail <= 0) {
+   pr_err(
+"WARNING:\tunable to get available CPUs in this system: %s\n"
+"\tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr)));
+   nr_cpus_avail = 128;
+   }
+   return nr_cpus_avail;
+}
+
+void llvm__dump_obj(const 

[PATCH v3 17/30] perf clang: Pass CFLAGS to builtin clang

2016-11-25 Thread Wang Nan
Pass -DLINUX_VERSION_CODE, -D__NR_CPUS__, llvm.clang-opt config options
and CFLAGS detected by kbuild detector to builtin clang so BPF scripts
can use kernel headers and user defined options like external clang
compiler.

Test:
  # perf record -v --dry-run -e tools/perf/tests/bpf-script-test-kbuild.c ls 
2>&1 | grep built
  bpf: builtin compiling successful

Committer notes:

Before installing the required clang/llvm devel files to have it
builtin:

  # perf record -v --dry-run -e tools/perf/tests/bpf-script-test-kbuild.c ls 
2>&1 | grep built
  bpf: builtin compiling failed: -95, try external compiler

I.e. it falls back to using the external compiler.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 105 --
 tools/perf/util/llvm-utils.h  |   9 +++-
 2 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 610f1cf..3a3b9791 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -27,6 +27,8 @@
 
 #include "clang.h"
 #include "clang-c.h"
+#include "llvm-utils.h"
+#include "util-cxx.h"
 
 namespace perf {
 
@@ -147,6 +149,101 @@ getBPFObjectFromModule(llvm::Module *Module)
return std::move(Buffer);
 }
 
+class ClangOptions {
+   llvm::SmallString FileName;
+   llvm::SmallString<64> KVerDef;
+   llvm::SmallString<64> NRCpusDef;
+   char *kbuild_dir;
+   char *kbuild_include_opts;
+   char *clang_opt;
+public:
+   ClangOptions(const char *filename) : FileName(filename),
+KVerDef(""),
+NRCpusDef(""),
+kbuild_dir(NULL),
+kbuild_include_opts(NULL),
+clang_opt(NULL)
+   {
+   llvm::sys::fs::make_absolute(FileName);
+
+   unsigned int kver;
+   if (!fetch_kernel_version(, NULL, 0))
+   KVerDef = "-DLINUX_VERSION_CODE=" + 
std::to_string(kver);
+
+   int nr_cpus = llvm__get_nr_cpus();
+   if (nr_cpus > 0)
+   NRCpusDef = "-D__NR_CPUS__=" + std::to_string(nr_cpus);
+
+   if (llvm_param.clang_opt)
+   clang_opt = strdup(llvm_param.clang_opt);
+
+   llvm__get_kbuild_opts(_dir, _include_opts);
+   if (!kbuild_dir || !kbuild_include_opts) {
+   free(kbuild_dir);
+   free(kbuild_include_opts);
+   kbuild_dir = kbuild_include_opts = NULL;
+   }
+   }
+
+   ~ClangOptions()
+   {
+   free(kbuild_dir);
+   free(kbuild_include_opts);
+   free(clang_opt);
+   }
+
+   static void fillCFlagsFromString(opt::ArgStringList , char *s, 
bool check = false)
+   {
+   if (!s)
+   return;
+
+   SmallVector Terms;
+   StringRef Opts(s);
+   Opts.split(Terms, ' ');
+
+   for (auto i = Terms.begin(); i != Terms.end(); i++)
+   s[i->end() - Opts.begin()] = '\0';
+
+   for (auto i = Terms.begin(); i != Terms.end(); i++) {
+   if (!check) {
+   CFlags.push_back(i->begin());
+   continue;
+   }
+
+   if (i->startswith("-I"))
+   CFlags.push_back(i->begin());
+   else if (i->startswith("-D"))
+   CFlags.push_back(i->begin());
+   else if (*i == "-include") {
+   CFlags.push_back((i++)->begin());
+   /* Let clang report this error */
+   if (i == Terms.end())
+   break;
+   CFlags.push_back(i->begin());
+   }
+   }
+   }
+
+   void getCFlags(opt::ArgStringList )
+   {
+   CFlags.push_back(KVerDef.c_str());
+   CFlags.push_back(NRCpusDef.c_str());
+
+   fillCFlagsFromString(CFlags, clang_opt);
+   fillCFlagsFromString(CFlags, kbuild_include_opts, true);
+
+   if (kbuild_dir) {
+   CFlags.push_back("-working-directory");
+   CFlags.push_back(kbuild_dir);
+   }
+   }
+
+   const char *getFileName(void)
+   {
+   return FileName.c_str();
+   }
+};
+
 }
 
 extern "C" {
@@ -174,11 

[PATCH v3 19/30] perf clang jit: Insignt BPF and JIT functions in a Module

2016-11-25 Thread Wang Nan
Identify BPF functions, JIT functions and maps during init. Functions in
section starting with "perfhook:" are JIT functions. They will be JIT
compiled and hooked at perfhooks.

During init of PerfModule, mark JIT functions as AvailableExternallyLinkage.
LLVM skips functions with linkage like this so they won't be compiled
into BPF objects.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 32 
 tools/perf/util/c++/clang.h   |  7 +++
 2 files changed, 39 insertions(+)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index d31b0a5..98d05e2 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -115,15 +115,47 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, 
StringRef Path)
 
 PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M))
 {
+   for (llvm::Function& F : *Module) {
+   if (F.getLinkage() != llvm::GlobalValue::ExternalLinkage)
+   continue;
+
+   if (StringRef(F.getSection()).startswith("perfhook:"))
+   JITFunctions.insert();
+   else
+   BPFFunctions.insert();
+   }
 
+   for (auto V = Module->global_begin(); V != Module->global_end(); V++) {
+   llvm::GlobalVariable *GV = &*V;
+   if (StringRef(GV->getSection()) == llvm::StringRef("maps"))
+   Maps.insert(GV);
+   }
 }
 
+void PerfModule::prepareBPF(void)
+{
+   for (llvm::Function *F : JITFunctions)
+   F->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
+   for (llvm::Function *F : BPFFunctions)
+   F->setLinkage(llvm::GlobalValue::ExternalLinkage);
+
+}
+
+void PerfModule::prepareJIT(void)
+{
+   for (llvm::Function *F : BPFFunctions)
+   F->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
+   for (llvm::Function *F : JITFunctions)
+   F->setLinkage(llvm::GlobalValue::ExternalLinkage);
+
+}
 
 std::unique_ptr>
 PerfModule::toBPFObject(void)
 {
using namespace llvm;
 
+   prepareBPF();
std::string TargetTriple("bpf-pc-linux");
std::string Error;
const Target* Target = TargetRegistry::lookupTarget(TargetTriple, 
Error);
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
index cbb291b..1eb71a6 100644
--- a/tools/perf/util/c++/clang.h
+++ b/tools/perf/util/c++/clang.h
@@ -6,6 +6,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
 #include 
+#include 
 
 namespace perf {
 
@@ -14,6 +15,12 @@ using namespace llvm;
 class PerfModule {
 private:
std::unique_ptr Module;
+
+   std::set Maps;
+   std::set BPFFunctions;
+   std::set JITFunctions;
+   void prepareBPF(void);
+   void prepareJIT(void);
 public:
inline llvm::Module *getModule(void)
{
-- 
2.10.1



[PATCH v3 06/30] perf llvm: Extract helpers in llvm-utils.c

2016-11-25 Thread Wang Nan
Following commits will use builtin clang to compile BPF script.
llvm__get_kbuild_opts() and llvm__get_nr_cpus() are extracted to help
building '-DKERNEL_VERSION_CODE' and '-D__NR_CPUS__' macros.

Doing object dumping in bpf loader, so futher builtin clang compiling
needn't consider it.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c |  4 +++
 tools/perf/util/llvm-utils.c | 76 +---
 tools/perf/util/llvm-utils.h |  6 
 3 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index a5fd275..cf16b941 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -90,6 +90,10 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
if (err)
return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
+
+   if (!IS_ERR(obj) && llvm_param.dump_obj)
+   llvm__dump_obj(filename, obj_buf, obj_buf_sz);
+
free(obj_buf);
} else
obj = bpf_object__open(filename);
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 27b6f303..b23ff44 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "debug.h"
 #include "llvm-utils.h"
 #include "config.h"
@@ -282,9 +283,10 @@ static const char *kinc_fetch_script =
 "rm -rf $TMPDIR\n"
 "exit $RET\n";
 
-static inline void
-get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
+void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
 {
+   static char *saved_kbuild_dir;
+   static char *saved_kbuild_include_opts;
int err;
 
if (!kbuild_dir || !kbuild_include_opts)
@@ -293,10 +295,28 @@ get_kbuild_opts(char **kbuild_dir, char 
**kbuild_include_opts)
*kbuild_dir = NULL;
*kbuild_include_opts = NULL;
 
+   if (saved_kbuild_dir && saved_kbuild_include_opts &&
+   !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) {
+   *kbuild_dir = strdup(saved_kbuild_dir);
+   *kbuild_include_opts = strdup(saved_kbuild_include_opts);
+
+   if (*kbuild_dir && *kbuild_include_opts)
+   return;
+
+   zfree(kbuild_dir);
+   zfree(kbuild_include_opts);
+   /*
+* Don't fall through: it may breaks saved_kbuild_dir and
+* saved_kbuild_include_opts if detect them again when
+* memory is low.
+*/
+   return;
+   }
+
if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n");
pr_debug("Skip kbuild options detection.\n");
-   return;
+   goto errout;
}
 
err = detect_kbuild_dir(kbuild_dir);
@@ -306,7 +326,7 @@ get_kbuild_opts(char **kbuild_dir, char 
**kbuild_include_opts)
 "Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n"
 " \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n"
 " \tdetection.\n\n");
-   return;
+   goto errout;
}
 
pr_debug("Kernel build dir is set to %s\n", *kbuild_dir);
@@ -325,14 +345,43 @@ get_kbuild_opts(char **kbuild_dir, char 
**kbuild_include_opts)
 
free(*kbuild_dir);
*kbuild_dir = NULL;
-   return;
+   goto errout;
}
 
pr_debug("include option is set to %s\n", *kbuild_include_opts);
+
+   saved_kbuild_dir = strdup(*kbuild_dir);
+   saved_kbuild_include_opts = strdup(*kbuild_include_opts);
+
+   if (!saved_kbuild_dir || !saved_kbuild_include_opts) {
+   zfree(_kbuild_dir);
+   zfree(_kbuild_include_opts);
+   }
+   return;
+errout:
+   saved_kbuild_dir = ERR_PTR(-EINVAL);
+   saved_kbuild_include_opts = ERR_PTR(-EINVAL);
 }
 
-static void
-dump_obj(const char *path, void *obj_buf, size_t size)
+int llvm__get_nr_cpus(void)
+{
+   static int nr_cpus_avail = 0;
+   char serr[STRERR_BUFSIZE];
+
+   if (nr_cpus_avail > 0)
+   return nr_cpus_avail;
+
+   nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
+   if (nr_cpus_avail <= 0) {
+   pr_err(
+"WARNING:\tunable to get available CPUs in this system: %s\n"
+"\tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr)));
+   nr_cpus_avail = 128;
+   }
+   return nr_cpus_avail;
+}
+
+void llvm__dump_obj(const char *path, void *obj_buf, size_t size)
 {
char *obj_path = strdup(path);
FILE *fp;
@@ 

[PATCH v3 17/30] perf clang: Pass CFLAGS to builtin clang

2016-11-25 Thread Wang Nan
Pass -DLINUX_VERSION_CODE, -D__NR_CPUS__, llvm.clang-opt config options
and CFLAGS detected by kbuild detector to builtin clang so BPF scripts
can use kernel headers and user defined options like external clang
compiler.

Test:
  # perf record -v --dry-run -e tools/perf/tests/bpf-script-test-kbuild.c ls 
2>&1 | grep built
  bpf: builtin compiling successful

Committer notes:

Before installing the required clang/llvm devel files to have it
builtin:

  # perf record -v --dry-run -e tools/perf/tests/bpf-script-test-kbuild.c ls 
2>&1 | grep built
  bpf: builtin compiling failed: -95, try external compiler

I.e. it falls back to using the external compiler.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 105 --
 tools/perf/util/llvm-utils.h  |   9 +++-
 2 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 610f1cf..3a3b9791 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -27,6 +27,8 @@
 
 #include "clang.h"
 #include "clang-c.h"
+#include "llvm-utils.h"
+#include "util-cxx.h"
 
 namespace perf {
 
@@ -147,6 +149,101 @@ getBPFObjectFromModule(llvm::Module *Module)
return std::move(Buffer);
 }
 
+class ClangOptions {
+   llvm::SmallString FileName;
+   llvm::SmallString<64> KVerDef;
+   llvm::SmallString<64> NRCpusDef;
+   char *kbuild_dir;
+   char *kbuild_include_opts;
+   char *clang_opt;
+public:
+   ClangOptions(const char *filename) : FileName(filename),
+KVerDef(""),
+NRCpusDef(""),
+kbuild_dir(NULL),
+kbuild_include_opts(NULL),
+clang_opt(NULL)
+   {
+   llvm::sys::fs::make_absolute(FileName);
+
+   unsigned int kver;
+   if (!fetch_kernel_version(, NULL, 0))
+   KVerDef = "-DLINUX_VERSION_CODE=" + 
std::to_string(kver);
+
+   int nr_cpus = llvm__get_nr_cpus();
+   if (nr_cpus > 0)
+   NRCpusDef = "-D__NR_CPUS__=" + std::to_string(nr_cpus);
+
+   if (llvm_param.clang_opt)
+   clang_opt = strdup(llvm_param.clang_opt);
+
+   llvm__get_kbuild_opts(_dir, _include_opts);
+   if (!kbuild_dir || !kbuild_include_opts) {
+   free(kbuild_dir);
+   free(kbuild_include_opts);
+   kbuild_dir = kbuild_include_opts = NULL;
+   }
+   }
+
+   ~ClangOptions()
+   {
+   free(kbuild_dir);
+   free(kbuild_include_opts);
+   free(clang_opt);
+   }
+
+   static void fillCFlagsFromString(opt::ArgStringList , char *s, 
bool check = false)
+   {
+   if (!s)
+   return;
+
+   SmallVector Terms;
+   StringRef Opts(s);
+   Opts.split(Terms, ' ');
+
+   for (auto i = Terms.begin(); i != Terms.end(); i++)
+   s[i->end() - Opts.begin()] = '\0';
+
+   for (auto i = Terms.begin(); i != Terms.end(); i++) {
+   if (!check) {
+   CFlags.push_back(i->begin());
+   continue;
+   }
+
+   if (i->startswith("-I"))
+   CFlags.push_back(i->begin());
+   else if (i->startswith("-D"))
+   CFlags.push_back(i->begin());
+   else if (*i == "-include") {
+   CFlags.push_back((i++)->begin());
+   /* Let clang report this error */
+   if (i == Terms.end())
+   break;
+   CFlags.push_back(i->begin());
+   }
+   }
+   }
+
+   void getCFlags(opt::ArgStringList )
+   {
+   CFlags.push_back(KVerDef.c_str());
+   CFlags.push_back(NRCpusDef.c_str());
+
+   fillCFlagsFromString(CFlags, clang_opt);
+   fillCFlagsFromString(CFlags, kbuild_include_opts, true);
+
+   if (kbuild_dir) {
+   CFlags.push_back("-working-directory");
+   CFlags.push_back(kbuild_dir);
+   }
+   }
+
+   const char *getFileName(void)
+   {
+   return FileName.c_str();
+   }
+};
+
 }
 
 extern "C" {
@@ -174,11 +271,11 @@ int perf_clang__compile_bpf(const char *_filename,
if (!p_obj_buf || !p_obj_buf_sz)

Xmas Offer

2016-11-25 Thread Mrs Julie Leach
You are a recipient to Mrs Julie Leach Donation of $3 million USD. Contact ( 
julieleac...@gmail.com ) for claims.


Xmas Offer

2016-11-25 Thread Mrs Julie Leach
You are a recipient to Mrs Julie Leach Donation of $3 million USD. Contact ( 
julieleac...@gmail.com ) for claims.


[PATCH v3 07/30] tools build: Add feature detection for LLVM

2016-11-25 Thread Wang Nan
Check if basic LLVM compiling environment is ready.

Use llvm-config to detect include and library directories. Avoid using
'llvm-config --cxxflags' because its result contain some unwanted flags
like --sysroot (if LLVM is built by yocto).

Use '?=' to set LLVM_CONFIG, so explicitly passing LLVM_CONFIG to make
would override it.

Use 'llvm-config --libs BPF' to check if BPF backend is compiled in.
Since now BPF bytecode is the only required backend, no need to waste
time linking llvm and clang if BPF backend is missing. This also
introduce an implicit requirement that LLVM should be new enough.  Old
LLVM doesn't support BPF backend.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-4-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/build/feature/Makefile  | 8 
 tools/build/feature/test-llvm.cpp | 8 
 2 files changed, 16 insertions(+)
 create mode 100644 tools/build/feature/test-llvm.cpp

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 8f668bc..c09de59 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -55,6 +55,7 @@ FILES := $(addprefix $(OUTPUT),$(FILES))
 CC := $(CROSS_COMPILE)gcc -MD
 CXX := $(CROSS_COMPILE)g++ -MD
 PKG_CONFIG := $(CROSS_COMPILE)pkg-config
+LLVM_CONFIG ?= llvm-config
 
 all: $(FILES)
 
@@ -229,6 +230,13 @@ $(OUTPUT)test-cxx.bin:
 $(OUTPUT)test-jvmti.bin:
$(BUILD)
 
+$(OUTPUT)test-llvm.bin:
+   $(BUILDXX) -std=gnu++11 \
+   -I$(shell $(LLVM_CONFIG) --includedir)  \
+   -L$(shell $(LLVM_CONFIG) --libdir)  \
+   $(shell $(LLVM_CONFIG) --libs Core BPF) \
+   $(shell $(LLVM_CONFIG) --system-libs)
+
 -include $(OUTPUT)*.d
 
 ###
diff --git a/tools/build/feature/test-llvm.cpp 
b/tools/build/feature/test-llvm.cpp
new file mode 100644
index 000..d8d2cee
--- /dev/null
+++ b/tools/build/feature/test-llvm.cpp
@@ -0,0 +1,8 @@
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+int main()
+{
+   llvm::errs() << "Hello World!\n";
+   llvm::llvm_shutdown();
+   return 0;
+}
-- 
2.10.1



[PATCH v3 24/30] perf clang jit: Retrive fd of BPF map from its offset

2016-11-25 Thread Wang Nan
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 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c | 37 +
 tools/perf/util/bpf-loader.h | 19 +++
 2 files changed, 56 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 81c6fed..86aa99b 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
-- 
2.10.1



[PATCH v3 30/30] perf clang jit: Export getpid() to perf hook

2016-11-25 Thread Wang Nan
After this patch perf hooks can retrive pid of perf itself by calling
getpid. It is important for excluding event from perf.

This commit is also an example to show how to export more helpers to
hooked script.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/bpf-helper-str.c | 1 +
 tools/perf/util/c++/clang.cpp| 1 +
 2 files changed, 2 insertions(+)

diff --git a/tools/perf/util/c++/bpf-helper-str.c 
b/tools/perf/util/c++/bpf-helper-str.c
index f4d6d57..1ad6ec0 100644
--- a/tools/perf/util/c++/bpf-helper-str.c
+++ b/tools/perf/util/c++/bpf-helper-str.c
@@ -12,6 +12,7 @@ const char clang_builtin_bpf_helper_str[] =
 "#define SEC(NAME) __attribute__((section(NAME), used))\n"
 "extern int printf(const char *, ...);\n"
 "extern int puts(const char *);\n"
+"extern int getpid(void);\n"
 "extern int perf_map_update_elem(void *, void *, void *, void *, unsigned 
long);\n"
 "extern int perf_map_lookup_elem(void *, void *, void *, void *);\n"
 "extern int perf_map_get_next_key(void *, void *, void *, void *);\n"
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 5c1efe8..213c58f 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -236,6 +236,7 @@ static std::map 
exported_funcs =
EXPORT(test__clang_callback),
EXPORT(printf),
EXPORT(puts),
+   EXPORT(getpid),
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)),
-- 
2.10.1



[PATCH v3 21/30] perf clang jit: Export functions for jitted code

2016-11-25 Thread Wang Nan
After this patch functions attached on perf hooks is allowed to invoke
external functions. Add a testcase for this feature.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/Build|  2 +-
 tools/perf/tests/bpf-script-example.c |  4 
 tools/perf/util/c++/clang-c.h |  2 ++
 tools/perf/util/c++/clang-test.cpp|  9 +
 tools/perf/util/c++/clang.cpp | 17 -
 5 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 6676c2d..d6e6e00 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -49,7 +49,7 @@ $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c 
tests/Build
$(call rule_mkdir)
$(Q)echo '#include ' > $@
$(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@
-   $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
+   $(Q)sed -e 's/\\//g' -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
$(Q)echo ';' >> $@
 
 $(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build
diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index 265036e..ccbc19c 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -48,9 +48,13 @@ char _license[] SEC("license") = "GPL";
 int _version SEC("version") = LINUX_VERSION_CODE;
 
 #ifdef TEST_PERF_HOOK
+extern int printf(const char *fmt, ...);
+extern void test__clang_callback(int x);
 SEC("perfhook:test")
 void hook_test(void)
 {
+   printf("Hello, hook_test\n");
+   test__clang_callback(1234);
return;
 }
 #endif
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 5ebcb41..9f75e41 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -16,6 +16,8 @@ extern int test__clang_to_IR(void);
 extern int test__clang_to_obj(void);
 extern int test__clang_jit(void);
 
+extern void test__clang_callback(int x);
+
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
   size_t *p_obj_buf_sz);
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 2b4aa8d..0bdb807 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -68,6 +68,13 @@ int test__clang_to_obj(void)
return 0;
 }
 
+static int callback_flag;
+
+void test__clang_callback(int x)
+{
+   callback_flag = x;
+}
+
 int test__clang_jit(void)
 {
perf_clang_scope _scope;
@@ -84,6 +91,8 @@ int test__clang_jit(void)
perf_hooks__set_hook(i.first.c_str(), i.second, NULL);
 
perf_hooks__invoke_test();
+   if (callback_flag != 1234)
+   return -1;
return 0;
 }
 
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 03012b2..325fbe4 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -30,6 +30,8 @@
 #include "llvm/Target/TargetOptions.h"
 #include 
 #include 
+#include 
+#include 
 
 #include "clang.h"
 #include "clang-c.h"
@@ -194,6 +196,15 @@ PerfModule::toBPFObject(void)
return std::move(Buffer);
 }
 
+static std::map exported_funcs =
+{
+#define EXPORT(f) {#f, (const void *)}
+   EXPORT(test__clang_callback),
+   EXPORT(printf),
+   EXPORT(puts),
+#undef EXPORT
+};
+
 /*
  * Use a global memory manager so allocated code and data won't be released
  * when object destroy.
@@ -220,7 +231,11 @@ int PerfModule::doJIT(void)
 
auto Resolver = createLambdaResolver(
[](const std::string ) {
-   return RuntimeDyld::SymbolInfo(nullptr);
+   auto i = exported_funcs.find(Name);
+   if (i == exported_funcs.end())
+   return RuntimeDyld::SymbolInfo(nullptr);
+   return 
RuntimeDyld::SymbolInfo((uint64_t)(i->second),
+  
JITSymbolFlags::Exported);
},
[](const std::string ) {
return RuntimeDyld::SymbolInfo(nullptr);
-- 
2.10.1



[PATCH v3 14/30] perf clang: Support compile IR to BPF object and add testcase

2016-11-25 Thread Wang Nan
getBPFObjectFromModule() is introduced to compile LLVM IR(Module)
to BPF object. Add new testcase for it.

Test result:
  $ ./buildperf/perf test -v clang
  51: Test builtin clang support   :
  51.1: Test builtin clang compile C source to IR  :
  --- start ---
  test child forked, pid 21822
  test child finished with 0
   end 
  Test builtin clang support subtest 0: Ok
  51.2: Test builtin clang compile C source to ELF object  :
  --- start ---
  test child forked, pid 21823
  test child finished with 0
   end 
  Test builtin clang support subtest 1: Ok

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/clang.c   |  6 -
 tools/perf/util/c++/clang-c.h  |  1 +
 tools/perf/util/c++/clang-test.cpp | 31 +-
 tools/perf/util/c++/clang.cpp  | 45 ++
 tools/perf/util/c++/clang.h|  3 +++
 5 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
index 57ee160..2964c06 100644
--- a/tools/perf/tests/clang.c
+++ b/tools/perf/tests/clang.c
@@ -12,6 +12,10 @@ static struct {
.func = test__clang_to_IR,
.desc = "Test builtin clang compile C source to IR",
},
+   {
+   .func = test__clang_to_obj,
+   .desc = "Test builtin clang compile C source to ELF object",
+   },
 #endif
 };
 
@@ -33,7 +37,7 @@ int test__clang(int i __maybe_unused)
return TEST_SKIP;
 }
 #else
-int test__clang(int i __maybe_unused)
+int test__clang(int i)
 {
if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
return TEST_FAIL;
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index dcde4b5..22b3936 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -9,6 +9,7 @@ extern void perf_clang__init(void);
 extern void perf_clang__cleanup(void);
 
 extern int test__clang_to_IR(void);
+extern int test__clang_to_obj(void);
 
 #ifdef __cplusplus
 }
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index d84e760..9b11e8c 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -13,15 +13,13 @@ public:
~perf_clang_scope() {perf_clang__cleanup();}
 };
 
-extern "C" {
-
-int test__clang_to_IR(void)
+static std::unique_ptr
+__test__clang_to_IR(void)
 {
-   perf_clang_scope _scope;
unsigned int kernel_version;
 
if (fetch_kernel_version(_version, NULL, 0))
-   return -1;
+   return std::unique_ptr(nullptr);
 
std::string cflag_kver("-DLINUX_VERSION_CODE=" +
std::to_string(kernel_version));
@@ -30,14 +28,35 @@ int test__clang_to_IR(void)
perf::getModuleFromSource({cflag_kver.c_str()},
  "perf-test.c",
  test_llvm__bpf_base_prog);
+   return M;
+}
+
+extern "C" {
+int test__clang_to_IR(void)
+{
+   perf_clang_scope _scope;
 
+   auto M = __test__clang_to_IR();
if (!M)
return -1;
-
for (llvm::Function& F : *M)
if (F.getName() == "bpf_func__SyS_epoll_wait")
return 0;
return -1;
 }
 
+int test__clang_to_obj(void)
+{
+   perf_clang_scope _scope;
+
+   auto M = __test__clang_to_IR();
+   if (!M)
+   return -1;
+
+   auto Buffer = perf::getBPFObjectFromModule(&*M);
+   if (!Buffer)
+   return -1;
+   return 0;
+}
+
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 715ca0a..2a1a75d 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -13,10 +13,15 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
 #include 
 
 #include "clang.h"
@@ -105,12 +110,52 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, 
StringRef Path)
return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
+std::unique_ptr
+getBPFObjectFromModule(llvm::Module *Module)
+{
+   using namespace llvm;
+
+   std::string TargetTriple("bpf-pc-linux");
+   std::string Error;
+   const Target* Target = 

[PATCH v3 16/30] perf clang: Pass full path to builtin clang

2016-11-25 Thread Wang Nan
If clang changes its working directory, relative path passed to
perf_clang__compile_bpf() becomes invalid. Before running clang,
convert it to absolute path so file can be found even working directory
is changed.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 1e97415..610f1cf 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
@@ -164,7 +165,7 @@ void perf_clang__cleanup(void)
llvm::llvm_shutdown();
 }
 
-int perf_clang__compile_bpf(const char *filename,
+int perf_clang__compile_bpf(const char *_filename,
void **p_obj_buf,
size_t *p_obj_buf_sz)
 {
@@ -173,8 +174,11 @@ int perf_clang__compile_bpf(const char *filename,
if (!p_obj_buf || !p_obj_buf_sz)
return -EINVAL;
 
+   llvm::SmallString FileName(_filename);
+   llvm::sys::fs::make_absolute(FileName);
+
llvm::opt::ArgStringList CFlags;
-   auto M = getModuleFromSource(std::move(CFlags), filename);
+   auto M = getModuleFromSource(std::move(CFlags), FileName.data());
if (!M)
return  -EINVAL;
auto O = getBPFObjectFromModule(&*M);
-- 
2.10.1



[PATCH v3 07/30] tools build: Add feature detection for LLVM

2016-11-25 Thread Wang Nan
Check if basic LLVM compiling environment is ready.

Use llvm-config to detect include and library directories. Avoid using
'llvm-config --cxxflags' because its result contain some unwanted flags
like --sysroot (if LLVM is built by yocto).

Use '?=' to set LLVM_CONFIG, so explicitly passing LLVM_CONFIG to make
would override it.

Use 'llvm-config --libs BPF' to check if BPF backend is compiled in.
Since now BPF bytecode is the only required backend, no need to waste
time linking llvm and clang if BPF backend is missing. This also
introduce an implicit requirement that LLVM should be new enough.  Old
LLVM doesn't support BPF backend.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-4-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/build/feature/Makefile  | 8 
 tools/build/feature/test-llvm.cpp | 8 
 2 files changed, 16 insertions(+)
 create mode 100644 tools/build/feature/test-llvm.cpp

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 8f668bc..c09de59 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -55,6 +55,7 @@ FILES := $(addprefix $(OUTPUT),$(FILES))
 CC := $(CROSS_COMPILE)gcc -MD
 CXX := $(CROSS_COMPILE)g++ -MD
 PKG_CONFIG := $(CROSS_COMPILE)pkg-config
+LLVM_CONFIG ?= llvm-config
 
 all: $(FILES)
 
@@ -229,6 +230,13 @@ $(OUTPUT)test-cxx.bin:
 $(OUTPUT)test-jvmti.bin:
$(BUILD)
 
+$(OUTPUT)test-llvm.bin:
+   $(BUILDXX) -std=gnu++11 \
+   -I$(shell $(LLVM_CONFIG) --includedir)  \
+   -L$(shell $(LLVM_CONFIG) --libdir)  \
+   $(shell $(LLVM_CONFIG) --libs Core BPF) \
+   $(shell $(LLVM_CONFIG) --system-libs)
+
 -include $(OUTPUT)*.d
 
 ###
diff --git a/tools/build/feature/test-llvm.cpp 
b/tools/build/feature/test-llvm.cpp
new file mode 100644
index 000..d8d2cee
--- /dev/null
+++ b/tools/build/feature/test-llvm.cpp
@@ -0,0 +1,8 @@
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+int main()
+{
+   llvm::errs() << "Hello World!\n";
+   llvm::llvm_shutdown();
+   return 0;
+}
-- 
2.10.1



[PATCH v3 24/30] perf clang jit: Retrive fd of BPF map from its offset

2016-11-25 Thread Wang Nan
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 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c | 37 +
 tools/perf/util/bpf-loader.h | 19 +++
 2 files changed, 56 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 81c6fed..86aa99b 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
-- 
2.10.1



[PATCH v3 30/30] perf clang jit: Export getpid() to perf hook

2016-11-25 Thread Wang Nan
After this patch perf hooks can retrive pid of perf itself by calling
getpid. It is important for excluding event from perf.

This commit is also an example to show how to export more helpers to
hooked script.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/bpf-helper-str.c | 1 +
 tools/perf/util/c++/clang.cpp| 1 +
 2 files changed, 2 insertions(+)

diff --git a/tools/perf/util/c++/bpf-helper-str.c 
b/tools/perf/util/c++/bpf-helper-str.c
index f4d6d57..1ad6ec0 100644
--- a/tools/perf/util/c++/bpf-helper-str.c
+++ b/tools/perf/util/c++/bpf-helper-str.c
@@ -12,6 +12,7 @@ const char clang_builtin_bpf_helper_str[] =
 "#define SEC(NAME) __attribute__((section(NAME), used))\n"
 "extern int printf(const char *, ...);\n"
 "extern int puts(const char *);\n"
+"extern int getpid(void);\n"
 "extern int perf_map_update_elem(void *, void *, void *, void *, unsigned 
long);\n"
 "extern int perf_map_lookup_elem(void *, void *, void *, void *);\n"
 "extern int perf_map_get_next_key(void *, void *, void *, void *);\n"
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 5c1efe8..213c58f 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -236,6 +236,7 @@ static std::map 
exported_funcs =
EXPORT(test__clang_callback),
EXPORT(printf),
EXPORT(puts),
+   EXPORT(getpid),
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)),
-- 
2.10.1



[PATCH v3 21/30] perf clang jit: Export functions for jitted code

2016-11-25 Thread Wang Nan
After this patch functions attached on perf hooks is allowed to invoke
external functions. Add a testcase for this feature.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/Build|  2 +-
 tools/perf/tests/bpf-script-example.c |  4 
 tools/perf/util/c++/clang-c.h |  2 ++
 tools/perf/util/c++/clang-test.cpp|  9 +
 tools/perf/util/c++/clang.cpp | 17 -
 5 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 6676c2d..d6e6e00 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -49,7 +49,7 @@ $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c 
tests/Build
$(call rule_mkdir)
$(Q)echo '#include ' > $@
$(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@
-   $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
+   $(Q)sed -e 's/\\//g' -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
$(Q)echo ';' >> $@
 
 $(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build
diff --git a/tools/perf/tests/bpf-script-example.c 
b/tools/perf/tests/bpf-script-example.c
index 265036e..ccbc19c 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -48,9 +48,13 @@ char _license[] SEC("license") = "GPL";
 int _version SEC("version") = LINUX_VERSION_CODE;
 
 #ifdef TEST_PERF_HOOK
+extern int printf(const char *fmt, ...);
+extern void test__clang_callback(int x);
 SEC("perfhook:test")
 void hook_test(void)
 {
+   printf("Hello, hook_test\n");
+   test__clang_callback(1234);
return;
 }
 #endif
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 5ebcb41..9f75e41 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -16,6 +16,8 @@ extern int test__clang_to_IR(void);
 extern int test__clang_to_obj(void);
 extern int test__clang_jit(void);
 
+extern void test__clang_callback(int x);
+
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
   size_t *p_obj_buf_sz);
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 2b4aa8d..0bdb807 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -68,6 +68,13 @@ int test__clang_to_obj(void)
return 0;
 }
 
+static int callback_flag;
+
+void test__clang_callback(int x)
+{
+   callback_flag = x;
+}
+
 int test__clang_jit(void)
 {
perf_clang_scope _scope;
@@ -84,6 +91,8 @@ int test__clang_jit(void)
perf_hooks__set_hook(i.first.c_str(), i.second, NULL);
 
perf_hooks__invoke_test();
+   if (callback_flag != 1234)
+   return -1;
return 0;
 }
 
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 03012b2..325fbe4 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -30,6 +30,8 @@
 #include "llvm/Target/TargetOptions.h"
 #include 
 #include 
+#include 
+#include 
 
 #include "clang.h"
 #include "clang-c.h"
@@ -194,6 +196,15 @@ PerfModule::toBPFObject(void)
return std::move(Buffer);
 }
 
+static std::map exported_funcs =
+{
+#define EXPORT(f) {#f, (const void *)}
+   EXPORT(test__clang_callback),
+   EXPORT(printf),
+   EXPORT(puts),
+#undef EXPORT
+};
+
 /*
  * Use a global memory manager so allocated code and data won't be released
  * when object destroy.
@@ -220,7 +231,11 @@ int PerfModule::doJIT(void)
 
auto Resolver = createLambdaResolver(
[](const std::string ) {
-   return RuntimeDyld::SymbolInfo(nullptr);
+   auto i = exported_funcs.find(Name);
+   if (i == exported_funcs.end())
+   return RuntimeDyld::SymbolInfo(nullptr);
+   return 
RuntimeDyld::SymbolInfo((uint64_t)(i->second),
+  
JITSymbolFlags::Exported);
},
[](const std::string ) {
return RuntimeDyld::SymbolInfo(nullptr);
-- 
2.10.1



[PATCH v3 14/30] perf clang: Support compile IR to BPF object and add testcase

2016-11-25 Thread Wang Nan
getBPFObjectFromModule() is introduced to compile LLVM IR(Module)
to BPF object. Add new testcase for it.

Test result:
  $ ./buildperf/perf test -v clang
  51: Test builtin clang support   :
  51.1: Test builtin clang compile C source to IR  :
  --- start ---
  test child forked, pid 21822
  test child finished with 0
   end 
  Test builtin clang support subtest 0: Ok
  51.2: Test builtin clang compile C source to ELF object  :
  --- start ---
  test child forked, pid 21823
  test child finished with 0
   end 
  Test builtin clang support subtest 1: Ok

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/tests/clang.c   |  6 -
 tools/perf/util/c++/clang-c.h  |  1 +
 tools/perf/util/c++/clang-test.cpp | 31 +-
 tools/perf/util/c++/clang.cpp  | 45 ++
 tools/perf/util/c++/clang.h|  3 +++
 5 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
index 57ee160..2964c06 100644
--- a/tools/perf/tests/clang.c
+++ b/tools/perf/tests/clang.c
@@ -12,6 +12,10 @@ static struct {
.func = test__clang_to_IR,
.desc = "Test builtin clang compile C source to IR",
},
+   {
+   .func = test__clang_to_obj,
+   .desc = "Test builtin clang compile C source to ELF object",
+   },
 #endif
 };
 
@@ -33,7 +37,7 @@ int test__clang(int i __maybe_unused)
return TEST_SKIP;
 }
 #else
-int test__clang(int i __maybe_unused)
+int test__clang(int i)
 {
if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table))
return TEST_FAIL;
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index dcde4b5..22b3936 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -9,6 +9,7 @@ extern void perf_clang__init(void);
 extern void perf_clang__cleanup(void);
 
 extern int test__clang_to_IR(void);
+extern int test__clang_to_obj(void);
 
 #ifdef __cplusplus
 }
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index d84e760..9b11e8c 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -13,15 +13,13 @@ public:
~perf_clang_scope() {perf_clang__cleanup();}
 };
 
-extern "C" {
-
-int test__clang_to_IR(void)
+static std::unique_ptr
+__test__clang_to_IR(void)
 {
-   perf_clang_scope _scope;
unsigned int kernel_version;
 
if (fetch_kernel_version(_version, NULL, 0))
-   return -1;
+   return std::unique_ptr(nullptr);
 
std::string cflag_kver("-DLINUX_VERSION_CODE=" +
std::to_string(kernel_version));
@@ -30,14 +28,35 @@ int test__clang_to_IR(void)
perf::getModuleFromSource({cflag_kver.c_str()},
  "perf-test.c",
  test_llvm__bpf_base_prog);
+   return M;
+}
+
+extern "C" {
+int test__clang_to_IR(void)
+{
+   perf_clang_scope _scope;
 
+   auto M = __test__clang_to_IR();
if (!M)
return -1;
-
for (llvm::Function& F : *M)
if (F.getName() == "bpf_func__SyS_epoll_wait")
return 0;
return -1;
 }
 
+int test__clang_to_obj(void)
+{
+   perf_clang_scope _scope;
+
+   auto M = __test__clang_to_IR();
+   if (!M)
+   return -1;
+
+   auto Buffer = perf::getBPFObjectFromModule(&*M);
+   if (!Buffer)
+   return -1;
+   return 0;
+}
+
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 715ca0a..2a1a75d 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -13,10 +13,15 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
 #include 
 
 #include "clang.h"
@@ -105,12 +110,52 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, 
StringRef Path)
return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
+std::unique_ptr>
+getBPFObjectFromModule(llvm::Module *Module)
+{
+   using namespace llvm;
+
+   std::string TargetTriple("bpf-pc-linux");
+   std::string Error;
+   const Target* Target = TargetRegistry::lookupTarget(TargetTriple, 
Error);
+   if (!Target) {
+   llvm::errs() << Error;
+   return 

[PATCH v3 16/30] perf clang: Pass full path to builtin clang

2016-11-25 Thread Wang Nan
If clang changes its working directory, relative path passed to
perf_clang__compile_bpf() becomes invalid. Before running clang,
convert it to absolute path so file can be found even working directory
is changed.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/c++/clang.cpp | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 1e97415..610f1cf 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Option/Option.h"
@@ -164,7 +165,7 @@ void perf_clang__cleanup(void)
llvm::llvm_shutdown();
 }
 
-int perf_clang__compile_bpf(const char *filename,
+int perf_clang__compile_bpf(const char *_filename,
void **p_obj_buf,
size_t *p_obj_buf_sz)
 {
@@ -173,8 +174,11 @@ int perf_clang__compile_bpf(const char *filename,
if (!p_obj_buf || !p_obj_buf_sz)
return -EINVAL;
 
+   llvm::SmallString FileName(_filename);
+   llvm::sys::fs::make_absolute(FileName);
+
llvm::opt::ArgStringList CFlags;
-   auto M = getModuleFromSource(std::move(CFlags), filename);
+   auto M = getModuleFromSource(std::move(CFlags), FileName.data());
if (!M)
return  -EINVAL;
auto O = getBPFObjectFromModule(&*M);
-- 
2.10.1



[PATCH v3 23/30] perf clang jit: Collect the lowest address in maps section as map_base

2016-11-25 Thread Wang Nan
During jitting, find the lowest address in maps section and store its
value to _map_base. Pass its value out through perf_clang__compile_bpf().
map_base is useful for jitted functions accessing BPF maps.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c  | 39 +--
 tools/perf/util/c++/clang-c.h |  6 --
 tools/perf/util/c++/clang.cpp | 15 +--
 tools/perf/util/c++/clang.h   |  5 +
 4 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index e50045f..81c6fed 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -47,6 +47,10 @@ struct bpf_prog_priv {
int *type_mapping;
 };
 
+struct bpf_obj_priv {
+   void *map_base;
+};
+
 static bool libbpf_initialized;
 
 struct bpf_object *
@@ -70,9 +74,20 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, 
const char *name)
return obj;
 }
 
+static void
+clear_obj_priv(struct bpf_object *obj __maybe_unused,
+  void *_priv)
+{
+   struct bpf_obj_priv *priv = _priv;
+
+   free(priv);
+}
+
 struct bpf_object *bpf__prepare_load(const char *filename, bool source)
 {
struct bpf_object *obj;
+   void *map_base = NULL;
+   int err;
 
if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning,
@@ -82,14 +97,14 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
}
 
if (source) {
-   int err;
void *obj_buf;
size_t obj_buf_sz;
jitted_funcs_map_t jitted_funcs_map;
 
perf_clang__init();
err = perf_clang__compile_bpf(filename, _buf,
- _buf_sz, _funcs_map);
+ _buf_sz, _funcs_map,
+ _base);
perf_clang__cleanup();
if (err) {
pr_warning("bpf: builtin compiling failed: %d, try 
external compiler\n", err);
@@ -119,7 +134,27 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
return obj;
}
 
+   if (map_base) {
+   struct bpf_obj_priv *priv = calloc(sizeof(*priv), 1);
+
+   if (!priv) {
+   pr_debug("bpf: failed to alloc priv for object\n");
+   err = -ENOMEM;
+   goto errout;
+   }
+   priv->map_base = map_base;
+
+   err = bpf_object__set_priv(obj, priv, clear_obj_priv);
+   if (err) {
+   pr_debug("Failed to set priv for object '%s'\n", 
filename);
+   goto errout;
+   }
+   }
+
return obj;
+errout:
+   bpf_object__close(obj);
+   return ERR_PTR(err);
 }
 
 void bpf__clear(void)
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 021b1ad..4cf651b 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -22,7 +22,8 @@ extern void test__clang_callback(int x);
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
   size_t *p_obj_buf_sz,
-  jitted_funcs_map_t *p_funcs_map);
+  jitted_funcs_map_t *p_funcs_map,
+  void **p_map_base);
 
 extern int
 perf_clang__hook_jitted_func(jitted_funcs_map_t map, void *ctx, bool is_err);
@@ -40,7 +41,8 @@ static inline int
 perf_clang__compile_bpf(const char *filename __maybe_unused,
void **p_obj_buf __maybe_unused,
size_t *p_obj_buf_sz __maybe_unused,
-   jitted_funcs_map_t *p_funcs_map __maybe_unused)
+   jitted_funcs_map_t *p_funcs_map __maybe_unused,
+   void **p_map_base __maybe_unused)
 {
return -ENOTSUP;
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index f2608f5..f8ea9bd 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -122,7 +122,7 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, 
StringRef Path)
return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
-PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M))
+PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M)), _map_base(NULL)
 {
for (llvm::Function& F : *Module) {
if (F.getLinkage() != llvm::GlobalValue::ExternalLinkage)
@@ -247,6 +247,13 @@ int PerfModule::doJIT(void)
  

[PATCH v3 04/30] perf tools: Introduce perf hooks

2016-11-25 Thread Wang Nan
Perf hooks allow hooking user code at perf events. They can be used for
manipulation of BPF maps, taking snapshot and reporting results. In this
patch two perf hook points are introduced: record_start and record_end.

To avoid buggy user actions, a SIGSEGV signal handler is introduced into
'perf record'. It turns off perf hook if it causes a segfault and report
an error to help debugging.

A test case for perf hook is introduced.

Test result:
  $ ./buildperf/perf test -v hook
  50: Test perf hooks  :
  --- start ---
  test child forked, pid 10311
  SIGSEGV is observed as expected, try to recover.
  Fatal error (SEGFAULT) in perf hook 'test'
  test child finished with 0
   end 
  Test perf hooks: Ok

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
---
 tools/perf/builtin-record.c   | 11 +
 tools/perf/tests/Build|  1 +
 tools/perf/tests/builtin-test.c   |  4 ++
 tools/perf/tests/perf-hooks.c | 44 
 tools/perf/tests/tests.h  |  1 +
 tools/perf/util/Build |  2 +
 tools/perf/util/perf-hooks-list.h |  3 ++
 tools/perf/util/perf-hooks.c  | 84 +++
 tools/perf/util/perf-hooks.h  | 37 +
 9 files changed, 187 insertions(+)
 create mode 100644 tools/perf/tests/perf-hooks.c
 create mode 100644 tools/perf/util/perf-hooks-list.h
 create mode 100644 tools/perf/util/perf-hooks.c
 create mode 100644 tools/perf/util/perf-hooks.h

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 67d2a90..fa26865 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -37,6 +37,7 @@
 #include "util/llvm-utils.h"
 #include "util/bpf-loader.h"
 #include "util/trigger.h"
+#include "util/perf-hooks.h"
 #include "asm/bug.h"
 
 #include 
@@ -206,6 +207,12 @@ static void sig_handler(int sig)
done = 1;
 }
 
+static void sigsegv_handler(int sig)
+{
+   perf_hooks__recover();
+   sighandler_dump_stack(sig);
+}
+
 static void record__sig_exit(void)
 {
if (signr == -1)
@@ -833,6 +840,7 @@ static int __cmd_record(struct record *rec, int argc, const 
char **argv)
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
+   signal(SIGSEGV, sigsegv_handler);
 
if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
signal(SIGUSR2, snapshot_sig_handler);
@@ -970,6 +978,7 @@ static int __cmd_record(struct record *rec, int argc, const 
char **argv)
 
trigger_ready(_snapshot_trigger);
trigger_ready(_output_trigger);
+   perf_hooks__invoke_record_start();
for (;;) {
unsigned long long hits = rec->samples;
 
@@ -1114,6 +1123,8 @@ static int __cmd_record(struct record *rec, int argc, 
const char **argv)
}
}
 
+   perf_hooks__invoke_record_end();
+
if (!err && !quiet) {
char samples[128];
const char *postfix = rec->timestamp_filename ?
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 8a4ce49..af3ec94 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -42,6 +42,7 @@ perf-y += backward-ring-buffer.o
 perf-y += sdt.o
 perf-y += is_printable_array.o
 perf-y += bitmap.o
+perf-y += perf-hooks.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 778668a..dab83f7 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -230,6 +230,10 @@ static struct test generic_tests[] = {
.func = test__bitmap_print,
},
{
+   .desc = "Test perf hooks",
+   .func = test__perf_hooks,
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
new file mode 100644
index 000..9338cb2
--- /dev/null
+++ b/tools/perf/tests/perf-hooks.c
@@ -0,0 +1,44 @@
+#include 
+#include 
+
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "perf-hooks.h"
+
+static void sigsegv_handler(int sig __maybe_unused)
+{
+   pr_debug("SIGSEGV is observed as expected, try to recover.\n");
+   perf_hooks__recover();
+   signal(SIGSEGV, SIG_DFL);
+   raise(SIGSEGV);
+   exit(-1);
+}
+
+static int hook_flags;
+
+static void the_hook(void)
+{
+   int *p = NULL;
+
+   hook_flags = 1234;
+
+   /* Generate a segfault, test perf_hooks__recover */
+   *p = 0;
+}
+
+int test__perf_hooks(int subtest __maybe_unused)
+{
+   signal(SIGSEGV, sigsegv_handler);
+   perf_hooks__set_hook("test", the_hook);
+   perf_hooks__invoke_test();
+
+   /* hook 

[PATCH v3 23/30] perf clang jit: Collect the lowest address in maps section as map_base

2016-11-25 Thread Wang Nan
During jitting, find the lowest address in maps section and store its
value to _map_base. Pass its value out through perf_clang__compile_bpf().
map_base is useful for jitted functions accessing BPF maps.

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c  | 39 +--
 tools/perf/util/c++/clang-c.h |  6 --
 tools/perf/util/c++/clang.cpp | 15 +--
 tools/perf/util/c++/clang.h   |  5 +
 4 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index e50045f..81c6fed 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -47,6 +47,10 @@ struct bpf_prog_priv {
int *type_mapping;
 };
 
+struct bpf_obj_priv {
+   void *map_base;
+};
+
 static bool libbpf_initialized;
 
 struct bpf_object *
@@ -70,9 +74,20 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, 
const char *name)
return obj;
 }
 
+static void
+clear_obj_priv(struct bpf_object *obj __maybe_unused,
+  void *_priv)
+{
+   struct bpf_obj_priv *priv = _priv;
+
+   free(priv);
+}
+
 struct bpf_object *bpf__prepare_load(const char *filename, bool source)
 {
struct bpf_object *obj;
+   void *map_base = NULL;
+   int err;
 
if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning,
@@ -82,14 +97,14 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
}
 
if (source) {
-   int err;
void *obj_buf;
size_t obj_buf_sz;
jitted_funcs_map_t jitted_funcs_map;
 
perf_clang__init();
err = perf_clang__compile_bpf(filename, _buf,
- _buf_sz, _funcs_map);
+ _buf_sz, _funcs_map,
+ _base);
perf_clang__cleanup();
if (err) {
pr_warning("bpf: builtin compiling failed: %d, try 
external compiler\n", err);
@@ -119,7 +134,27 @@ struct bpf_object *bpf__prepare_load(const char *filename, 
bool source)
return obj;
}
 
+   if (map_base) {
+   struct bpf_obj_priv *priv = calloc(sizeof(*priv), 1);
+
+   if (!priv) {
+   pr_debug("bpf: failed to alloc priv for object\n");
+   err = -ENOMEM;
+   goto errout;
+   }
+   priv->map_base = map_base;
+
+   err = bpf_object__set_priv(obj, priv, clear_obj_priv);
+   if (err) {
+   pr_debug("Failed to set priv for object '%s'\n", 
filename);
+   goto errout;
+   }
+   }
+
return obj;
+errout:
+   bpf_object__close(obj);
+   return ERR_PTR(err);
 }
 
 void bpf__clear(void)
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
index 021b1ad..4cf651b 100644
--- a/tools/perf/util/c++/clang-c.h
+++ b/tools/perf/util/c++/clang-c.h
@@ -22,7 +22,8 @@ extern void test__clang_callback(int x);
 extern int perf_clang__compile_bpf(const char *filename,
   void **p_obj_buf,
   size_t *p_obj_buf_sz,
-  jitted_funcs_map_t *p_funcs_map);
+  jitted_funcs_map_t *p_funcs_map,
+  void **p_map_base);
 
 extern int
 perf_clang__hook_jitted_func(jitted_funcs_map_t map, void *ctx, bool is_err);
@@ -40,7 +41,8 @@ static inline int
 perf_clang__compile_bpf(const char *filename __maybe_unused,
void **p_obj_buf __maybe_unused,
size_t *p_obj_buf_sz __maybe_unused,
-   jitted_funcs_map_t *p_funcs_map __maybe_unused)
+   jitted_funcs_map_t *p_funcs_map __maybe_unused,
+   void **p_map_base __maybe_unused)
 {
return -ENOTSUP;
 }
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index f2608f5..f8ea9bd 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -122,7 +122,7 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, 
StringRef Path)
return getModuleFromSource(std::move(CFlags), Path, VFS);
 }
 
-PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M))
+PerfModule::PerfModule(std::unique_ptr&& M) : 
Module(std::move(M)), _map_base(NULL)
 {
for (llvm::Function& F : *Module) {
if (F.getLinkage() != llvm::GlobalValue::ExternalLinkage)
@@ -247,6 +247,13 @@ int PerfModule::doJIT(void)
,
std::move(Resolver));
 
+   void *map_base = NULL;
+   for 

[PATCH v3 04/30] perf tools: Introduce perf hooks

2016-11-25 Thread Wang Nan
Perf hooks allow hooking user code at perf events. They can be used for
manipulation of BPF maps, taking snapshot and reporting results. In this
patch two perf hook points are introduced: record_start and record_end.

To avoid buggy user actions, a SIGSEGV signal handler is introduced into
'perf record'. It turns off perf hook if it causes a segfault and report
an error to help debugging.

A test case for perf hook is introduced.

Test result:
  $ ./buildperf/perf test -v hook
  50: Test perf hooks  :
  --- start ---
  test child forked, pid 10311
  SIGSEGV is observed as expected, try to recover.
  Fatal error (SEGFAULT) in perf hook 'test'
  test child finished with 0
   end 
  Test perf hooks: Ok

Signed-off-by: Wang Nan 
Cc: Arnaldo Carvalho de Melo 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
---
 tools/perf/builtin-record.c   | 11 +
 tools/perf/tests/Build|  1 +
 tools/perf/tests/builtin-test.c   |  4 ++
 tools/perf/tests/perf-hooks.c | 44 
 tools/perf/tests/tests.h  |  1 +
 tools/perf/util/Build |  2 +
 tools/perf/util/perf-hooks-list.h |  3 ++
 tools/perf/util/perf-hooks.c  | 84 +++
 tools/perf/util/perf-hooks.h  | 37 +
 9 files changed, 187 insertions(+)
 create mode 100644 tools/perf/tests/perf-hooks.c
 create mode 100644 tools/perf/util/perf-hooks-list.h
 create mode 100644 tools/perf/util/perf-hooks.c
 create mode 100644 tools/perf/util/perf-hooks.h

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 67d2a90..fa26865 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -37,6 +37,7 @@
 #include "util/llvm-utils.h"
 #include "util/bpf-loader.h"
 #include "util/trigger.h"
+#include "util/perf-hooks.h"
 #include "asm/bug.h"
 
 #include 
@@ -206,6 +207,12 @@ static void sig_handler(int sig)
done = 1;
 }
 
+static void sigsegv_handler(int sig)
+{
+   perf_hooks__recover();
+   sighandler_dump_stack(sig);
+}
+
 static void record__sig_exit(void)
 {
if (signr == -1)
@@ -833,6 +840,7 @@ static int __cmd_record(struct record *rec, int argc, const 
char **argv)
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
+   signal(SIGSEGV, sigsegv_handler);
 
if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
signal(SIGUSR2, snapshot_sig_handler);
@@ -970,6 +978,7 @@ static int __cmd_record(struct record *rec, int argc, const 
char **argv)
 
trigger_ready(_snapshot_trigger);
trigger_ready(_output_trigger);
+   perf_hooks__invoke_record_start();
for (;;) {
unsigned long long hits = rec->samples;
 
@@ -1114,6 +1123,8 @@ static int __cmd_record(struct record *rec, int argc, 
const char **argv)
}
}
 
+   perf_hooks__invoke_record_end();
+
if (!err && !quiet) {
char samples[128];
const char *postfix = rec->timestamp_filename ?
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 8a4ce49..af3ec94 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -42,6 +42,7 @@ perf-y += backward-ring-buffer.o
 perf-y += sdt.o
 perf-y += is_printable_array.o
 perf-y += bitmap.o
+perf-y += perf-hooks.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 778668a..dab83f7 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -230,6 +230,10 @@ static struct test generic_tests[] = {
.func = test__bitmap_print,
},
{
+   .desc = "Test perf hooks",
+   .func = test__perf_hooks,
+   },
+   {
.func = NULL,
},
 };
diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
new file mode 100644
index 000..9338cb2
--- /dev/null
+++ b/tools/perf/tests/perf-hooks.c
@@ -0,0 +1,44 @@
+#include 
+#include 
+
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+#include "perf-hooks.h"
+
+static void sigsegv_handler(int sig __maybe_unused)
+{
+   pr_debug("SIGSEGV is observed as expected, try to recover.\n");
+   perf_hooks__recover();
+   signal(SIGSEGV, SIG_DFL);
+   raise(SIGSEGV);
+   exit(-1);
+}
+
+static int hook_flags;
+
+static void the_hook(void)
+{
+   int *p = NULL;
+
+   hook_flags = 1234;
+
+   /* Generate a segfault, test perf_hooks__recover */
+   *p = 0;
+}
+
+int test__perf_hooks(int subtest __maybe_unused)
+{
+   signal(SIGSEGV, sigsegv_handler);
+   perf_hooks__set_hook("test", the_hook);
+   perf_hooks__invoke_test();
+
+   /* hook is triggered? */
+   if (hook_flags != 1234)
+   return TEST_FAIL;
+
+   

[PATCH v3 13/30] perf clang: Update test case to use real BPF script

2016-11-25 Thread Wang Nan
Allow C++ code to use util.h and tests/llvm.h. Let 'perf test' compile a
real BPF script.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-10-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/Makefile.config | 27 +++
 tools/perf/tests/llvm.h|  7 +++
 tools/perf/util/c++/clang-test.cpp | 17 ++---
 tools/perf/util/util-cxx.h | 26 ++
 4 files changed, 62 insertions(+), 15 deletions(-)
 create mode 100644 tools/perf/util/util-cxx.h

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index b7c9c80..09c2a98 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -212,24 +212,27 @@ ifeq ($(DEBUG),0)
   endif
 endif
 
-CFLAGS += -I$(src-perf)/util/include
-CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
-CFLAGS += -I$(srctree)/tools/include/uapi
-CFLAGS += -I$(srctree)/tools/include/
-CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi
-CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/
-CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/
+INC_FLAGS += -I$(src-perf)/util/include
+INC_FLAGS += -I$(src-perf)/arch/$(ARCH)/include
+INC_FLAGS += -I$(srctree)/tools/include/uapi
+INC_FLAGS += -I$(srctree)/tools/include/
+INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi
+INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/
+INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/
 
 # $(obj-perf)  for generated common-cmds.h
 # $(obj-perf)/util for generated bison/flex headers
 ifneq ($(OUTPUT),)
-CFLAGS += -I$(obj-perf)/util
-CFLAGS += -I$(obj-perf)
+INC_FLAGS += -I$(obj-perf)/util
+INC_FLAGS += -I$(obj-perf)
 endif
 
-CFLAGS += -I$(src-perf)/util
-CFLAGS += -I$(src-perf)
-CFLAGS += -I$(srctree)/tools/lib/
+INC_FLAGS += -I$(src-perf)/util
+INC_FLAGS += -I$(src-perf)
+INC_FLAGS += -I$(srctree)/tools/lib/
+
+CFLAGS   += $(INC_FLAGS)
+CXXFLAGS += $(INC_FLAGS)
 
 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
index 0eaa604..b835717 100644
--- a/tools/perf/tests/llvm.h
+++ b/tools/perf/tests/llvm.h
@@ -1,6 +1,10 @@
 #ifndef PERF_TEST_LLVM_H
 #define PERF_TEST_LLVM_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include  /* for size_t */
 #include  /* for bool */
 
@@ -20,4 +24,7 @@ enum test_llvm__testcase {
 int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz,
 enum test_llvm__testcase index, bool force,
 bool *should_load_fail);
+#ifdef __cplusplus
+}
+#endif
 #endif
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 0f484fb..d84e760 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -3,6 +3,10 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/LLVMContext.h"
 
+#include 
+#include 
+#include 
+
 class perf_clang_scope {
 public:
explicit perf_clang_scope() {perf_clang__init();}
@@ -14,17 +18,24 @@ extern "C" {
 int test__clang_to_IR(void)
 {
perf_clang_scope _scope;
+   unsigned int kernel_version;
+
+   if (fetch_kernel_version(_version, NULL, 0))
+   return -1;
+
+   std::string cflag_kver("-DLINUX_VERSION_CODE=" +
+   std::to_string(kernel_version));
 
std::unique_ptr M =
-   perf::getModuleFromSource({"-DRESULT=1"},
+   perf::getModuleFromSource({cflag_kver.c_str()},
  "perf-test.c",
- "int myfunc(void) {return RESULT;}");
+ test_llvm__bpf_base_prog);
 
if (!M)
return -1;
 
for (llvm::Function& F : *M)
-   if (F.getName() == "myfunc")
+   if (F.getName() == "bpf_func__SyS_epoll_wait")
return 0;
return -1;
 }
diff --git a/tools/perf/util/util-cxx.h b/tools/perf/util/util-cxx.h
new file mode 100644
index 000..0e0e019
--- /dev/null
+++ b/tools/perf/util/util-cxx.h
@@ -0,0 +1,26 @@
+/*
+ * Support C++ source use utilities defined in util.h
+ */
+
+#ifndef PERF_UTIL_UTIL_CXX_H
+#define PERF_UTIL_UTIL_CXX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Now 'new' is the only C++ keyword found in util.h:
+ * in tools/include/linux/rbtree.h
+ *
+ * Other keywords, like class and delete, should be
+ * redefined if necessary.
+ */
+#define new _new
+#include "util.h"
+#undef new
+
+#ifdef __cplusplus
+}
+#endif
+#endif
-- 
2.10.1



[PATCH v3 01/30] tools lib bpf: Add missing BPF functions

2016-11-25 Thread Wang Nan
Add more BPF map operations to libbpf. Also add bpf_obj_{pin,get}(). They
can be used on not only BPF maps but also BPF programs.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Joe Stringer 
Cc: Li Zefan 
---
 tools/lib/bpf/bpf.c | 56 +
 tools/lib/bpf/bpf.h |  7 +++
 2 files changed, 63 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 4212ed6..8143536 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -110,3 +110,59 @@ int bpf_map_update_elem(int fd, void *key, void *value,
 
return sys_bpf(BPF_MAP_UPDATE_ELEM, , sizeof(attr));
 }
+
+int bpf_map_lookup_elem(int fd, void *key, void *value)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.map_fd = fd;
+   attr.key = ptr_to_u64(key);
+   attr.value = ptr_to_u64(value);
+
+   return sys_bpf(BPF_MAP_LOOKUP_ELEM, , sizeof(attr));
+}
+
+int bpf_map_delete_elem(int fd, void *key)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.map_fd = fd;
+   attr.key = ptr_to_u64(key);
+
+   return sys_bpf(BPF_MAP_DELETE_ELEM, , sizeof(attr));
+}
+
+int bpf_map_get_next_key(int fd, void *key, void *next_key)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.map_fd = fd;
+   attr.key = ptr_to_u64(key);
+   attr.next_key = ptr_to_u64(next_key);
+
+   return sys_bpf(BPF_MAP_GET_NEXT_KEY, , sizeof(attr));
+}
+
+int bpf_obj_pin(int fd, const char *pathname)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.pathname = ptr_to_u64((void *)pathname);
+   attr.bpf_fd = fd;
+
+   return sys_bpf(BPF_OBJ_PIN, , sizeof(attr));
+}
+
+int bpf_obj_get(const char *pathname)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.pathname = ptr_to_u64((void *)pathname);
+
+   return sys_bpf(BPF_OBJ_GET, , sizeof(attr));
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index e8ba540..253c3db 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -35,4 +35,11 @@ int bpf_load_program(enum bpf_prog_type type, struct 
bpf_insn *insns,
 
 int bpf_map_update_elem(int fd, void *key, void *value,
u64 flags);
+
+int bpf_map_lookup_elem(int fd, void *key, void *value);
+int bpf_map_delete_elem(int fd, void *key);
+int bpf_map_get_next_key(int fd, void *key, void *next_key);
+int bpf_obj_pin(int fd, const char *pathname);
+int bpf_obj_get(const char *pathname);
+
 #endif
-- 
2.10.1



[PATCH v3 02/30] tools lib bpf: Add private field for bpf_object

2016-11-25 Thread Wang Nan
Similar to other classes defined in libbpf.h (map and program), allow
'object' class has its own private data.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Li Zefan 
---
 tools/lib/bpf/libbpf.c | 23 +++
 tools/lib/bpf/libbpf.h |  5 +
 2 files changed, 28 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 96a2b2f..866d5cd 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -229,6 +229,10 @@ struct bpf_object {
 * all objects.
 */
struct list_head list;
+
+   void *priv;
+   bpf_object_clear_priv_t clear_priv;
+
char path[];
 };
 #define obj_elf_valid(o)   ((o)->efile.elf)
@@ -1229,6 +1233,9 @@ void bpf_object__close(struct bpf_object *obj)
if (!obj)
return;
 
+   if (obj->clear_priv)
+   obj->clear_priv(obj, obj->priv);
+
bpf_object__elf_finish(obj);
bpf_object__unload(obj);
 
@@ -1282,6 +1289,22 @@ unsigned int bpf_object__kversion(struct bpf_object *obj)
return obj ? obj->kern_version : 0;
 }
 
+int bpf_object__set_priv(struct bpf_object *obj, void *priv,
+bpf_object_clear_priv_t clear_priv)
+{
+   if (obj->priv && obj->clear_priv)
+   obj->clear_priv(obj, obj->priv);
+
+   obj->priv = priv;
+   obj->clear_priv = clear_priv;
+   return 0;
+}
+
+void *bpf_object__priv(struct bpf_object *obj)
+{
+   return obj ? obj->priv : ERR_PTR(-EINVAL);
+}
+
 struct bpf_program *
 bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
 {
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index dd7a513..0c0b012 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -79,6 +79,11 @@ struct bpf_object *bpf_object__next(struct bpf_object *prev);
 (pos) != NULL; \
 (pos) = (tmp), (tmp) = bpf_object__next(tmp))
 
+typedef void (*bpf_object_clear_priv_t)(struct bpf_object *, void *);
+int bpf_object__set_priv(struct bpf_object *obj, void *priv,
+bpf_object_clear_priv_t clear_priv);
+void *bpf_object__priv(struct bpf_object *prog);
+
 /* Accessors of bpf_program. */
 struct bpf_program;
 struct bpf_program *bpf_program__next(struct bpf_program *prog,
-- 
2.10.1



[PATCH v3 13/30] perf clang: Update test case to use real BPF script

2016-11-25 Thread Wang Nan
Allow C++ code to use util.h and tests/llvm.h. Let 'perf test' compile a
real BPF script.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: He Kuang 
Cc: Jiri Olsa 
Cc: Zefan Li 
Cc: pi3or...@163.com
Link: 
http://lkml.kernel.org/r/1474874832-134786-10-git-send-email-wangn...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/Makefile.config | 27 +++
 tools/perf/tests/llvm.h|  7 +++
 tools/perf/util/c++/clang-test.cpp | 17 ++---
 tools/perf/util/util-cxx.h | 26 ++
 4 files changed, 62 insertions(+), 15 deletions(-)
 create mode 100644 tools/perf/util/util-cxx.h

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index b7c9c80..09c2a98 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -212,24 +212,27 @@ ifeq ($(DEBUG),0)
   endif
 endif
 
-CFLAGS += -I$(src-perf)/util/include
-CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
-CFLAGS += -I$(srctree)/tools/include/uapi
-CFLAGS += -I$(srctree)/tools/include/
-CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi
-CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/
-CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/
+INC_FLAGS += -I$(src-perf)/util/include
+INC_FLAGS += -I$(src-perf)/arch/$(ARCH)/include
+INC_FLAGS += -I$(srctree)/tools/include/uapi
+INC_FLAGS += -I$(srctree)/tools/include/
+INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi
+INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/
+INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/
 
 # $(obj-perf)  for generated common-cmds.h
 # $(obj-perf)/util for generated bison/flex headers
 ifneq ($(OUTPUT),)
-CFLAGS += -I$(obj-perf)/util
-CFLAGS += -I$(obj-perf)
+INC_FLAGS += -I$(obj-perf)/util
+INC_FLAGS += -I$(obj-perf)
 endif
 
-CFLAGS += -I$(src-perf)/util
-CFLAGS += -I$(src-perf)
-CFLAGS += -I$(srctree)/tools/lib/
+INC_FLAGS += -I$(src-perf)/util
+INC_FLAGS += -I$(src-perf)
+INC_FLAGS += -I$(srctree)/tools/lib/
+
+CFLAGS   += $(INC_FLAGS)
+CXXFLAGS += $(INC_FLAGS)
 
 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
index 0eaa604..b835717 100644
--- a/tools/perf/tests/llvm.h
+++ b/tools/perf/tests/llvm.h
@@ -1,6 +1,10 @@
 #ifndef PERF_TEST_LLVM_H
 #define PERF_TEST_LLVM_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include  /* for size_t */
 #include  /* for bool */
 
@@ -20,4 +24,7 @@ enum test_llvm__testcase {
 int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz,
 enum test_llvm__testcase index, bool force,
 bool *should_load_fail);
+#ifdef __cplusplus
+}
+#endif
 #endif
diff --git a/tools/perf/util/c++/clang-test.cpp 
b/tools/perf/util/c++/clang-test.cpp
index 0f484fb..d84e760 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -3,6 +3,10 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/LLVMContext.h"
 
+#include 
+#include 
+#include 
+
 class perf_clang_scope {
 public:
explicit perf_clang_scope() {perf_clang__init();}
@@ -14,17 +18,24 @@ extern "C" {
 int test__clang_to_IR(void)
 {
perf_clang_scope _scope;
+   unsigned int kernel_version;
+
+   if (fetch_kernel_version(_version, NULL, 0))
+   return -1;
+
+   std::string cflag_kver("-DLINUX_VERSION_CODE=" +
+   std::to_string(kernel_version));
 
std::unique_ptr M =
-   perf::getModuleFromSource({"-DRESULT=1"},
+   perf::getModuleFromSource({cflag_kver.c_str()},
  "perf-test.c",
- "int myfunc(void) {return RESULT;}");
+ test_llvm__bpf_base_prog);
 
if (!M)
return -1;
 
for (llvm::Function& F : *M)
-   if (F.getName() == "myfunc")
+   if (F.getName() == "bpf_func__SyS_epoll_wait")
return 0;
return -1;
 }
diff --git a/tools/perf/util/util-cxx.h b/tools/perf/util/util-cxx.h
new file mode 100644
index 000..0e0e019
--- /dev/null
+++ b/tools/perf/util/util-cxx.h
@@ -0,0 +1,26 @@
+/*
+ * Support C++ source use utilities defined in util.h
+ */
+
+#ifndef PERF_UTIL_UTIL_CXX_H
+#define PERF_UTIL_UTIL_CXX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Now 'new' is the only C++ keyword found in util.h:
+ * in tools/include/linux/rbtree.h
+ *
+ * Other keywords, like class and delete, should be
+ * redefined if necessary.
+ */
+#define new _new
+#include "util.h"
+#undef new
+
+#ifdef __cplusplus
+}
+#endif
+#endif
-- 
2.10.1



[PATCH v3 01/30] tools lib bpf: Add missing BPF functions

2016-11-25 Thread Wang Nan
Add more BPF map operations to libbpf. Also add bpf_obj_{pin,get}(). They
can be used on not only BPF maps but also BPF programs.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Joe Stringer 
Cc: Li Zefan 
---
 tools/lib/bpf/bpf.c | 56 +
 tools/lib/bpf/bpf.h |  7 +++
 2 files changed, 63 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 4212ed6..8143536 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -110,3 +110,59 @@ int bpf_map_update_elem(int fd, void *key, void *value,
 
return sys_bpf(BPF_MAP_UPDATE_ELEM, , sizeof(attr));
 }
+
+int bpf_map_lookup_elem(int fd, void *key, void *value)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.map_fd = fd;
+   attr.key = ptr_to_u64(key);
+   attr.value = ptr_to_u64(value);
+
+   return sys_bpf(BPF_MAP_LOOKUP_ELEM, , sizeof(attr));
+}
+
+int bpf_map_delete_elem(int fd, void *key)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.map_fd = fd;
+   attr.key = ptr_to_u64(key);
+
+   return sys_bpf(BPF_MAP_DELETE_ELEM, , sizeof(attr));
+}
+
+int bpf_map_get_next_key(int fd, void *key, void *next_key)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.map_fd = fd;
+   attr.key = ptr_to_u64(key);
+   attr.next_key = ptr_to_u64(next_key);
+
+   return sys_bpf(BPF_MAP_GET_NEXT_KEY, , sizeof(attr));
+}
+
+int bpf_obj_pin(int fd, const char *pathname)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.pathname = ptr_to_u64((void *)pathname);
+   attr.bpf_fd = fd;
+
+   return sys_bpf(BPF_OBJ_PIN, , sizeof(attr));
+}
+
+int bpf_obj_get(const char *pathname)
+{
+   union bpf_attr attr;
+
+   bzero(, sizeof(attr));
+   attr.pathname = ptr_to_u64((void *)pathname);
+
+   return sys_bpf(BPF_OBJ_GET, , sizeof(attr));
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index e8ba540..253c3db 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -35,4 +35,11 @@ int bpf_load_program(enum bpf_prog_type type, struct 
bpf_insn *insns,
 
 int bpf_map_update_elem(int fd, void *key, void *value,
u64 flags);
+
+int bpf_map_lookup_elem(int fd, void *key, void *value);
+int bpf_map_delete_elem(int fd, void *key);
+int bpf_map_get_next_key(int fd, void *key, void *next_key);
+int bpf_obj_pin(int fd, const char *pathname);
+int bpf_obj_get(const char *pathname);
+
 #endif
-- 
2.10.1



[PATCH v3 02/30] tools lib bpf: Add private field for bpf_object

2016-11-25 Thread Wang Nan
Similar to other classes defined in libbpf.h (map and program), allow
'object' class has its own private data.

Signed-off-by: Wang Nan 
Cc: Alexei Starovoitov 
Cc: Arnaldo Carvalho de Melo 
Cc: Li Zefan 
---
 tools/lib/bpf/libbpf.c | 23 +++
 tools/lib/bpf/libbpf.h |  5 +
 2 files changed, 28 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 96a2b2f..866d5cd 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -229,6 +229,10 @@ struct bpf_object {
 * all objects.
 */
struct list_head list;
+
+   void *priv;
+   bpf_object_clear_priv_t clear_priv;
+
char path[];
 };
 #define obj_elf_valid(o)   ((o)->efile.elf)
@@ -1229,6 +1233,9 @@ void bpf_object__close(struct bpf_object *obj)
if (!obj)
return;
 
+   if (obj->clear_priv)
+   obj->clear_priv(obj, obj->priv);
+
bpf_object__elf_finish(obj);
bpf_object__unload(obj);
 
@@ -1282,6 +1289,22 @@ unsigned int bpf_object__kversion(struct bpf_object *obj)
return obj ? obj->kern_version : 0;
 }
 
+int bpf_object__set_priv(struct bpf_object *obj, void *priv,
+bpf_object_clear_priv_t clear_priv)
+{
+   if (obj->priv && obj->clear_priv)
+   obj->clear_priv(obj, obj->priv);
+
+   obj->priv = priv;
+   obj->clear_priv = clear_priv;
+   return 0;
+}
+
+void *bpf_object__priv(struct bpf_object *obj)
+{
+   return obj ? obj->priv : ERR_PTR(-EINVAL);
+}
+
 struct bpf_program *
 bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
 {
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index dd7a513..0c0b012 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -79,6 +79,11 @@ struct bpf_object *bpf_object__next(struct bpf_object *prev);
 (pos) != NULL; \
 (pos) = (tmp), (tmp) = bpf_object__next(tmp))
 
+typedef void (*bpf_object_clear_priv_t)(struct bpf_object *, void *);
+int bpf_object__set_priv(struct bpf_object *obj, void *priv,
+bpf_object_clear_priv_t clear_priv);
+void *bpf_object__priv(struct bpf_object *prog);
+
 /* Accessors of bpf_program. */
 struct bpf_program;
 struct bpf_program *bpf_program__next(struct bpf_program *prog,
-- 
2.10.1



Re: [PATCH v3 2/3] zram: revalidate disk under init_lock

2016-11-25 Thread Sergey Senozhatsky

Hi,

On (11/25/16 17:35), Minchan Kim wrote:
> [1] moved revalidate_disk call out of init_lock to avoid lockdep
> false-positive splat. However, [2] remove init_lock in IO path
> so there is no worry about lockdep splat. So, let's restore it.
> This patch need to set BDI_CAP_STABLE_WRITES atomically in
> next patch.

can we break that dependency on the next patch if we would
set BDI_CAP_STABLE_WRITES when we allocate the queue?

queue->backing_dev_info.capabilities |= BDI_CAP_CGROUP_WRITEBACK;

-ss


Re: [PATCH v3 2/3] zram: revalidate disk under init_lock

2016-11-25 Thread Sergey Senozhatsky

Hi,

On (11/25/16 17:35), Minchan Kim wrote:
> [1] moved revalidate_disk call out of init_lock to avoid lockdep
> false-positive splat. However, [2] remove init_lock in IO path
> so there is no worry about lockdep splat. So, let's restore it.
> This patch need to set BDI_CAP_STABLE_WRITES atomically in
> next patch.

can we break that dependency on the next patch if we would
set BDI_CAP_STABLE_WRITES when we allocate the queue?

queue->backing_dev_info.capabilities |= BDI_CAP_CGROUP_WRITEBACK;

-ss


Re: [PATCH v3 3/3] zram: support BDI_CAP_STABLE_WRITES

2016-11-25 Thread Sergey Senozhatsky
Hello Minchan,

On (11/25/16 17:35), Minchan Kim wrote:
[..]
> +static void zram_revalidate_disk(struct zram *zram)
> +{
> + revalidate_disk(zram->disk);
> + zram->disk->queue->backing_dev_info.capabilities |=
> + BDI_CAP_STABLE_WRITES;
> +}
> +
>  /*
>   * Check if request is within bounds and aligned on zram logical blocks.
>   */
> @@ -1094,7 +1102,7 @@ static ssize_t disksize_store(struct device *dev,
>   zram->comp = comp;
>   zram->disksize = disksize;
>   set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
> - revalidate_disk(zram->disk);
> + zram_revalidate_disk(zram);
>   up_write(>init_lock);
>  
>   return len;
> @@ -1142,7 +1150,7 @@ static ssize_t reset_store(struct device *dev,
>   /* Make sure all the pending I/O are finished */
>   fsync_bdev(bdev);
>   zram_reset_device(zram);
> - revalidate_disk(zram->disk);
> + zram_revalidate_disk(zram);
>   bdput(bdev);
>  
>   mutex_lock(>bd_mutex);

why not set it just once, when we allocate queue/disk and configure both
of them:  in zram_add()

queue->backing_dev_info.capabilities |= BDI_CAP_CGROUP_WRITEBACK;

-ss


Re: [PATCH v3 3/3] zram: support BDI_CAP_STABLE_WRITES

2016-11-25 Thread Sergey Senozhatsky
Hello Minchan,

On (11/25/16 17:35), Minchan Kim wrote:
[..]
> +static void zram_revalidate_disk(struct zram *zram)
> +{
> + revalidate_disk(zram->disk);
> + zram->disk->queue->backing_dev_info.capabilities |=
> + BDI_CAP_STABLE_WRITES;
> +}
> +
>  /*
>   * Check if request is within bounds and aligned on zram logical blocks.
>   */
> @@ -1094,7 +1102,7 @@ static ssize_t disksize_store(struct device *dev,
>   zram->comp = comp;
>   zram->disksize = disksize;
>   set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
> - revalidate_disk(zram->disk);
> + zram_revalidate_disk(zram);
>   up_write(>init_lock);
>  
>   return len;
> @@ -1142,7 +1150,7 @@ static ssize_t reset_store(struct device *dev,
>   /* Make sure all the pending I/O are finished */
>   fsync_bdev(bdev);
>   zram_reset_device(zram);
> - revalidate_disk(zram->disk);
> + zram_revalidate_disk(zram);
>   bdput(bdev);
>  
>   mutex_lock(>bd_mutex);

why not set it just once, when we allocate queue/disk and configure both
of them:  in zram_add()

queue->backing_dev_info.capabilities |= BDI_CAP_CGROUP_WRITEBACK;

-ss


Re: [PATCH] Fixes for compiling with clang

2016-11-25 Thread kbuild test robot
Hi Peter,

[auto build test ERROR on kbuild/for-next]
[also build test ERROR on v4.9-rc6 next-20161125]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Peter-Foley/Fixes-for-compiling-with-clang/20161126-124017
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git 
for-next
config: avr32-atngw100_defconfig (attached as .config)
compiler: avr-gcc (GCC) 4.9.2
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=avr32 

All errors (new ones prefixed by >>):

>> /bin/sh: 0: Illegal option - 
--
>> /bin/sh: 0: Illegal option - 
   kernel/time/Kconfig:155:warning: range is invalid
--
>> /bin/sh: 0: Illegal option - 
   kernel/time/Kconfig:155:warning: range is invalid
>> /bin/sh: 0: Illegal option - 
   avr-gcc: error: unrecognized command line option '-mno-pic'
   avr-gcc: error: unrecognized command line option '-march=ap'
   make[2]: *** [kernel/bounds.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH] Fixes for compiling with clang

2016-11-25 Thread kbuild test robot
Hi Peter,

[auto build test ERROR on kbuild/for-next]
[also build test ERROR on v4.9-rc6 next-20161125]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Peter-Foley/Fixes-for-compiling-with-clang/20161126-124017
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git 
for-next
config: avr32-atngw100_defconfig (attached as .config)
compiler: avr-gcc (GCC) 4.9.2
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=avr32 

All errors (new ones prefixed by >>):

>> /bin/sh: 0: Illegal option - 
--
>> /bin/sh: 0: Illegal option - 
   kernel/time/Kconfig:155:warning: range is invalid
--
>> /bin/sh: 0: Illegal option - 
   kernel/time/Kconfig:155:warning: range is invalid
>> /bin/sh: 0: Illegal option - 
   avr-gcc: error: unrecognized command line option '-mno-pic'
   avr-gcc: error: unrecognized command line option '-march=ap'
   make[2]: *** [kernel/bounds.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH v2] Staging: iio: adc: fix sysfs files modes in ad7192.c

2016-11-25 Thread Boyan Vladinov

Ignore patch version...comments below

Will resend it

On 24.11.2016 19:38, Boyan Vladinov wrote:

Fixes sysfs entries user/group modes and coding style warnings
found by checkpatch.pl tool. Also use the IIO_DEVICE_ATTR_[RO|RW] and
macros to create device attributes

Signed-off-by: Boyan Vladinov 
---
 drivers/staging/iio/adc/ad7192.c | 45 +++-
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 1fb68c01abd5..630b04d8128f 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -324,8 +324,8 @@ static int ad7192_setup(struct ad7192_state *st,
 }

 static ssize_t
-ad7192_show_scale_available(struct device *dev,
-   struct device_attribute *attr, char *buf)
+in_v_m_v_scale_available_show(struct device *dev, struct device_attribute 
*attr,
+ char *buf)
 {
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7192_state *st = iio_priv(indio_dev);
@@ -340,15 +340,19 @@ ad7192_show_scale_available(struct device *dev,
return len;
 }

-static IIO_DEVICE_ATTR_NAMED(in_v_m_v_scale_available,
-in_voltage-voltage_scale_available,

behavior changed after removed `in_voltage-voltage_scale_available`

-S_IRUGO, ad7192_show_scale_available, NULL, 0);
+static ssize_t
+in_voltage_scale_available_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   return in_v_m_v_scale_available_show(dev, attr, buf);
+}
+
+static IIO_DEVICE_ATTR_RO(in_v_m_v_scale_available, 0);

-static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
-  ad7192_show_scale_available, NULL, 0);
+static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);

-static ssize_t ad7192_show_ac_excitation(struct device *dev,
-struct device_attribute *attr,
+static ssize_t ac_excitation_en_show(struct device *dev,
+struct device_attribute *attr,
 char *buf)
 {
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -357,8 +361,8 @@ static ssize_t ad7192_show_ac_excitation(struct device *dev,
return sprintf(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX));
 }

-static ssize_t ad7192_show_bridge_switch(struct device *dev,
-struct device_attribute *attr,
+static ssize_t bridge_switch_en_show(struct device *dev,
+struct device_attribute *attr,
 char *buf)
 {
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -367,8 +371,8 @@ static ssize_t ad7192_show_bridge_switch(struct device *dev,
return sprintf(buf, "%d\n", !!(st->gpocon & AD7192_GPOCON_BPDSW));
 }

-static ssize_t ad7192_set(struct device *dev,
- struct device_attribute *attr,
+static ssize_t bridge_switch_en_store(struct device *dev,
+ struct device_attribute *attr,
  const char *buf,
  size_t len)
 {
@@ -412,13 +416,16 @@ static ssize_t ad7192_set(struct device *dev,
return ret ? ret : len;
 }

-static IIO_DEVICE_ATTR(bridge_switch_en, S_IRUGO | S_IWUSR,
-  ad7192_show_bridge_switch, ad7192_set,
-  AD7192_REG_GPOCON);
+static ssize_t ac_excitation_en_store(struct device *dev,
+ struct device_attribute *attr,
+const char *buf, size_t len)
+{
+   return bridge_switch_en_store(dev, attr, buf, len);
+}
+
+static IIO_DEVICE_ATTR_RW(bridge_switch_en, AD7192_REG_GPOCON);

-static IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR,
-  ad7192_show_ac_excitation, ad7192_set,
-  AD7192_REG_MODE);
+static IIO_DEVICE_ATTR_RW(ac_excitation_en, AD7192_REG_MODE);

 static struct attribute *ad7192_attributes[] = {
_dev_attr_in_v_m_v_scale_available.dev_attr.attr,



Re: [PATCH v2] Staging: iio: adc: fix sysfs files modes in ad7192.c

2016-11-25 Thread Boyan Vladinov

Ignore patch version...comments below

Will resend it

On 24.11.2016 19:38, Boyan Vladinov wrote:

Fixes sysfs entries user/group modes and coding style warnings
found by checkpatch.pl tool. Also use the IIO_DEVICE_ATTR_[RO|RW] and
macros to create device attributes

Signed-off-by: Boyan Vladinov 
---
 drivers/staging/iio/adc/ad7192.c | 45 +++-
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 1fb68c01abd5..630b04d8128f 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -324,8 +324,8 @@ static int ad7192_setup(struct ad7192_state *st,
 }

 static ssize_t
-ad7192_show_scale_available(struct device *dev,
-   struct device_attribute *attr, char *buf)
+in_v_m_v_scale_available_show(struct device *dev, struct device_attribute 
*attr,
+ char *buf)
 {
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7192_state *st = iio_priv(indio_dev);
@@ -340,15 +340,19 @@ ad7192_show_scale_available(struct device *dev,
return len;
 }

-static IIO_DEVICE_ATTR_NAMED(in_v_m_v_scale_available,
-in_voltage-voltage_scale_available,

behavior changed after removed `in_voltage-voltage_scale_available`

-S_IRUGO, ad7192_show_scale_available, NULL, 0);
+static ssize_t
+in_voltage_scale_available_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   return in_v_m_v_scale_available_show(dev, attr, buf);
+}
+
+static IIO_DEVICE_ATTR_RO(in_v_m_v_scale_available, 0);

-static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
-  ad7192_show_scale_available, NULL, 0);
+static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);

-static ssize_t ad7192_show_ac_excitation(struct device *dev,
-struct device_attribute *attr,
+static ssize_t ac_excitation_en_show(struct device *dev,
+struct device_attribute *attr,
 char *buf)
 {
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -357,8 +361,8 @@ static ssize_t ad7192_show_ac_excitation(struct device *dev,
return sprintf(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX));
 }

-static ssize_t ad7192_show_bridge_switch(struct device *dev,
-struct device_attribute *attr,
+static ssize_t bridge_switch_en_show(struct device *dev,
+struct device_attribute *attr,
 char *buf)
 {
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -367,8 +371,8 @@ static ssize_t ad7192_show_bridge_switch(struct device *dev,
return sprintf(buf, "%d\n", !!(st->gpocon & AD7192_GPOCON_BPDSW));
 }

-static ssize_t ad7192_set(struct device *dev,
- struct device_attribute *attr,
+static ssize_t bridge_switch_en_store(struct device *dev,
+ struct device_attribute *attr,
  const char *buf,
  size_t len)
 {
@@ -412,13 +416,16 @@ static ssize_t ad7192_set(struct device *dev,
return ret ? ret : len;
 }

-static IIO_DEVICE_ATTR(bridge_switch_en, S_IRUGO | S_IWUSR,
-  ad7192_show_bridge_switch, ad7192_set,
-  AD7192_REG_GPOCON);
+static ssize_t ac_excitation_en_store(struct device *dev,
+ struct device_attribute *attr,
+const char *buf, size_t len)
+{
+   return bridge_switch_en_store(dev, attr, buf, len);
+}
+
+static IIO_DEVICE_ATTR_RW(bridge_switch_en, AD7192_REG_GPOCON);

-static IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR,
-  ad7192_show_ac_excitation, ad7192_set,
-  AD7192_REG_MODE);
+static IIO_DEVICE_ATTR_RW(ac_excitation_en, AD7192_REG_MODE);

 static struct attribute *ad7192_attributes[] = {
_dev_attr_in_v_m_v_scale_available.dev_attr.attr,



Xmas Offer

2016-11-25 Thread Mrs Julie Leach
You are a recipient to Mrs Julie Leach Donation of $3 million USD. Contact ( 
julieleac...@gmail.com ) for claims.


Xmas Offer

2016-11-25 Thread Mrs Julie Leach
You are a recipient to Mrs Julie Leach Donation of $3 million USD. Contact ( 
julieleac...@gmail.com ) for claims.


[PATCH] Fixes for compiling with clang

2016-11-25 Thread Peter Foley
Move definition of HOSTCC to allow use of cc-name.
Suppress warnings about unsupported optimization options.
Disable clang's integrated assembler which is incompatible with kernel
asm constructs.

Signed-off-by: Peter Foley 
---
 Makefile | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index 0ede48ba5aaf..b69ad7e4a6d2 100644
--- a/Makefile
+++ b/Makefile
@@ -299,16 +299,6 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo 
$$BASH; \
  else if [ -x /bin/bash ]; then echo /bin/bash; \
  else echo sh; fi ; fi)
 
-HOSTCC   = gcc
-HOSTCXX  = g++
-HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 
-fomit-frame-pointer -std=gnu89
-HOSTCXXFLAGS = -O2
-
-ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
-HOSTCFLAGS  += -Wno-unused-value -Wno-unused-parameter \
-   -Wno-missing-field-initializers -fno-delete-null-pointer-checks
-endif
-
 # Decide whether to build built-in, modular, or both.
 # Normally, just do built-in.
 
@@ -343,6 +333,16 @@ export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
 scripts/Kbuild.include: ;
 include scripts/Kbuild.include
 
+HOSTCC   = gcc
+HOSTCXX  = g++
+HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 
-fomit-frame-pointer -std=gnu89 \
+   -Wno-unused-value -Wno-unused-parameter 
-Wno-missing-field-initializers
+HOSTCXXFLAGS = -O2
+
+ifneq ($(cc-name),clang)
+HOSTCFLAGS +=  -fno-delete-null-pointer-checks
+endif
+
 # Make variables (CC, etc...)
 AS = $(CROSS_COMPILE)as
 LD = $(CROSS_COMPILE)ld
@@ -685,6 +685,7 @@ KBUILD_CFLAGS += $(stackp-flag)
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
 KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)
+KBUILD_CFLAGS += $(call cc-disable-warning, ignored-optimization-argument)
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable)
 KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
 KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
@@ -695,6 +696,8 @@ KBUILD_CFLAGS += $(call cc-disable-warning, 
tautological-compare)
 # See modpost pattern 2
 KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
 KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
+KBUILD_CFLAGS += $(call cc-option, -fno-integrated-as)
+KBUILD_AFLAGS += $(call cc-option, -fno-integrated-as)
 else
 
 # These warnings generated too much noise in a regular build.
-- 
2.11.0.rc2



[PATCH] Fixes for compiling with clang

2016-11-25 Thread Peter Foley
Move definition of HOSTCC to allow use of cc-name.
Suppress warnings about unsupported optimization options.
Disable clang's integrated assembler which is incompatible with kernel
asm constructs.

Signed-off-by: Peter Foley 
---
 Makefile | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index 0ede48ba5aaf..b69ad7e4a6d2 100644
--- a/Makefile
+++ b/Makefile
@@ -299,16 +299,6 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo 
$$BASH; \
  else if [ -x /bin/bash ]; then echo /bin/bash; \
  else echo sh; fi ; fi)
 
-HOSTCC   = gcc
-HOSTCXX  = g++
-HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 
-fomit-frame-pointer -std=gnu89
-HOSTCXXFLAGS = -O2
-
-ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
-HOSTCFLAGS  += -Wno-unused-value -Wno-unused-parameter \
-   -Wno-missing-field-initializers -fno-delete-null-pointer-checks
-endif
-
 # Decide whether to build built-in, modular, or both.
 # Normally, just do built-in.
 
@@ -343,6 +333,16 @@ export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
 scripts/Kbuild.include: ;
 include scripts/Kbuild.include
 
+HOSTCC   = gcc
+HOSTCXX  = g++
+HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 
-fomit-frame-pointer -std=gnu89 \
+   -Wno-unused-value -Wno-unused-parameter 
-Wno-missing-field-initializers
+HOSTCXXFLAGS = -O2
+
+ifneq ($(cc-name),clang)
+HOSTCFLAGS +=  -fno-delete-null-pointer-checks
+endif
+
 # Make variables (CC, etc...)
 AS = $(CROSS_COMPILE)as
 LD = $(CROSS_COMPILE)ld
@@ -685,6 +685,7 @@ KBUILD_CFLAGS += $(stackp-flag)
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
 KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)
+KBUILD_CFLAGS += $(call cc-disable-warning, ignored-optimization-argument)
 KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable)
 KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
 KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
@@ -695,6 +696,8 @@ KBUILD_CFLAGS += $(call cc-disable-warning, 
tautological-compare)
 # See modpost pattern 2
 KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
 KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
+KBUILD_CFLAGS += $(call cc-option, -fno-integrated-as)
+KBUILD_AFLAGS += $(call cc-option, -fno-integrated-as)
 else
 
 # These warnings generated too much noise in a regular build.
-- 
2.11.0.rc2



Re: [RFC 1/1] LSM ptags: Add tagging of processes

2016-11-25 Thread Tetsuo Handa
Jose Bollo wrote:
> +/**
> + * is_valid_utf8 - Is buffer a valid utf8 string?
> + *
> + * @buffer: the start of the string
> + * @length: length in bytes of the buffer
> + *
> + * Return 1 when valid or else returns 0
> + */

Do we really need to check UTF-8 inside kernel? What do you do if
people start using UTF-32 in the future? There was a discussion
about use of encoding inside kernel started at
http://lkml.kernel.org/r/20071103164303.GA26707@ubuntu .



> +
> +/**
> + * _ptags_read - Implement the reading of the tags
> + *
> + * @ptags: tags structure of the readen task
> + * @result: a pointer for storing the read result
> + * @uns: user namespace proxy
> + *
> + * Returns the count of byte read or the negative code -ENOMEM
> + * if an allocation failed.
> + */
> +static int _ptags_read(struct _ptags *ptags, char **result, struct uns uns)
> +{
> + unsigned idx, count;
> + size_t size;
> + struct entry *entries, *entry;
> + char *buffer;
> + struct value *value;
> + struct item *item;
> +
> + /* init loops */
> + count = ptags->count;
> + entries = ptags->entries;
> +
> + /* compute printed size */
> + size = 0;
> + for (idx = 0; idx < count; idx++) {
> + entry = [idx];
> + value = entry_read(entry, uns);
> + if (value) {
> + item = value_get(*value);
> + size += entry_name(*entry)->length
> + + (unsigned)value_is_kept(*value)
> + + (item ? 2 + item->length : 1);
> + }
> + }
> +
> + if (size > INT_MAX)
> + return -E2BIG;

This sanity check is useless. INT_MAX is 2,147,483,647 but kmalloc() can't
allocate larger than 8,388,608 bytes if PAGE_SIZE = 4096 and MAX_ORDER = 11.

> + buffer = kmalloc(size, GFP_KERNEL);
> + if (!buffer)
> + return -ENOMEM;

Moreover, kmalloc() will not try to allocate larger than 32,768 bytes
(PAGE_ALLOC_COSTLY_ORDER = 3). Although __GFP_NOFAIL can force kmalloc() to
retry by invoking the OOM killer, such behavior might change in near future
due to http://lkml.kernel.org/r/20161123064925.9716-3-mho...@kernel.org .

Given these constants

#define MAXCOUNT4000
#define MAXTAGLEN   4000
#define MAXVALUELEN 32700

and someone tried to use as many and long as possible tags, what is
possible max value for "size"? I think that that value can easily exceed
32,768 and kmalloc() won't be reliable. vmalloc() can be used as a fallback
when kmalloc() failed, but is trying to pass possible max value for "size"
to vmalloc() reasonable? Shouldn't this function be rewritten not to
allocate so much memory?

Also, how much memory will be consumed if everybody tried to use tags
as many and long as possible?

> +
> + /* print in the buffer */
> + *result = buffer;
> + for (idx = 0; idx < count; idx++) {
> + entry = [idx];
> + value = entry_read(entry, uns);
> + if (value) {
> + if (value_is_kept(*value))
> + *buffer++ = KEEP_CHAR;
> + item = entry_name(*entry);
> + memcpy(buffer, item->value, item->length);
> + buffer += item->length;
> + item = value_get(*value);
> + if (item) {
> + *buffer++ = ASSIGN_CHAR;
> + memcpy(buffer, item->value, item->length);
> + buffer += item->length;
> + }
> + *buffer++ = EOL_CHAR;
> + }
> + }
> +
> + return (int)size;
> +}


Re: [RFC 1/1] LSM ptags: Add tagging of processes

2016-11-25 Thread Tetsuo Handa
Jose Bollo wrote:
> +/**
> + * is_valid_utf8 - Is buffer a valid utf8 string?
> + *
> + * @buffer: the start of the string
> + * @length: length in bytes of the buffer
> + *
> + * Return 1 when valid or else returns 0
> + */

Do we really need to check UTF-8 inside kernel? What do you do if
people start using UTF-32 in the future? There was a discussion
about use of encoding inside kernel started at
http://lkml.kernel.org/r/20071103164303.GA26707@ubuntu .



> +
> +/**
> + * _ptags_read - Implement the reading of the tags
> + *
> + * @ptags: tags structure of the readen task
> + * @result: a pointer for storing the read result
> + * @uns: user namespace proxy
> + *
> + * Returns the count of byte read or the negative code -ENOMEM
> + * if an allocation failed.
> + */
> +static int _ptags_read(struct _ptags *ptags, char **result, struct uns uns)
> +{
> + unsigned idx, count;
> + size_t size;
> + struct entry *entries, *entry;
> + char *buffer;
> + struct value *value;
> + struct item *item;
> +
> + /* init loops */
> + count = ptags->count;
> + entries = ptags->entries;
> +
> + /* compute printed size */
> + size = 0;
> + for (idx = 0; idx < count; idx++) {
> + entry = [idx];
> + value = entry_read(entry, uns);
> + if (value) {
> + item = value_get(*value);
> + size += entry_name(*entry)->length
> + + (unsigned)value_is_kept(*value)
> + + (item ? 2 + item->length : 1);
> + }
> + }
> +
> + if (size > INT_MAX)
> + return -E2BIG;

This sanity check is useless. INT_MAX is 2,147,483,647 but kmalloc() can't
allocate larger than 8,388,608 bytes if PAGE_SIZE = 4096 and MAX_ORDER = 11.

> + buffer = kmalloc(size, GFP_KERNEL);
> + if (!buffer)
> + return -ENOMEM;

Moreover, kmalloc() will not try to allocate larger than 32,768 bytes
(PAGE_ALLOC_COSTLY_ORDER = 3). Although __GFP_NOFAIL can force kmalloc() to
retry by invoking the OOM killer, such behavior might change in near future
due to http://lkml.kernel.org/r/20161123064925.9716-3-mho...@kernel.org .

Given these constants

#define MAXCOUNT4000
#define MAXTAGLEN   4000
#define MAXVALUELEN 32700

and someone tried to use as many and long as possible tags, what is
possible max value for "size"? I think that that value can easily exceed
32,768 and kmalloc() won't be reliable. vmalloc() can be used as a fallback
when kmalloc() failed, but is trying to pass possible max value for "size"
to vmalloc() reasonable? Shouldn't this function be rewritten not to
allocate so much memory?

Also, how much memory will be consumed if everybody tried to use tags
as many and long as possible?

> +
> + /* print in the buffer */
> + *result = buffer;
> + for (idx = 0; idx < count; idx++) {
> + entry = [idx];
> + value = entry_read(entry, uns);
> + if (value) {
> + if (value_is_kept(*value))
> + *buffer++ = KEEP_CHAR;
> + item = entry_name(*entry);
> + memcpy(buffer, item->value, item->length);
> + buffer += item->length;
> + item = value_get(*value);
> + if (item) {
> + *buffer++ = ASSIGN_CHAR;
> + memcpy(buffer, item->value, item->length);
> + buffer += item->length;
> + }
> + *buffer++ = EOL_CHAR;
> + }
> + }
> +
> + return (int)size;
> +}


fixed drivers/staging/most/mostcore/core.c coding style

2016-11-25 Thread wenhungyang
fix drivers/staging/most/mostcore/core.c coding style

1. move static from MACRO to function name
2. change symbolic permission such as 'S_IRUGO' to number

>From 3e1dba83090c58251aae1dc7aca431bb11632a98 Mon Sep 17 00:00:00 2001
From: wenhungyang 
Date: Wed, 23 Nov 2016 21:55:36 +0800
Subject: [c157e58488d1] fix core.c coding-style
To: fyony...@gmail.com

Signed-off-by: wenhungyang 
---
 drivers/staging/most/mostcore/core.c | 40 ++--
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c
index 4c580d1..9286c36 100644
--- a/drivers/staging/most/mostcore/core.c
+++ b/drivers/staging/most/mostcore/core.c
@@ -342,15 +342,15 @@ static ssize_t show_channel_starving(struct most_c_obj *c,
 }
 
 #define create_show_channel_attribute(val) \
-	static MOST_CHNL_ATTR(val, S_IRUGO, show_##val, NULL)
+	MOST_CHNL_ATTR(val, 0444, show_##val, NULL)
 
-create_show_channel_attribute(available_directions);
-create_show_channel_attribute(available_datatypes);
-create_show_channel_attribute(number_of_packet_buffers);
-create_show_channel_attribute(number_of_stream_buffers);
-create_show_channel_attribute(size_of_stream_buffer);
-create_show_channel_attribute(size_of_packet_buffer);
-create_show_channel_attribute(channel_starving);
+static create_show_channel_attribute(available_directions);
+static create_show_channel_attribute(available_datatypes);
+static create_show_channel_attribute(number_of_packet_buffers);
+static create_show_channel_attribute(number_of_stream_buffers);
+static create_show_channel_attribute(size_of_stream_buffer);
+static create_show_channel_attribute(size_of_packet_buffer);
+static create_show_channel_attribute(channel_starving);
 
 static ssize_t show_set_number_of_buffers(struct most_c_obj *c,
 	  struct most_c_attr *attr,
@@ -494,16 +494,16 @@ static ssize_t store_set_packets_per_xact(struct most_c_obj *c,
 }
 
 #define create_channel_attribute(value) \
-	static MOST_CHNL_ATTR(value, S_IRUGO | S_IWUSR, \
+	MOST_CHNL_ATTR(value, 0644, \
 			  show_##value, \
 			  store_##value)
 
-create_channel_attribute(set_buffer_size);
-create_channel_attribute(set_number_of_buffers);
-create_channel_attribute(set_direction);
-create_channel_attribute(set_datatype);
-create_channel_attribute(set_subbuffer_size);
-create_channel_attribute(set_packets_per_xact);
+static create_channel_attribute(set_buffer_size);
+static create_channel_attribute(set_number_of_buffers);
+static create_channel_attribute(set_direction);
+static create_channel_attribute(set_datatype);
+static create_channel_attribute(set_subbuffer_size);
+static create_channel_attribute(set_packets_per_xact);
 
 /**
  * most_channel_def_attrs - array of default attributes of channel object
@@ -690,10 +690,10 @@ static ssize_t show_interface(struct most_inst_obj *instance_obj,
 }
 
 #define create_inst_attribute(value) \
-	static MOST_INST_ATTR(value, S_IRUGO, show_##value, NULL)
+	MOST_INST_ATTR(value, 0444, show_##value, NULL)
 
-create_inst_attribute(description);
-create_inst_attribute(interface);
+static create_inst_attribute(description);
+static create_inst_attribute(interface);
 
 static struct attribute *most_inst_def_attrs[] = {
 	_inst_attr_description.attr,
@@ -1016,7 +1016,7 @@ static ssize_t store_add_link(struct most_aim_obj *aim_obj,
 }
 
 static struct most_aim_attribute most_aim_attr_add_link =
-	__ATTR(add_link, S_IRUGO | S_IWUSR, show_add_link, store_add_link);
+	__ATTR(add_link, 0644, show_add_link, store_add_link);
 
 /**
  * store_remove_link - store function for remove_link attribute
@@ -1059,7 +1059,7 @@ static ssize_t store_remove_link(struct most_aim_obj *aim_obj,
 }
 
 static struct most_aim_attribute most_aim_attr_remove_link =
-	__ATTR(remove_link, S_IWUSR, NULL, store_remove_link);
+	__ATTR(remove_link, 0200, NULL, store_remove_link);
 
 static struct attribute *most_aim_def_attrs[] = {
 	_aim_attr_add_link.attr,
-- 
2.7.4



fixed drivers/staging/most/mostcore/core.c coding style

2016-11-25 Thread wenhungyang
fix drivers/staging/most/mostcore/core.c coding style

1. move static from MACRO to function name
2. change symbolic permission such as 'S_IRUGO' to number

>From 3e1dba83090c58251aae1dc7aca431bb11632a98 Mon Sep 17 00:00:00 2001
From: wenhungyang 
Date: Wed, 23 Nov 2016 21:55:36 +0800
Subject: [c157e58488d1] fix core.c coding-style
To: fyony...@gmail.com

Signed-off-by: wenhungyang 
---
 drivers/staging/most/mostcore/core.c | 40 ++--
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c
index 4c580d1..9286c36 100644
--- a/drivers/staging/most/mostcore/core.c
+++ b/drivers/staging/most/mostcore/core.c
@@ -342,15 +342,15 @@ static ssize_t show_channel_starving(struct most_c_obj *c,
 }
 
 #define create_show_channel_attribute(val) \
-	static MOST_CHNL_ATTR(val, S_IRUGO, show_##val, NULL)
+	MOST_CHNL_ATTR(val, 0444, show_##val, NULL)
 
-create_show_channel_attribute(available_directions);
-create_show_channel_attribute(available_datatypes);
-create_show_channel_attribute(number_of_packet_buffers);
-create_show_channel_attribute(number_of_stream_buffers);
-create_show_channel_attribute(size_of_stream_buffer);
-create_show_channel_attribute(size_of_packet_buffer);
-create_show_channel_attribute(channel_starving);
+static create_show_channel_attribute(available_directions);
+static create_show_channel_attribute(available_datatypes);
+static create_show_channel_attribute(number_of_packet_buffers);
+static create_show_channel_attribute(number_of_stream_buffers);
+static create_show_channel_attribute(size_of_stream_buffer);
+static create_show_channel_attribute(size_of_packet_buffer);
+static create_show_channel_attribute(channel_starving);
 
 static ssize_t show_set_number_of_buffers(struct most_c_obj *c,
 	  struct most_c_attr *attr,
@@ -494,16 +494,16 @@ static ssize_t store_set_packets_per_xact(struct most_c_obj *c,
 }
 
 #define create_channel_attribute(value) \
-	static MOST_CHNL_ATTR(value, S_IRUGO | S_IWUSR, \
+	MOST_CHNL_ATTR(value, 0644, \
 			  show_##value, \
 			  store_##value)
 
-create_channel_attribute(set_buffer_size);
-create_channel_attribute(set_number_of_buffers);
-create_channel_attribute(set_direction);
-create_channel_attribute(set_datatype);
-create_channel_attribute(set_subbuffer_size);
-create_channel_attribute(set_packets_per_xact);
+static create_channel_attribute(set_buffer_size);
+static create_channel_attribute(set_number_of_buffers);
+static create_channel_attribute(set_direction);
+static create_channel_attribute(set_datatype);
+static create_channel_attribute(set_subbuffer_size);
+static create_channel_attribute(set_packets_per_xact);
 
 /**
  * most_channel_def_attrs - array of default attributes of channel object
@@ -690,10 +690,10 @@ static ssize_t show_interface(struct most_inst_obj *instance_obj,
 }
 
 #define create_inst_attribute(value) \
-	static MOST_INST_ATTR(value, S_IRUGO, show_##value, NULL)
+	MOST_INST_ATTR(value, 0444, show_##value, NULL)
 
-create_inst_attribute(description);
-create_inst_attribute(interface);
+static create_inst_attribute(description);
+static create_inst_attribute(interface);
 
 static struct attribute *most_inst_def_attrs[] = {
 	_inst_attr_description.attr,
@@ -1016,7 +1016,7 @@ static ssize_t store_add_link(struct most_aim_obj *aim_obj,
 }
 
 static struct most_aim_attribute most_aim_attr_add_link =
-	__ATTR(add_link, S_IRUGO | S_IWUSR, show_add_link, store_add_link);
+	__ATTR(add_link, 0644, show_add_link, store_add_link);
 
 /**
  * store_remove_link - store function for remove_link attribute
@@ -1059,7 +1059,7 @@ static ssize_t store_remove_link(struct most_aim_obj *aim_obj,
 }
 
 static struct most_aim_attribute most_aim_attr_remove_link =
-	__ATTR(remove_link, S_IWUSR, NULL, store_remove_link);
+	__ATTR(remove_link, 0200, NULL, store_remove_link);
 
 static struct attribute *most_aim_def_attrs[] = {
 	_aim_attr_add_link.attr,
-- 
2.7.4



[PATCH] IIO: Change msleep to usleep_range for small msecs

2016-11-25 Thread Aniroop Mathur
msleep(1~20) may not do what the caller intends, and will often sleep longer.
(~20 ms actual sleep for any value given in the 1~20ms range)
This is not the desired behaviour for many cases like device resume time,
device suspend time, device enable time, data reading time, etc.
Thus, change msleep to usleep_range for precise wakeups.

Signed-off-by: Aniroop Mathur 
---
 drivers/iio/adc/exynos_adc.c |  2 +-
 drivers/iio/pressure/bmp280-core.c   | 14 +++---
 drivers/staging/iio/meter/ade7753.c  |  2 +-
 drivers/staging/iio/meter/ade7753.h  |  2 +-
 drivers/staging/iio/meter/ade7754.c  |  2 +-
 drivers/staging/iio/meter/ade7754.h  |  2 +-
 drivers/staging/iio/meter/ade7758.h  |  2 +-
 drivers/staging/iio/meter/ade7758_core.c |  2 +-
 drivers/staging/iio/meter/ade7759.c  |  2 +-
 drivers/staging/iio/meter/ade7759.h  |  2 +-
 drivers/staging/iio/meter/ade7854.c  |  2 +-
 drivers/staging/iio/meter/ade7854.h  |  2 +-
 12 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index c15756d..ad1775b 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -632,7 +632,7 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
input_report_key(info->input, BTN_TOUCH, 1);
input_sync(info->input);
 
-   msleep(1);
+   usleep_range(1000, 1100);
};
 
writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
diff --git a/drivers/iio/pressure/bmp280-core.c 
b/drivers/iio/pressure/bmp280-core.c
index e5a533c..4d18826 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -65,7 +65,7 @@ struct bmp280_data {
struct bmp180_calib calib;
struct regulator *vddd;
struct regulator *vdda;
-   unsigned int start_up_time; /* in milliseconds */
+   unsigned int start_up_time; /* in microseconds */
 
/* log of base 2 of oversampling rate */
u8 oversampling_press;
@@ -935,14 +935,14 @@ int bmp280_common_probe(struct device *dev,
data->chip_info = _chip_info;
data->oversampling_press = ilog2(8);
data->oversampling_temp = ilog2(1);
-   data->start_up_time = 10;
+   data->start_up_time = 1;
break;
case BMP280_CHIP_ID:
indio_dev->num_channels = 2;
data->chip_info = _chip_info;
data->oversampling_press = ilog2(16);
data->oversampling_temp = ilog2(2);
-   data->start_up_time = 2;
+   data->start_up_time = 2000;
break;
case BME280_CHIP_ID:
indio_dev->num_channels = 3;
@@ -950,7 +950,7 @@ int bmp280_common_probe(struct device *dev,
data->oversampling_press = ilog2(16);
data->oversampling_humid = ilog2(16);
data->oversampling_temp = ilog2(2);
-   data->start_up_time = 2;
+   data->start_up_time = 2000;
break;
default:
return -EINVAL;
@@ -979,7 +979,7 @@ int bmp280_common_probe(struct device *dev,
goto out_disable_vddd;
}
/* Wait to make sure we started up properly */
-   mdelay(data->start_up_time);
+   usleep_range(data->start_up_time, data->start_up_time + 100);
 
/* Bring chip out of reset if there is an assigned GPIO line */
gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
@@ -1038,7 +1038,7 @@ int bmp280_common_probe(struct device *dev,
 * Set autosuspend to two orders of magnitude larger than the
 * start-up time.
 */
-   pm_runtime_set_autosuspend_delay(dev, data->start_up_time *100);
+   pm_runtime_set_autosuspend_delay(dev, data->start_up_time / 10);
pm_runtime_use_autosuspend(dev);
pm_runtime_put(dev);
 
@@ -1101,7 +1101,7 @@ static int bmp280_runtime_resume(struct device *dev)
ret = regulator_enable(data->vdda);
if (ret)
return ret;
-   msleep(data->start_up_time);
+   usleep_range(data->start_up_time, data->start_up_time + 100);
return data->chip_info->chip_config(data);
 }
 #endif /* CONFIG_PM */
diff --git a/drivers/staging/iio/meter/ade7753.c 
b/drivers/staging/iio/meter/ade7753.c
index 4b5f05f..671dc99 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -377,7 +377,7 @@ static int ade7753_initial_setup(struct iio_dev *indio_dev)
}
 
ade7753_reset(dev);
-   msleep(ADE7753_STARTUP_DELAY);
+   usleep_range(ADE7753_STARTUP_DELAY, ADE7753_STARTUP_DELAY + 100);
 
 err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7753.h 
b/drivers/staging/iio/meter/ade7753.h
index a9d93cc..bfe7491 100644
--- a/drivers/staging/iio/meter/ade7753.h
+++ 

[PATCH] IIO: Change msleep to usleep_range for small msecs

2016-11-25 Thread Aniroop Mathur
msleep(1~20) may not do what the caller intends, and will often sleep longer.
(~20 ms actual sleep for any value given in the 1~20ms range)
This is not the desired behaviour for many cases like device resume time,
device suspend time, device enable time, data reading time, etc.
Thus, change msleep to usleep_range for precise wakeups.

Signed-off-by: Aniroop Mathur 
---
 drivers/iio/adc/exynos_adc.c |  2 +-
 drivers/iio/pressure/bmp280-core.c   | 14 +++---
 drivers/staging/iio/meter/ade7753.c  |  2 +-
 drivers/staging/iio/meter/ade7753.h  |  2 +-
 drivers/staging/iio/meter/ade7754.c  |  2 +-
 drivers/staging/iio/meter/ade7754.h  |  2 +-
 drivers/staging/iio/meter/ade7758.h  |  2 +-
 drivers/staging/iio/meter/ade7758_core.c |  2 +-
 drivers/staging/iio/meter/ade7759.c  |  2 +-
 drivers/staging/iio/meter/ade7759.h  |  2 +-
 drivers/staging/iio/meter/ade7854.c  |  2 +-
 drivers/staging/iio/meter/ade7854.h  |  2 +-
 12 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index c15756d..ad1775b 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -632,7 +632,7 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
input_report_key(info->input, BTN_TOUCH, 1);
input_sync(info->input);
 
-   msleep(1);
+   usleep_range(1000, 1100);
};
 
writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
diff --git a/drivers/iio/pressure/bmp280-core.c 
b/drivers/iio/pressure/bmp280-core.c
index e5a533c..4d18826 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -65,7 +65,7 @@ struct bmp280_data {
struct bmp180_calib calib;
struct regulator *vddd;
struct regulator *vdda;
-   unsigned int start_up_time; /* in milliseconds */
+   unsigned int start_up_time; /* in microseconds */
 
/* log of base 2 of oversampling rate */
u8 oversampling_press;
@@ -935,14 +935,14 @@ int bmp280_common_probe(struct device *dev,
data->chip_info = _chip_info;
data->oversampling_press = ilog2(8);
data->oversampling_temp = ilog2(1);
-   data->start_up_time = 10;
+   data->start_up_time = 1;
break;
case BMP280_CHIP_ID:
indio_dev->num_channels = 2;
data->chip_info = _chip_info;
data->oversampling_press = ilog2(16);
data->oversampling_temp = ilog2(2);
-   data->start_up_time = 2;
+   data->start_up_time = 2000;
break;
case BME280_CHIP_ID:
indio_dev->num_channels = 3;
@@ -950,7 +950,7 @@ int bmp280_common_probe(struct device *dev,
data->oversampling_press = ilog2(16);
data->oversampling_humid = ilog2(16);
data->oversampling_temp = ilog2(2);
-   data->start_up_time = 2;
+   data->start_up_time = 2000;
break;
default:
return -EINVAL;
@@ -979,7 +979,7 @@ int bmp280_common_probe(struct device *dev,
goto out_disable_vddd;
}
/* Wait to make sure we started up properly */
-   mdelay(data->start_up_time);
+   usleep_range(data->start_up_time, data->start_up_time + 100);
 
/* Bring chip out of reset if there is an assigned GPIO line */
gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
@@ -1038,7 +1038,7 @@ int bmp280_common_probe(struct device *dev,
 * Set autosuspend to two orders of magnitude larger than the
 * start-up time.
 */
-   pm_runtime_set_autosuspend_delay(dev, data->start_up_time *100);
+   pm_runtime_set_autosuspend_delay(dev, data->start_up_time / 10);
pm_runtime_use_autosuspend(dev);
pm_runtime_put(dev);
 
@@ -1101,7 +1101,7 @@ static int bmp280_runtime_resume(struct device *dev)
ret = regulator_enable(data->vdda);
if (ret)
return ret;
-   msleep(data->start_up_time);
+   usleep_range(data->start_up_time, data->start_up_time + 100);
return data->chip_info->chip_config(data);
 }
 #endif /* CONFIG_PM */
diff --git a/drivers/staging/iio/meter/ade7753.c 
b/drivers/staging/iio/meter/ade7753.c
index 4b5f05f..671dc99 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -377,7 +377,7 @@ static int ade7753_initial_setup(struct iio_dev *indio_dev)
}
 
ade7753_reset(dev);
-   msleep(ADE7753_STARTUP_DELAY);
+   usleep_range(ADE7753_STARTUP_DELAY, ADE7753_STARTUP_DELAY + 100);
 
 err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7753.h 
b/drivers/staging/iio/meter/ade7753.h
index a9d93cc..bfe7491 100644
--- a/drivers/staging/iio/meter/ade7753.h
+++ b/drivers/staging/iio/meter/ade7753.h
@@ 

Re: [PATCH 1/3] perf sched timehist: Mark schedule function in callchains

2016-11-25 Thread David Ahern
On 11/23/16 11:30 PM, Namhyung Kim wrote:
> Hi David,
> 
> On Wed, Nov 23, 2016 at 10:13:46PM -0500, David Ahern wrote:
>> On 11/23/16 8:11 PM, Namhyung Kim wrote:
>>> The sched_switch event always captured from the scheduler function.  So
>>> it'd be great omit them from the callchain.  This patch marks the
>>> functions to be omitted by later patch.
>>
>> I had this covered by a symbol filter:
>>
>> https://github.com/dsahern/linux/blob/perf/full-monty-4.1/tools/perf/builtin-sched.c#L3000
>>
>> Not sure what happened over the years but that should still work and
>> allows the user to add more symbols to ignore:
> 
> The symbol filter was removed by commit be39db9f2932 ("perf symbols:
> Remove symbol_filter_t machinery").

That's unfortunate. The exclude list is huge in removing redundant callchains 
and getting more relevant information on the screen with a stack depth of 5. 
I'll see what I can cook up with the existing code.



Re: [PATCH 1/3] perf sched timehist: Mark schedule function in callchains

2016-11-25 Thread David Ahern
On 11/23/16 11:30 PM, Namhyung Kim wrote:
> Hi David,
> 
> On Wed, Nov 23, 2016 at 10:13:46PM -0500, David Ahern wrote:
>> On 11/23/16 8:11 PM, Namhyung Kim wrote:
>>> The sched_switch event always captured from the scheduler function.  So
>>> it'd be great omit them from the callchain.  This patch marks the
>>> functions to be omitted by later patch.
>>
>> I had this covered by a symbol filter:
>>
>> https://github.com/dsahern/linux/blob/perf/full-monty-4.1/tools/perf/builtin-sched.c#L3000
>>
>> Not sure what happened over the years but that should still work and
>> allows the user to add more symbols to ignore:
> 
> The symbol filter was removed by commit be39db9f2932 ("perf symbols:
> Remove symbol_filter_t machinery").

That's unfortunate. The exclude list is huge in removing redundant callchains 
and getting more relevant information on the screen with a stack depth of 5. 
I'll see what I can cook up with the existing code.



Re: [PATCH 2/2] x86/intel_rdt: Update task closid immediately on CPU in rmdir and unmount

2016-11-25 Thread Fenghua Yu
On Wed, Nov 23, 2016 at 03:23:50PM +0100, Thomas Gleixner wrote:
> On Fri, 18 Nov 2016, Fenghua Yu wrote:
> Reworked untested patch below.

The reworked patch passes my baisc tests. But I have a quesiton on
rdt_move_group_tasks() (please see below).

> 
> Thanks,
> 
>   tglx
> 
> 8<-
> --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
> +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
> @@ -194,12 +194,13 @@ static int rdtgroup_cpus_show(struct ker
>  /*
>   * This is safe against intel_rdt_sched_in() called from __switch_to()
>   * because __switch_to() is executed with interrupts disabled. A local call
> - * from rdt_update_percpu_closid() is proteced against __switch_to() because
> + * from rdt_update_closid() is proteced against __switch_to() because
>   * preemption is disabled.
>   */
> -static void rdt_update_cpu_closid(void *v)
> +static void rdt_update_cpu_closid(void *closid)
>  {
> - this_cpu_write(cpu_closid, *(int *)v);
> + if (closid)
> + this_cpu_write(cpu_closid, *(int *)closid);
>   /*
>* We cannot unconditionally write the MSR because the current
>* executing task might have its own closid selected. Just reuse
> @@ -208,14 +209,23 @@ static void rdt_update_cpu_closid(void *
>   intel_rdt_sched_in();
>  }
>  
> -/* Update the per cpu closid and eventually the PGR_ASSOC MSR */
> -static void rdt_update_percpu_closid(const struct cpumask *cpu_mask, int 
> closid)
> +/*
> + * Update the PGR_ASSOC MSR on all cpus in @cpu_mask,
> + *
> + * Per task closids must have been set up before calling this function.
> + *
> + * The per cpu closids are updated with the smp function call, when @closid
> + * is not NULL. If @closid is NULL then all affected percpu closids must
> + * have been set up before calling this function.
> + */
> +static void
> +rdt_update_closid(const struct cpumask *cpu_mask, int *closid)
>  {
>   int cpu = get_cpu();
>  
>   if (cpumask_test_cpu(cpu, cpu_mask))
> - rdt_update_cpu_closid();
> - smp_call_function_many(cpu_mask, rdt_update_cpu_closid, , 1);
> + rdt_update_cpu_closid(closid);
> + smp_call_function_many(cpu_mask, rdt_update_cpu_closid, closid, 1);
>   put_cpu();
>  }
>  
> @@ -264,7 +274,7 @@ static ssize_t rdtgroup_cpus_write(struc
>   /* Give any dropped cpus to rdtgroup_default */
>   cpumask_or(_default.cpu_mask,
>  _default.cpu_mask, tmpmask);
> - rdt_update_percpu_closid(tmpmask, rdtgroup_default.closid);
> + rdt_update_closid(tmpmask, _default.closid);
>   }
>  
>   /*
> @@ -278,7 +288,7 @@ static ssize_t rdtgroup_cpus_write(struc
>   continue;
>   cpumask_andnot(>cpu_mask, >cpu_mask, tmpmask);
>   }
> - rdt_update_percpu_closid(tmpmask, rdtgrp->closid);
> + rdt_update_closid(tmpmask, >closid);
>   }
>  
>   /* Done pushing/pulling - update this group with new mask */
> @@ -807,18 +817,49 @@ static int reset_all_cbms(struct rdt_res
>  }
>  
>  /*
> - * Forcibly remove all of subdirectories under root.
> + * Move tasks from one to the other group. If @from is NULL, then all tasks
> + * in the systems are moved unconditionally (used for teardown).
> + *
> + * If @mask is not NULL the cpus on which moved tasks are running are set
> + * in that mask so the update smp function call is restricted to affected
> + * cpus.
>   */
> -static void rmdir_all_sub(void)
> +static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
> +  struct cpumask *mask)
>  {
> - struct rdtgroup *rdtgrp, *tmp;
>   struct task_struct *p, *t;
>  
> - /* move all tasks to default resource group */
>   read_lock(_lock);
> - for_each_process_thread(p, t)
> - t->closid = 0;
> + for_each_process_thread(p, t) {
> + if (!from || t->closid == from->closid) {
> + t->closid = to->closid;
> +#ifdef CONFIG_SMP
> + /*
> +  * This is safe on x86 w/o barriers as the ordering
> +  * of writing to task_cpu() and t->on_cpu is
> +  * reverse to the reading here. The detection is
> +  * inaccurate as tasks might move or schedule
> +  * before the smp function call takes place. In
> +  * such a case the function call is pointless, but
> +  * there is no other side effect.
> +  */

If process p1 is running on CPU1 before this point,

> + if (mask && t->on_cpu)
> + cpumask_set_cpu(task_cpu(t), mask);

If between CPU1 is set in mask and rdt_update_closid(tmpmask, NULL) is
called, p1 is switched to CPU2, and process p2 with its own closid
(e.g. 2) is switched to CPU1.

Then closid in PQR_ASSOC is set 

Re: [PATCH 2/2] x86/intel_rdt: Update task closid immediately on CPU in rmdir and unmount

2016-11-25 Thread Fenghua Yu
On Wed, Nov 23, 2016 at 03:23:50PM +0100, Thomas Gleixner wrote:
> On Fri, 18 Nov 2016, Fenghua Yu wrote:
> Reworked untested patch below.

The reworked patch passes my baisc tests. But I have a quesiton on
rdt_move_group_tasks() (please see below).

> 
> Thanks,
> 
>   tglx
> 
> 8<-
> --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
> +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
> @@ -194,12 +194,13 @@ static int rdtgroup_cpus_show(struct ker
>  /*
>   * This is safe against intel_rdt_sched_in() called from __switch_to()
>   * because __switch_to() is executed with interrupts disabled. A local call
> - * from rdt_update_percpu_closid() is proteced against __switch_to() because
> + * from rdt_update_closid() is proteced against __switch_to() because
>   * preemption is disabled.
>   */
> -static void rdt_update_cpu_closid(void *v)
> +static void rdt_update_cpu_closid(void *closid)
>  {
> - this_cpu_write(cpu_closid, *(int *)v);
> + if (closid)
> + this_cpu_write(cpu_closid, *(int *)closid);
>   /*
>* We cannot unconditionally write the MSR because the current
>* executing task might have its own closid selected. Just reuse
> @@ -208,14 +209,23 @@ static void rdt_update_cpu_closid(void *
>   intel_rdt_sched_in();
>  }
>  
> -/* Update the per cpu closid and eventually the PGR_ASSOC MSR */
> -static void rdt_update_percpu_closid(const struct cpumask *cpu_mask, int 
> closid)
> +/*
> + * Update the PGR_ASSOC MSR on all cpus in @cpu_mask,
> + *
> + * Per task closids must have been set up before calling this function.
> + *
> + * The per cpu closids are updated with the smp function call, when @closid
> + * is not NULL. If @closid is NULL then all affected percpu closids must
> + * have been set up before calling this function.
> + */
> +static void
> +rdt_update_closid(const struct cpumask *cpu_mask, int *closid)
>  {
>   int cpu = get_cpu();
>  
>   if (cpumask_test_cpu(cpu, cpu_mask))
> - rdt_update_cpu_closid();
> - smp_call_function_many(cpu_mask, rdt_update_cpu_closid, , 1);
> + rdt_update_cpu_closid(closid);
> + smp_call_function_many(cpu_mask, rdt_update_cpu_closid, closid, 1);
>   put_cpu();
>  }
>  
> @@ -264,7 +274,7 @@ static ssize_t rdtgroup_cpus_write(struc
>   /* Give any dropped cpus to rdtgroup_default */
>   cpumask_or(_default.cpu_mask,
>  _default.cpu_mask, tmpmask);
> - rdt_update_percpu_closid(tmpmask, rdtgroup_default.closid);
> + rdt_update_closid(tmpmask, _default.closid);
>   }
>  
>   /*
> @@ -278,7 +288,7 @@ static ssize_t rdtgroup_cpus_write(struc
>   continue;
>   cpumask_andnot(>cpu_mask, >cpu_mask, tmpmask);
>   }
> - rdt_update_percpu_closid(tmpmask, rdtgrp->closid);
> + rdt_update_closid(tmpmask, >closid);
>   }
>  
>   /* Done pushing/pulling - update this group with new mask */
> @@ -807,18 +817,49 @@ static int reset_all_cbms(struct rdt_res
>  }
>  
>  /*
> - * Forcibly remove all of subdirectories under root.
> + * Move tasks from one to the other group. If @from is NULL, then all tasks
> + * in the systems are moved unconditionally (used for teardown).
> + *
> + * If @mask is not NULL the cpus on which moved tasks are running are set
> + * in that mask so the update smp function call is restricted to affected
> + * cpus.
>   */
> -static void rmdir_all_sub(void)
> +static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
> +  struct cpumask *mask)
>  {
> - struct rdtgroup *rdtgrp, *tmp;
>   struct task_struct *p, *t;
>  
> - /* move all tasks to default resource group */
>   read_lock(_lock);
> - for_each_process_thread(p, t)
> - t->closid = 0;
> + for_each_process_thread(p, t) {
> + if (!from || t->closid == from->closid) {
> + t->closid = to->closid;
> +#ifdef CONFIG_SMP
> + /*
> +  * This is safe on x86 w/o barriers as the ordering
> +  * of writing to task_cpu() and t->on_cpu is
> +  * reverse to the reading here. The detection is
> +  * inaccurate as tasks might move or schedule
> +  * before the smp function call takes place. In
> +  * such a case the function call is pointless, but
> +  * there is no other side effect.
> +  */

If process p1 is running on CPU1 before this point,

> + if (mask && t->on_cpu)
> + cpumask_set_cpu(task_cpu(t), mask);

If between CPU1 is set in mask and rdt_update_closid(tmpmask, NULL) is
called, p1 is switched to CPU2, and process p2 with its own closid
(e.g. 2) is switched to CPU1.

Then closid in PQR_ASSOC is set 

Xmas Offer

2016-11-25 Thread Mrs Julie Leach
You are a recipient to Mrs Julie Leach Donation of $3 million USD. Contact ( 
julieleac...@gmail.com ) for claims.


Xmas Offer

2016-11-25 Thread Mrs Julie Leach
You are a recipient to Mrs Julie Leach Donation of $3 million USD. Contact ( 
julieleac...@gmail.com ) for claims.


Re: [PATCH net] mvpp2: use correct size for memset

2016-11-25 Thread David Miller
From: Arnd Bergmann 
Date: Thu, 24 Nov 2016 17:28:12 +0100

> gcc-7 detects a short memset in mvpp2, introduced in the original
> merge of the driver:
> 
> drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_cls_init':
> drivers/net/ethernet/marvell/mvpp2.c:3296:2: error: 'memset' used with length 
> equal to number of elements without multiplication by element size 
> [-Werror=memset-elt-size]
> 
> The result seems to be that we write uninitialized data into the
> flow table registers, although we did not get any warning about
> that uninitialized data usage.
> 
> Using sizeof() lets us initialize then entire array instead.
> 
> Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network 
> unit")
> Signed-off-by: Arnd Bergmann 

Applied, thanks.


Re: [PATCH net] mvpp2: use correct size for memset

2016-11-25 Thread David Miller
From: Arnd Bergmann 
Date: Thu, 24 Nov 2016 17:28:12 +0100

> gcc-7 detects a short memset in mvpp2, introduced in the original
> merge of the driver:
> 
> drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_cls_init':
> drivers/net/ethernet/marvell/mvpp2.c:3296:2: error: 'memset' used with length 
> equal to number of elements without multiplication by element size 
> [-Werror=memset-elt-size]
> 
> The result seems to be that we write uninitialized data into the
> flow table registers, although we did not get any warning about
> that uninitialized data usage.
> 
> Using sizeof() lets us initialize then entire array instead.
> 
> Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network 
> unit")
> Signed-off-by: Arnd Bergmann 

Applied, thanks.


Re: [PATCH] irda: fix overly long udelay()

2016-11-25 Thread David Miller
From: Arnd Bergmann 
Date: Thu, 24 Nov 2016 17:26:22 +0100

> irda_get_mtt() returns a hardcoded '1' in some cases,
> and with gcc-7, we get a build error because this triggers a
> compile-time check in udelay():
> 
> drivers/net/irda/w83977af_ir.o: In function `w83977af_hard_xmit':
> w83977af_ir.c:(.text.w83977af_hard_xmit+0x14c): undefined reference to 
> `__bad_udelay'
> 
> Older compilers did not run into this because they either did not
> completely inline the irda_get_mtt() or did not consider the
> 1 value a constant expression.
> 
> The code has been wrong since the start of git history.
> 
> Signed-off-by: Arnd Bergmann 
 ...
> @@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
>   
>   mtt = irda_get_mtt(skb);
>   pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
> - if (mtt)
> + if (mtt > 1000)
> + mdelay(mtt/1000);
> + else if (mtt)
>   udelay(mtt);

I know this isn't caused by you, but wow what is going on with the
indentation here?!?!?


Re: [PATCH] irda: fix overly long udelay()

2016-11-25 Thread David Miller
From: Arnd Bergmann 
Date: Thu, 24 Nov 2016 17:26:22 +0100

> irda_get_mtt() returns a hardcoded '1' in some cases,
> and with gcc-7, we get a build error because this triggers a
> compile-time check in udelay():
> 
> drivers/net/irda/w83977af_ir.o: In function `w83977af_hard_xmit':
> w83977af_ir.c:(.text.w83977af_hard_xmit+0x14c): undefined reference to 
> `__bad_udelay'
> 
> Older compilers did not run into this because they either did not
> completely inline the irda_get_mtt() or did not consider the
> 1 value a constant expression.
> 
> The code has been wrong since the start of git history.
> 
> Signed-off-by: Arnd Bergmann 
 ...
> @@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
>   
>   mtt = irda_get_mtt(skb);
>   pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
> - if (mtt)
> + if (mtt > 1000)
> + mdelay(mtt/1000);
> + else if (mtt)
>   udelay(mtt);

I know this isn't caused by you, but wow what is going on with the
indentation here?!?!?


RE: [patch v3 1/1] platform/x86: move module mlx-platform from arch/x86 to drivers/platform/x86

2016-11-25 Thread Vadim Pasternak


> -Original Message-
> From: Andy Shevchenko [mailto:andy.shevche...@gmail.com]
> Sent: Friday, November 25, 2016 12:03 PM
> To: Vadim Pasternak 
> Cc: Thomas Gleixner ; dvh...@infradead.org; platform-
> driver-...@vger.kernel.org; x...@kernel.org; linux-kernel@vger.kernel.org;
> j...@resnulli.us; andriy.shevche...@linux.intel.com
> Subject: Re: [patch v3 1/1] platform/x86: move module mlx-platform from
> arch/x86 to drivers/platform/x86
> 
> On Fri, Nov 25, 2016 at 6:14 AM, Vadim Pasternak 
> wrote:
> >> Thanks for reply.
> >>
> >> > First of all, please avoid top posting.
> >>
> >> Sorry for that.
> >> I posted on top, because it doesn't come as reply to something (but
> >> it seems I should post at bottom in suc case).
> >>
> >> > I will process the pdx86 mailing list and queue this week.
> >
> > I am very sorry for reminding, but I see that it's still not merged.
> 
> 
> Sorry for that, we encounter one issue with repository permissions, so, 
> currently
> I can't do much. We are trying to resolve this as soon as possible.
> We still have time before merge window (one week or so).
> 
Hi Andy,

OK, I see.
I just have another patch, you already made review for that.
And I am waiting for the merge, in order to send this patch (this is the change 
in mlx-platform.c module, which is going to migrate).
And I am afraid I can missed merge window for it.

Thanks,
Vadim.

> --
> With Best Regards,
> Andy Shevchenko


RE: [patch v3 1/1] platform/x86: move module mlx-platform from arch/x86 to drivers/platform/x86

2016-11-25 Thread Vadim Pasternak


> -Original Message-
> From: Andy Shevchenko [mailto:andy.shevche...@gmail.com]
> Sent: Friday, November 25, 2016 12:03 PM
> To: Vadim Pasternak 
> Cc: Thomas Gleixner ; dvh...@infradead.org; platform-
> driver-...@vger.kernel.org; x...@kernel.org; linux-kernel@vger.kernel.org;
> j...@resnulli.us; andriy.shevche...@linux.intel.com
> Subject: Re: [patch v3 1/1] platform/x86: move module mlx-platform from
> arch/x86 to drivers/platform/x86
> 
> On Fri, Nov 25, 2016 at 6:14 AM, Vadim Pasternak 
> wrote:
> >> Thanks for reply.
> >>
> >> > First of all, please avoid top posting.
> >>
> >> Sorry for that.
> >> I posted on top, because it doesn't come as reply to something (but
> >> it seems I should post at bottom in suc case).
> >>
> >> > I will process the pdx86 mailing list and queue this week.
> >
> > I am very sorry for reminding, but I see that it's still not merged.
> 
> 
> Sorry for that, we encounter one issue with repository permissions, so, 
> currently
> I can't do much. We are trying to resolve this as soon as possible.
> We still have time before merge window (one week or so).
> 
Hi Andy,

OK, I see.
I just have another patch, you already made review for that.
And I am waiting for the merge, in order to send this patch (this is the change 
in mlx-platform.c module, which is going to migrate).
And I am afraid I can missed merge window for it.

Thanks,
Vadim.

> --
> With Best Regards,
> Andy Shevchenko


Re: [PATCH] net: ieee802154: drop duplicate header delay.h

2016-11-25 Thread David Miller
From: Geliang Tang 
Date: Thu, 24 Nov 2016 21:58:32 +0800

> Drop duplicate header delay.h from adf7242.c.
> 
> Signed-off-by: Geliang Tang 

Applied.


Re: [PATCH] net: ieee802154: drop duplicate header delay.h

2016-11-25 Thread David Miller
From: Geliang Tang 
Date: Thu, 24 Nov 2016 21:58:32 +0800

> Drop duplicate header delay.h from adf7242.c.
> 
> Signed-off-by: Geliang Tang 

Applied.


Re: [PATCH] net/mlx5: drop duplicate header delay.h

2016-11-25 Thread David Miller
From: Geliang Tang 
Date: Thu, 24 Nov 2016 21:58:33 +0800

> Drop duplicate header delay.h from mlx5/core/main.c.
> 
> Signed-off-by: Geliang Tang 

Applied.


Re: [PATCH] net/mlx5: drop duplicate header delay.h

2016-11-25 Thread David Miller
From: Geliang Tang 
Date: Thu, 24 Nov 2016 21:58:33 +0800

> Drop duplicate header delay.h from mlx5/core/main.c.
> 
> Signed-off-by: Geliang Tang 

Applied.


  1   2   3   4   5   6   7   8   9   10   >