perf/core improvements and fixes
Subsystems (3)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit bebd23a2ed31d47e7dd746d3b125068aa2c42d85:
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-10-30 10:09:37 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to 0014de172d228e450377d1fd079d94e67128d27f:
perf sched latency: Fix thread pid reuse issue (2015-11-05 12:51:00 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
- Fix 'perf top' segfault related to splitting overlapping mmaps (Jiri Olsa)
- Fix 'perf sched latency' when there is pid/tid reuse (Jiri Olsa)
- Fix documentation for 'perf trace -i' (Peter Feiner)
Infrastructure:
- Make the LINUX_VERSION_CODE define available for bpf scriptlets to use (Wang Nan)
- Pass the number of configured CPUs via the __NR_CPUS__ define to bpf scriptlets (Wang Nan)
- Fix libbpf compiler warning on CentOS 6 (Namhyung Kim)
- Only be verbose in several perf test entries, bpf included, when -v is used (Wang Nan)
- Don't run the 'build-test' entries always in the same order, the full set takes a long time, so sometimes we interrupt, shuffling them avoids running just the first same few in interrupted runs (Arnaldo Carvalho de Melo)
- Change FEATURE-DUMP to FEATURE-DUMP.libbpf in .gitignore and 'clean' make target (Yunlong Song)
- 'perf stat' refactorings to avoid duplicated code (Andi Kleen)
----------------------------------------------------------------
Andi Kleen (2):
perf stat: Move sw clock metrics printout to stat-shadow perf stat: Use common printout function to avoid duplicated code
Arnaldo Carvalho de Melo (1):
perf tools: Allow shuffling the build tests
Jiri Olsa (2):
perf tools: Insert split maps correctly into origin group perf sched latency: Fix thread pid reuse issue
Namhyung Kim (1):
tools lib bpf: Fix compiler warning on CentOS 6
Peter Feiner (1):
perf trace: Fix documentation for -i
Wang Nan (5):
perf test: Keep test result clean if '-v' not set
perf bpf: Mute libbpf when '-v' not set
perf llvm: Pass number of configured CPUs to clang compiler
perf llvm: Pass LINUX_VERSION_CODE to BPF program when compiling perf tools: Fix find_perf_probe_point_from_map() which incorrectly returns success
Yunlong Song (1):
tools lib bpf: Change FEATURE-DUMP to FEATURE-DUMP.libbpf
tools/lib/bpf/.gitignore | 2 +- tools/lib/bpf/Makefile | 2 +- tools/lib/bpf/libbpf.c | 4 +-- tools/lib/bpf/libbpf.h | 2 +- tools/perf/Documentation/perf-trace.txt | 1 - tools/perf/Makefile | 2 +- tools/perf/builtin-sched.c | 5 +-- tools/perf/builtin-stat.c | 59 +++++++++++---------------------- tools/perf/tests/attr.c | 3 +- tools/perf/tests/code-reading.c | 8 ++--- tools/perf/tests/keep-tracking.c | 4 +-- tools/perf/tests/llvm.c | 11 +++--- tools/perf/tests/make | 5 +++ tools/perf/tests/switch-tracking.c | 4 +-- tools/perf/util/bpf-loader.c | 4 +-- tools/perf/util/llvm-utils.c | 51 ++++++++++++++++++++++++---- tools/perf/util/map.c | 10 ++++-- tools/perf/util/probe-event.c | 3 ++ tools/perf/util/stat-shadow.c | 5 +++ 19 files changed, 110 insertions(+), 75 deletions(-)
Arnaldo Carvalho de Melo
maintainerPATCH 1/12 perf test: Keep test result clean if '-v' not set
From: Wang Nan <[email protected]>
According to [1], 'perf test' should avoid output too much information if '-v' is not set, only 'Ok', 'FAIL' or 'Skip' need to be printed.
This patch removes several messages sent directly to stderr to make the output clean.
Before this patch:
# perf test dummy 23: Test using a dummy software event to keep tracking : (not supported) Ok
After this patch:
# perf test dummy 23: Test using a dummy software event to keep tracking : Skip
[1] http://lkml.kernel.org/r/[email protected]
--- tools/perf/tests/attr.c | 3 +-- tools/perf/tests/code-reading.c | 8 ++++---- tools/perf/tests/keep-tracking.c | 4 ++-- tools/perf/tests/llvm.c | 11 ++++------- tools/perf/tests/switch-tracking.c | 4 ++-- 5 files changed, 13 insertions(+), 17 deletions(-)
tools/perf/tests/attr.c +1 -2
@@ -171,6 +171,5 @@ int test__attr(void) !lstat(path_perf, &st))return run_dir (path_dir, path_perf); -fprintf (stderr," (omitted)" ); -return 0 ; +return TEST_SKIP ; }
tools/perf/tests/code-reading.c +4 -4
@@ -613,16 +613,16 @@ int test__code_reading(void)case TEST_CODE_READING_OK :return 0 ;case TEST_CODE_READING_NO_VMLINUX : -fprintf (stderr," (no vmlinux)" ); +pr_debug ("no vmlinux\n" );return 0 ;case TEST_CODE_READING_NO_KCORE : -fprintf (stderr," (no kcore)" ); +pr_debug ("no kcore\n" );return 0 ;case TEST_CODE_READING_NO_ACCESS : -fprintf (stderr," (no access)" ); +pr_debug ("no access\n" );return 0 ;case TEST_CODE_READING_NO_KERNEL_OBJ : -fprintf (stderr," (no kernel obj)" ); +pr_debug ("no kernel obj\n" );return 0 ;default :return -1 ;
tools/perf/tests/keep-tracking.c +2 -2
@@ -90,8 +90,8 @@ int test__keep_tracking(void) evsel->attr.enable_on_exec =0 ;if (perf_evlist__open (evlist) <0 ) { -fprintf (stderr," (not supported)" ); - err =0 ; +pr_debug ("Unable to open dummy and cycles event\n" ); + err =TEST_SKIP ; goto out_err; }
tools/perf/tests/llvm.c +4 -7
@@ -36,7 +36,7 @@ static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)static int test__bpf_parsing (void *obj_buf__maybe_unused ,size_t obj_buf_sz__maybe_unused ) { -fprintf (stderr," (skip bpf parsing)" ); +pr_debug ("Skip bpf parsing\n" );return 0 ; }#endif
@@ -55,7 +55,7 @@ int test__llvm(void)* and clang is not found in $PATH, and this is not perf test -v */ if (verbose ==0 && !llvm_param.user_set_param &&llvm__search_clang ()) { -fprintf (stderr," (no clang, try 'perf test -v LLVM')" ); +pr_debug ("No clang and no verbosive, skip this test\n" );return TEST_SKIP ; }
@@ -86,11 +86,8 @@ int test__llvm(void) err =llvm__compile_bpf ("-" , &obj_buf, &obj_buf_sz); verbose = old_verbose; -if (err) { -if (!verbose) -fprintf (stderr," (use -v to see error message)" ); -return -1 ; - } +if (err) +return TEST_FAIL ; err =test__bpf_parsing (obj_buf, obj_buf_sz);free (obj_buf);
tools/perf/tests/switch-tracking.c +2 -2
@@ -366,7 +366,7 @@ int test__switch_tracking(void)/* Third event */ if (!perf_evlist__can_select_event (evlist, sched_switch)) { -fprintf (stderr," (no sched_switch)" ); +pr_debug ("No sched_switch\n" ); err =0 ; goto out; }
@@ -442,7 +442,7 @@ int test__switch_tracking(void) }if (perf_evlist__open (evlist) <0 ) { -fprintf (stderr," (not supported)" ); +pr_debug ("Not supported\n" ); err =0 ; goto out; }
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 2/12 perf bpf: Mute libbpf when '-v' not set
In reply to Arnaldo Carvalho de MeloFrom: Wang Nan <[email protected]>
According to [1], libbpf should be muted. This patch reset info and warning message level to ensure libbpf doesn't output anything even if error happened.
[1] http://lkml.kernel.org/r/[email protected]
Committer note:
Before:
Testing it with an incompatible kernel version in the .c file that generated foo.o:
[root@zoo ~]# perf record -e /tmp/foo.o sleep 1
libbpf: load bpf program failed: Invalid argument
libbpf: -- BEGIN DUMP LOG ---
libbpf:
libbpf: -- END LOG --
libbpf: failed to load program 'fork=_do_fork'
libbpf: failed to load object '/tmp/foo.o'
event syntax error: '/tmp/foo.o'
\___ Invalid argument: Are you root and runing a CONFIG_BPF_SYSCALL kernel?
(add -v to see detail)
Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list available events
[root@zoo ~]#
After:
[root@zoo ~]# perf record -e /tmp/foo.o sleep 1
event syntax error: '/tmp/foo.o'
\___ Invalid argument: Are you root and runing a CONFIG_BPF_SYSCALL kernel?
(add -v to see detail)
Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list available events
[root@zoo ~]#
This, BTW, need fixing to emit a proper message by validating the version in the foo.o "version" ELF section against the running kernel, warning the user instead of asking the kernel to load a binary that it will refuse due to unmatching kernel version.
--- tools/perf/util/bpf-loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/bpf-loader.c +2 -2
@@ -26,8 +26,8 @@ static int libbpf_##name(const char *fmt, ...) \return ret; \ } -DEFINE_PRINT_FN(warning, 0) -DEFINE_PRINT_FN(info, 0) +DEFINE_PRINT_FN(warning, 1) +DEFINE_PRINT_FN(info, 1) DEFINE_PRINT_FN(debug, 1)struct bpf_prog_priv {
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 3/12 tools lib bpf: Fix compiler warning on CentOS 6
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
CC libbpf.o
cc1: warnings being treated as errors
libbpf.c: In function 'bpf_program__title':
libbpf.c:1037: error: declaration of 'dup' shadows a global declaration /usr/include/unistd.h:528: error: shadowed declaration is here
mv: cannot stat `./.libbpf.o.tmp': No such file or directory make[3]: *** [libbpf.o] Error 1
make[2]: *** [libbpf-in.o] Error 2
make[1]: *** [/linux/tools/lib/bpf/libbpf.a] Error 2 make[1]: *** Waiting for unfinished jobs....
--- tools/lib/bpf/libbpf.c | 4 ++-- tools/lib/bpf/libbpf.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
tools/lib/bpf/libbpf.c +2 -2
@@ -1034,12 +1034,12 @@ int bpf_program__get_private(struct bpf_program *prog, void **ppriv)return 0 ; } -const char *bpf_program__title (struct bpf_program *prog,bool dup) +const char *bpf_program__title (struct bpf_program *prog,bool needs_copy) {const char *title; title = prog->section_name; -if (dup) { +if (needs_copy) { title =strdup (title);if (!title) {pr_warning ("failed to strdup program title\n" );
tools/lib/bpf/libbpf.h +1 -1
@@ -63,7 +63,7 @@ int bpf_program__set_private(struct bpf_program *prog, void *priv,int bpf_program__get_private (struct bpf_program *prog,void **ppriv); -const char *bpf_program__title (struct bpf_program *prog,bool dup); +const char *bpf_program__title (struct bpf_program *prog,bool needs_copy);int bpf_program__fd (struct bpf_program *prog);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 4/12 perf stat: Move sw clock metrics printout to stat-shadow
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
The sw clock metrics printing was missed in the earlier move to stat-shadow of all the other metric printouts. Move it too.
v2: Fix metrics printing in this version to make bisect safe.
--- tools/perf/builtin-stat.c | 8 +++----- tools/perf/util/stat-shadow.c | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +3 -5
@@ -493,6 +493,7 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)double msecs = avg /1e6 ;const char *fmt_v, *fmt_n;char name[25 ]; +int cpu =cpu_map__id_to_cpu (id); fmt_v = csv_output ?"%.6f%s" :"%18.6f%s" ; fmt_n = csv_output ?"%s" :"%-25s" ;
@@ -517,11 +518,8 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)if (csv_output || stat_config.interval)return ; -if (perf_evsel__match (evsel,SOFTWARE ,SW_TASK_CLOCK )) -fprintf (output," # %8.3f CPUs utilized " , - avg /avg_stats (&walltime_nsecs_stats)); -else -fprintf (output," " ); +perf_stat__print_shadow_stats (output, evsel, avg, cpu, + stat_config.aggr_mode); }static void abs_printout (int id,int nr,struct perf_evsel *evsel,double avg)
tools/perf/util/stat-shadow.c +5 -0
@@ -413,6 +413,11 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel, ratio = total / avg;fprintf (out," # %8.0f cycles / elision " , ratio); + }else if (perf_evsel__match (evsel,SOFTWARE ,SW_TASK_CLOCK )) { +if ((ratio =avg_stats (&walltime_nsecs_stats)) !=0 ) +fprintf (out," # %8.3f CPUs utilized " , avg / ratio); +else +fprintf (out," " ); }else if (runtime_nsecs_stats[cpu].n !=0 ) {char unit ='M' ;
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 5/12 perf stat: Use common printout function to avoid duplicated code
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Instead of every caller deciding whether to call abs or nsec printout do it all in a single central function. No functional changes.
--- tools/perf/builtin-stat.c | 57 +++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 37 deletions(-)
tools/perf/builtin-stat.c +20 -37
@@ -493,7 +493,6 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)double msecs = avg /1e6 ;const char *fmt_v, *fmt_n;char name[25 ]; -int cpu =cpu_map__id_to_cpu (id); fmt_v = csv_output ?"%.6f%s" :"%18.6f%s" ; fmt_n = csv_output ?"%s" :"%-25s" ;
@@ -514,12 +513,6 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)if (evsel->cgrp)fprintf (output,"%s%s" , csv_sep, evsel->cgrp->name); - -if (csv_output || stat_config.interval) -return ; - -perf_stat__print_shadow_stats (output, evsel, avg, cpu, - stat_config.aggr_mode); }static void abs_printout (int id,int nr,struct perf_evsel *evsel,double avg)
@@ -527,7 +520,6 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)FILE *output = stat_config.output;double sc = evsel->scale;const char *fmt; -int cpu =cpu_map__id_to_cpu (id);if (csv_output) { fmt = sc !=1.0 ?"%.2f%s" :"%.0f%s" ;
@@ -540,9 +532,6 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)aggr_printout (evsel, id, nr); -if (stat_config.aggr_mode ==AGGR_GLOBAL ) - cpu =0 ; -fprintf (output, fmt, avg, csv_sep);if (evsel->unit)
@@ -554,12 +543,24 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)if (evsel->cgrp)fprintf (output,"%s%s" , csv_sep, evsel->cgrp->name); +} -if (csv_output || stat_config.interval) -return ; +static void printout (int id,int nr,struct perf_evsel *counter,double uval) +{ +int cpu =cpu_map__id_to_cpu (id); + +if (stat_config.aggr_mode ==AGGR_GLOBAL ) + cpu =0 ; + +if (nsec_counter (counter)) +nsec_printout (id, nr, counter, uval); +else +abs_printout (id, nr, counter, uval); -perf_stat__print_shadow_stats (output, evsel, avg, cpu, - stat_config.aggr_mode); +if (!csv_output && !stat_config.interval) +perf_stat__print_shadow_stats (stat_config.output, counter, + uval, cpu, + stat_config.aggr_mode); }static void print_aggr (char *prefix)
@@ -615,12 +616,7 @@ static void print_aggr(char *prefix)continue ; } uval = val * counter->scale; - -if (nsec_counter (counter)) -nsec_printout (id, nr, counter, uval); -else -abs_printout (id, nr, counter, uval); - +printout (id, nr, counter, uval);if (!csv_output)print_noise (counter,1.0 );
@@ -651,11 +647,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); uval = val * counter->scale; - -if (nsec_counter (counter)) -nsec_printout (thread,0 , counter, uval); -else -abs_printout (thread,0 , counter, uval); +printout (thread,0 , counter, uval);if (!csv_output)print_noise (counter,1.0 );
@@ -705,11 +697,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix) } uval = avg * counter->scale; - -if (nsec_counter (counter)) -nsec_printout (-1 ,0 , counter, uval); -else -abs_printout (-1 ,0 , counter, uval); +printout (-1 ,0 , counter, uval);print_noise (counter, avg);
@@ -762,12 +750,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix) } uval = val * counter->scale; - -if (nsec_counter (counter)) -nsec_printout (cpu,0 , counter, uval); -else -abs_printout (cpu,0 , counter, uval); - +printout (cpu,0 , counter, uval);if (!csv_output)print_noise (counter,1.0 );print_running (run, ena);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 6/12 perf tools: Insert split maps correctly into origin group
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
When new maps are cloned out of split map they are added into origin map's group, but their groups pointer is not updated.
This could lead to a segfault, because map->groups is expected to be always set as reported by Markus:
__map__is_kernel (map=map@entry=0x1abb7a0) at util/map.c:238
238 return __machine__kernel_map(map->groups->machine, map->type) =
(gdb) bt
#0 __map__is_kernel (map=map@entry=0x1abb7a0) at util/map.c:238 #1 0x00000000004393e4 in symbol_filter (map=map@entry=0x1abb7a0, sym=sym@entry #2 0x00000000004fcd4d in dso__load_sym (dso=dso@entry=0x166dae0, map=map@entry #3 0x00000000004a64e0 in dso__load (dso=0x166dae0, map=map@entry=0x1abb7a0, fi #4 0x00000000004b941f in map__load (filter=0x4393c0 <symbol_filter>, map=<opti #5 map__find_symbol (map=0x1abb7a0, addr=40188, filter=0x4393c0 <symbol_filter
...
Adding __map_groups__insert function to add map into groups together with map->groups pointer update. It takes no lock as opposed to existing map_groups__insert, as maps__fixup_overlappings(), where it is being called, already has the necessary lock held.
Using __map_groups__insert to add new maps after map split.
--- tools/perf/util/map.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
tools/perf/util/map.c +8 -2
@@ -644,6 +644,12 @@ size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)return printed; } +static void __map_groups__insert (struct map_groups *mg,struct map *map) +{ +__maps__insert (&mg->maps[map->type], map); + map->groups = mg; +} +static int maps__fixup_overlappings (struct maps *maps,struct map *map,FILE *fp) {struct rb_root *root;
@@ -682,7 +688,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp } before->end = map->start; -__maps__insert (maps, before); +__map_groups__insert (pos->groups, before);if (verbose >=2 )map__fprintf (before, fp); }
@@ -696,7 +702,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp } after->start = map->end; -__maps__insert (maps, after); +__map_groups__insert (pos->groups, after);if (verbose >=2 )map__fprintf (after, fp); }
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 7/12 perf tools: Allow shuffling the build tests
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Those tests take a long time and sometimes we stop it, so allow randomly shuffling the tests so that we have a better chance of running more of them in partial 'make build-test' runs.
Using it just on the 'build-test' target, i.e.:
make -C tools/perf build-test
Is equivalent to:
make SHUF=1 -C tools/perf -f tests/make
--- tools/perf/Makefile | 2 +- tools/perf/tests/make | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-)
tools/perf/Makefile +1 -1
@@ -78,7 +78,7 @@ clean: # The build-test target is not really parallel, don't print the jobs info: # build-test: - @$(MAKE) -f tests/make --no-print-directory + @$(MAKE) SHUF=1 -f tests/make --no-print-directory # # All other targets get passed through:
tools/perf/tests/make +5 -0
@@ -221,6 +221,11 @@ test_O = $(if $(test_$1),$(test_$1),$(test_default_O)) all: +ifdef SHUF +run := $(shell shuf -e $(run)) +run_O := $(shell shuf -e $(run_O)) +endif + ifdef DEBUG d := $(info run $(run)) d := $(info run_O $(run_O))
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 8/12 perf llvm: Pass available CPU number to clang compiler
In reply to Arnaldo Carvalho de MeloFrom: Wang Nan <[email protected]>
This patch introduces a new macro "__NR_CPUS__" to perf's embedded clang compiler, which represent the available CPU counters in this system. BPF program can use this macro to create a map with same number of system CPUs. For exmaple:
struct bpf_map_def SEC("maps") pmu_map = {
.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(u32),
.max_entries = __NR_CPUS__,
};
--- tools/perf/util/llvm-utils.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
tools/perf/util/llvm-utils.c +18 -6
@@ -11,10 +11,11 @@#include "cache.h" #define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ - "$CLANG_EXEC -D__KERNEL__ $CLANG_OPTIONS " \ - "$KERNEL_INC_OPTIONS -Wno-unused-value " \ - "-Wno-pointer-sign -working-directory " \ - "$WORKING_DIR -c \"$CLANG_SOURCE\" -target bpf -O2 -o -" + "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ + "$CLANG_OPTIONS $KERNEL_INC_OPTIONS " \ + "-Wno-unused-value -Wno-pointer-sign " \ + "-working-directory $WORKING_DIR " \ + "-c \"$CLANG_SOURCE\" -target bpf -O2 -o -"struct llvm_param llvm_param = { .clang_path ="clang" ,
@@ -326,8 +327,8 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)int llvm__compile_bpf (const char *path,void **p_obj_buf,size_t *p_obj_buf_sz) { -int err; -char clang_path[PATH_MAX ]; +int err, nr_cpus_avail; +char clang_path[PATH_MAX ], nr_cpus_avail_str[64 ];const char *clang_opt = llvm_param.clang_opt;const char *template = llvm_param.clang_bpf_cmd_template;char *kbuild_dir =NULL , *kbuild_include_opts =NULL ;
@@ -354,6 +355,17 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,*/ get_kbuild_opts (&kbuild_dir, &kbuild_include_opts); + 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" ,strerror (errno)); + nr_cpus_avail =128 ; + } +snprintf (nr_cpus_avail_str,sizeof (nr_cpus_avail_str),"%d" , + nr_cpus_avail); + +force_set_env ("NR_CPUS" , nr_cpus_avail_str);force_set_env ("CLANG_EXEC" , clang_path);force_set_env ("CLANG_OPTIONS" , clang_opt);force_set_env ("KERNEL_INC_OPTIONS" , kbuild_include_opts);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 9/12 perf llvm: Pass LINUX_VERSION_CODE to BPF program when compiling
In reply to Arnaldo Carvalho de MeloFrom: Wang Nan <[email protected]>
Arnaldo suggests to make LINUX_VERSION_CODE works like __func__ and __FILE__ so user don't need to care setting right linux version too much. In this patch, perf llvm transfers LINUX_VERSION_CODE macro through clang cmdline.
[1] http://lkml.kernel.org/r/[email protected]
Committer notes:
Before, forgetting to update the version:
# uname -r
4.3.0-rc1+
# cat bpf.c
__attribute__((section("fork=_do_fork"), used))
int fork(void *ctx)
{
return 1;
} char _license[] __attribute__((section("license"), used)) = "GPL";
int _version __attribute__((section("version"), used)) = 0x40200;
#
# perf record -e bpf.c sleep 1
event syntax error: 'bpf.c'
\___ Invalid argument: Are you root and runing a CONFIG_BPF_SYSCALL kernel? (add -v to see detail)
Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list available events
#
After:
# grep version bpf.c
int _version __attribute__((section("version"), used)) = LINUX_VERSION_CODE;
# perf record -e bpf.c sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data ]
# perf evlist -v
perf_bpf_probe:fork: type: 2, size: 112, config: 0x5ee, { sample_period,
sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, disabled: 1,
inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all:
1, exclude_guest: 1, mmap2: 1, comm_exec: 1
#--- tools/perf/util/llvm-utils.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
tools/perf/util/llvm-utils.c +27 -0
@@ -12,6 +12,7 @@#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ + "-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE " \ "$CLANG_OPTIONS $KERNEL_INC_OPTIONS " \ "-Wno-unused-value -Wno-pointer-sign " \ "-working-directory $WORKING_DIR " \
@@ -324,11 +325,33 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)pr_debug ("include option is set to %s\n" , *kbuild_include_opts); } +static unsigned long +fetch_kernel_version (void ) +{ +struct utsname utsname; +int version, patchlevel, sublevel, err; + +if (uname (&utsname)) +return 0 ; + + err =sscanf (utsname.release,"%d.%d.%d" , + &version, &patchlevel, &sublevel); + +if (err !=3 ) { +pr_debug ("Unablt to get kernel version from uname '%s'\n" , + utsname.release); +return 0 ; + } + +return (version <<16 ) + (patchlevel <<8 ) + sublevel; +} +int llvm__compile_bpf (const char *path,void **p_obj_buf,size_t *p_obj_buf_sz) {int err, nr_cpus_avail;char clang_path[PATH_MAX ], nr_cpus_avail_str[64 ]; +char linux_version_code_str[64 ];const char *clang_opt = llvm_param.clang_opt;const char *template = llvm_param.clang_bpf_cmd_template;char *kbuild_dir =NULL , *kbuild_include_opts =NULL ;
@@ -365,7 +388,11 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,snprintf (nr_cpus_avail_str,sizeof (nr_cpus_avail_str),"%d" , nr_cpus_avail); +snprintf (linux_version_code_str,sizeof (linux_version_code_str), +"0x%lx" ,fetch_kernel_version ()); +force_set_env ("NR_CPUS" , nr_cpus_avail_str); +force_set_env ("LINUX_VERSION_CODE" , linux_version_code_str);force_set_env ("CLANG_EXEC" , clang_path);force_set_env ("CLANG_OPTIONS" , clang_opt);force_set_env ("KERNEL_INC_OPTIONS" , kbuild_include_opts);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 10/12 tools lib bpf: Change FEATURE-DUMP to FEATURE-DUMP.libbpf
In reply to Arnaldo Carvalho de MeloFrom: Yunlong Song <[email protected]>
Commit ed63f34c026e9a60d17fa750ecdfe3f600d49393 ("perf tools: Make perf depend on libbpf") triggers the build of libbpf when building the perf tools, dynamically creating FEATURE-DUMP.libbpf.
It failed to update the tools/lib/bpf/.gitignore file to have that prefix, fix it.
--- tools/lib/bpf/.gitignore | 2 +- tools/lib/bpf/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/lib/bpf/.gitignore +1 -1
@@ -1,2 +1,2 @@ libbpf_version.h -FEATURE-DUMP +FEATURE-DUMP.libbpf
tools/lib/bpf/Makefile +1 -1
@@ -180,7 +180,7 @@ config-clean: clean: $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ $(RM) LIBBPF-CFLAGS - $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP + $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 11/12 perf trace: Fix documentation for -i
In reply to Arnaldo Carvalho de MeloFrom: Peter Feiner <[email protected]>
The -i flag was incorrectly listed as a short flag for --no-inherit. It should have only been listed as a short flag for --input.
This documentation error has existed since the --input flag was introduced in 6810fc915f7a89d8134edb3996dbbf8eac386c26 (perf trace: Add option to analyze events in a file versus live).
--- tools/perf/Documentation/perf-trace.txt | 1 - 1 file changed, 1 deletion(-)
tools/perf/Documentation/perf-trace.txt +0 -1
@@ -62,7 +62,6 @@ OPTIONS --verbose=:: Verbosity level. --i:: --no-inherit:: Child tasks do not inherit counters.
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 12/12 perf tools: Fix find_perf_probe_point_from_map() which incorrectly returns success
In reply to Arnaldo Carvalho de MeloFrom: Wang Nan <[email protected]>
It is possible that find_perf_probe_point_from_map() fails to find a symbol but still returns 0 because of an small error when coding:find_perf_probe_point_from_map() set 'ret' to error code at first, but also use it to hold return value of kernel_get_symbol_address_by_name().
This patch resets 'ret' to error even kernel_get_symbol_address_by_name() success, so if !sym, the whole function returns error correctly.
--- tools/perf/util/probe-event.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/probe-event.c +3 -0
@@ -1905,6 +1905,9 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp, sym =__find_kernel_function (addr, &map); } } + +/* ret may has be overwritten so reset it */ + ret = -ENOENT ;if (!sym) goto out;
Signature · 1 line
2.1.0