aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2018-08-15 16:07:01 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-08-20 07:54:58 -0400
commitcb76371441d0984824a6e66f8f3d369f037edb34 (patch)
tree11e51fef417533c4a2d02aeae03615c7665d8e82
parent49836f7811f383d8613661fff110ce74f4710d52 (diff)
perf llvm: Allow passing options to llc in addition to clang
The newly added 'llvm.opts' variable allows passing options directly to llc, like needed to get sane DWARF in BPF ELF debug sections: With: [root@seventh perf]# cat ~/.perfconfig [llvm] dump-obj = true clang-opt = -g [root@seventh perf]# We get: [root@seventh perf]# perf trace -e tools/perf/examples/bpf/hello.c cat /etc/passwd > /dev/null LLVM: dumping tools/perf/examples/bpf/hello.o 0.000 __bpf_stdout__:Hello, world 0.015 __bpf_stdout__:Hello, world 0.187 __bpf_stdout__:Hello, world [root@seventh perf]# pahole tools/perf/examples/bpf/hello.o struct clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c) { clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 0 4 */ clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 4 4 */ clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 8 4 */ clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 12 4 */ clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 16 4 */ clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 20 4 */ clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566e.org clang version 8.0.0 (http://llvm.org/git/clang.git 8587270a739ee30c926a76d5657e65e85b560f6e) (http://llvm.org/git/llvm.git 0566eefef9c3777bd780ec4cbb9efa764633b76c); /* 24 4 */ /* size: 28, cachelines: 1, members: 7 */ /* last cacheline: 28 bytes */ }; [root@seventh perf]# Adding these options to be passed to llvm's llc: [root@seventh perf]# cat ~/.perfconfig [llvm] dump-obj = true clang-opt = -g opts = -mattr=dwarfris [root@seventh perf]# We get sane output: [root@seventh perf]# perf trace -e tools/perf/examples/bpf/hello.c cat /etc/passwd > /dev/null LLVM: dumping tools/perf/examples/bpf/hello.o 0.000 __bpf_stdout__:Hello, world 0.015 __bpf_stdout__:Hello, world 0.185 __bpf_stdout__:Hello, world [root@seventh perf]# pahole tools/perf/examples/bpf/hello.o struct bpf_map { unsigned int type; /* 0 4 */ unsigned int key_size; /* 4 4 */ unsigned int value_size; /* 8 4 */ unsigned int max_entries; /* 12 4 */ unsigned int map_flags; /* 16 4 */ unsigned int inner_map_idx; /* 20 4 */ unsigned int numa_node; /* 24 4 */ /* size: 28, cachelines: 1, members: 7 */ /* last cacheline: 28 bytes */ }; [root@seventh perf]# Cc: Alexei Starovoitov <ast@fb.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Martin KaFai Lau <kafai@fb.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com>, Cc: Yonghong Song <yhs@fb.com> Link: https://lkml.kernel.org/n/tip-0lrwmrip4dru1651rm8xa7tq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/llvm-utils.c31
-rw-r--r--tools/perf/util/llvm-utils.h9
2 files changed, 38 insertions, 2 deletions
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 5e94857dfca2..19262f98cd4e 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -22,12 +22,14 @@
22 "$CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS " \ 22 "$CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS " \
23 "-Wno-unused-value -Wno-pointer-sign " \ 23 "-Wno-unused-value -Wno-pointer-sign " \
24 "-working-directory $WORKING_DIR " \ 24 "-working-directory $WORKING_DIR " \
25 "-c \"$CLANG_SOURCE\" -target bpf -O2 -o -" 25 "-c \"$CLANG_SOURCE\" -target bpf $CLANG_EMIT_LLVM -O2 -o - $LLVM_OPTIONS_PIPE"
26 26
27struct llvm_param llvm_param = { 27struct llvm_param llvm_param = {
28 .clang_path = "clang", 28 .clang_path = "clang",
29 .llc_path = "llc",
29 .clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE, 30 .clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE,
30 .clang_opt = NULL, 31 .clang_opt = NULL,
32 .opts = NULL,
31 .kbuild_dir = NULL, 33 .kbuild_dir = NULL,
32 .kbuild_opts = NULL, 34 .kbuild_opts = NULL,
33 .user_set_param = false, 35 .user_set_param = false,
@@ -51,6 +53,8 @@ int perf_llvm_config(const char *var, const char *value)
51 llvm_param.kbuild_opts = strdup(value); 53 llvm_param.kbuild_opts = strdup(value);
52 else if (!strcmp(var, "dump-obj")) 54 else if (!strcmp(var, "dump-obj"))
53 llvm_param.dump_obj = !!perf_config_bool(var, value); 55 llvm_param.dump_obj = !!perf_config_bool(var, value);
56 else if (!strcmp(var, "opts"))
57 llvm_param.opts = strdup(value);
54 else { 58 else {
55 pr_debug("Invalid LLVM config option: %s\n", value); 59 pr_debug("Invalid LLVM config option: %s\n", value);
56 return -1; 60 return -1;
@@ -430,11 +434,13 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
430 unsigned int kernel_version; 434 unsigned int kernel_version;
431 char linux_version_code_str[64]; 435 char linux_version_code_str[64];
432 const char *clang_opt = llvm_param.clang_opt; 436 const char *clang_opt = llvm_param.clang_opt;
433 char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64]; 437 char clang_path[PATH_MAX], llc_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
434 char serr[STRERR_BUFSIZE]; 438 char serr[STRERR_BUFSIZE];
435 char *kbuild_dir = NULL, *kbuild_include_opts = NULL, 439 char *kbuild_dir = NULL, *kbuild_include_opts = NULL,
436 *perf_bpf_include_opts = NULL; 440 *perf_bpf_include_opts = NULL;
437 const char *template = llvm_param.clang_bpf_cmd_template; 441 const char *template = llvm_param.clang_bpf_cmd_template;
442 char *pipe_template = NULL;
443 const char *opts = llvm_param.opts;
438 char *command_echo = NULL, *command_out; 444 char *command_echo = NULL, *command_out;
439 char *perf_include_dir = system_path(PERF_INCLUDE_DIR); 445 char *perf_include_dir = system_path(PERF_INCLUDE_DIR);
440 446
@@ -484,6 +490,26 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
484 force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts); 490 force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts);
485 force_set_env("WORKING_DIR", kbuild_dir ? : "."); 491 force_set_env("WORKING_DIR", kbuild_dir ? : ".");
486 492
493 if (opts) {
494 err = search_program(llvm_param.llc_path, "llc", llc_path);
495 if (err) {
496 pr_err("ERROR:\tunable to find llc.\n"
497 "Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH\n"
498 " \tand 'llc-path' option in [llvm] section of ~/.perfconfig.\n");
499 version_notice();
500 goto errout;
501 }
502
503 if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -",
504 template, llc_path, opts) < 0) {
505 pr_err("ERROR:\tnot enough memory to setup command line\n");
506 goto errout;
507 }
508
509 template = pipe_template;
510
511 }
512
487 /* 513 /*
488 * Since we may reset clang's working dir, path of source file 514 * Since we may reset clang's working dir, path of source file
489 * should be transferred into absolute path, except we want 515 * should be transferred into absolute path, except we want
@@ -535,6 +561,7 @@ errout:
535 free(obj_buf); 561 free(obj_buf);
536 free(perf_bpf_include_opts); 562 free(perf_bpf_include_opts);
537 free(perf_include_dir); 563 free(perf_include_dir);
564 free(pipe_template);
538 if (p_obj_buf) 565 if (p_obj_buf)
539 *p_obj_buf = NULL; 566 *p_obj_buf = NULL;
540 if (p_obj_buf_sz) 567 if (p_obj_buf_sz)
diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h
index d3ad8deb5db4..bf3f3f4c4fe2 100644
--- a/tools/perf/util/llvm-utils.h
+++ b/tools/perf/util/llvm-utils.h
@@ -11,6 +11,8 @@
11struct llvm_param { 11struct llvm_param {
12 /* Path of clang executable */ 12 /* Path of clang executable */
13 const char *clang_path; 13 const char *clang_path;
14 /* Path of llc executable */
15 const char *llc_path;
14 /* 16 /*
15 * Template of clang bpf compiling. 5 env variables 17 * Template of clang bpf compiling. 5 env variables
16 * can be used: 18 * can be used:
@@ -23,6 +25,13 @@ struct llvm_param {
23 const char *clang_bpf_cmd_template; 25 const char *clang_bpf_cmd_template;
24 /* Will be filled in $CLANG_OPTIONS */ 26 /* Will be filled in $CLANG_OPTIONS */
25 const char *clang_opt; 27 const char *clang_opt;
28 /*
29 * If present it'll add -emit-llvm to $CLANG_OPTIONS to pipe
30 * the clang output to llc, useful for new llvm options not
31 * yet selectable via 'clang -mllvm option', such as -mattr=dwarfris
32 * in clang 6.0/llvm 7
33 */
34 const char *opts;
26 /* Where to find kbuild system */ 35 /* Where to find kbuild system */
27 const char *kbuild_dir; 36 const char *kbuild_dir;
28 /* 37 /*