aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-15 12:36:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-15 12:36:24 -0500
commit0ca9b67606f0ce984b5811b0830cfd7d143f6077 (patch)
tree0352af98e9760edd8bbd1712cd0c79f77156217a /tools/perf
parent051b29f2798b5f1a95e745613117eeb367ab4bce (diff)
parent41ac18ebfc429ce3f4d369ef07447d652999a0cd (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Thomas Gleixner: "Mostly updates to the perf tool plus two fixes to the kernel core code: - Handle tracepoint filters correctly for inherited events (Peter Zijlstra) - Prevent a deadlock in perf_lock_task_context (Paul McKenney) - Add missing newlines to some pr_err() calls (Arnaldo Carvalho de Melo) - Print full source file paths when using 'perf annotate --print-line --full-paths' (Michael Petlan) - Fix 'perf probe -d' when just one out of uprobes and kprobes is enabled (Wang Nan) - Add compiler.h to list.h to fix 'make perf-tar-src-pkg' generated tarballs, i.e. out of tree building (Arnaldo Carvalho de Melo) - Add the llvm-src-base.c and llvm-src-kbuild.c files, generated by the 'perf test' LLVM entries, when running it in-tree, to .gitignore (Yunlong Song) - libbpf error reporting improvements, using a strerror interface to more precisely tell the user about problems with the provided scriptlet, be it in C or as a ready made object file (Wang Nan) - Do not be case sensitive when searching for matching 'perf test' entries (Arnaldo Carvalho de Melo) - Inform the user about objdump failures in 'perf annotate' (Andi Kleen) - Improve the LLVM 'perf test' entry, introduce a new ones for BPF and kbuild tests to check the environment used by clang to compile .c scriptlets (Wang Nan)" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (32 commits) perf/x86/intel/rapl: Remove the unused RAPL_EVENT_DESC() macro tools include: Add compiler.h to list.h perf probe: Verify parameters in two functions perf session: Add missing newlines to some pr_err() calls perf annotate: Support full source file paths for srcline fix perf test: Add llvm-src-base.c and llvm-src-kbuild.c to .gitignore perf: Fix inherited events vs. tracepoint filters perf: Disable IRQs across RCU RS CS that acquires scheduler lock perf test: Do not be case sensitive when searching for matching tests perf test: Add 'perf test BPF' perf test: Enhance the LLVM tests: add kbuild test perf test: Enhance the LLVM test: update basic BPF test program perf bpf: Improve BPF related error messages perf tools: Make fetch_kernel_version() publicly available bpf tools: Add new API bpf_object__get_kversion() bpf tools: Improve libbpf error reporting perf probe: Cleanup find_perf_probe_point_from_map to reduce redundancy perf annotate: Inform the user about objdump failures in --stdio perf stat: Make stat options global perf sched latency: Fix thread pid reuse issue ...
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-trace.txt1
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-sched.c5
-rw-r--r--tools/perf/builtin-stat.c222
-rw-r--r--tools/perf/tests/.gitignore2
-rw-r--r--tools/perf/tests/Build17
-rw-r--r--tools/perf/tests/attr.c3
-rw-r--r--tools/perf/tests/bpf-script-example.c4
-rw-r--r--tools/perf/tests/bpf-script-test-kbuild.c21
-rw-r--r--tools/perf/tests/bpf.c209
-rw-r--r--tools/perf/tests/builtin-test.c6
-rw-r--r--tools/perf/tests/code-reading.c8
-rw-r--r--tools/perf/tests/keep-tracking.c4
-rw-r--r--tools/perf/tests/llvm.c146
-rw-r--r--tools/perf/tests/llvm.h18
-rw-r--r--tools/perf/tests/make5
-rw-r--r--tools/perf/tests/switch-tracking.c4
-rw-r--r--tools/perf/tests/tests.h1
-rw-r--r--tools/perf/util/annotate.c21
-rw-r--r--tools/perf/util/bpf-loader.c143
-rw-r--r--tools/perf/util/bpf-loader.h33
-rw-r--r--tools/perf/util/llvm-utils.c54
-rw-r--r--tools/perf/util/map.c10
-rw-r--r--tools/perf/util/parse-events.c11
-rw-r--r--tools/perf/util/probe-event.c6
-rw-r--r--tools/perf/util/probe-file.c6
-rw-r--r--tools/perf/util/session.c8
-rw-r--r--tools/perf/util/stat-shadow.c5
-rw-r--r--tools/perf/util/util.c30
-rw-r--r--tools/perf/util/util.h8
30 files changed, 789 insertions, 224 deletions
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 7ea078658a87..13293de8869f 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -62,7 +62,6 @@ OPTIONS
62--verbose=:: 62--verbose=::
63 Verbosity level. 63 Verbosity level.
64 64
65-i::
66--no-inherit:: 65--no-inherit::
67 Child tasks do not inherit counters. 66 Child tasks do not inherit counters.
68 67
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 480546d5f13b..dcd9a70c7193 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -78,7 +78,7 @@ clean:
78# The build-test target is not really parallel, don't print the jobs info: 78# The build-test target is not really parallel, don't print the jobs info:
79# 79#
80build-test: 80build-test:
81 @$(MAKE) -f tests/make --no-print-directory 81 @$(MAKE) SHUF=1 -f tests/make --no-print-directory
82 82
83# 83#
84# All other targets get passed through: 84# All other targets get passed through:
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 0ee6d900e100..e3d3e32c0a93 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1203,12 +1203,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
1203 1203
1204static int pid_cmp(struct work_atoms *l, struct work_atoms *r) 1204static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
1205{ 1205{
1206 if (l->thread == r->thread)
1207 return 0;
1206 if (l->thread->tid < r->thread->tid) 1208 if (l->thread->tid < r->thread->tid)
1207 return -1; 1209 return -1;
1208 if (l->thread->tid > r->thread->tid) 1210 if (l->thread->tid > r->thread->tid)
1209 return 1; 1211 return 1;
1210 1212 return (int)(l->thread - r->thread);
1211 return 0;
1212} 1213}
1213 1214
1214static int avg_cmp(struct work_atoms *l, struct work_atoms *r) 1215static int avg_cmp(struct work_atoms *l, struct work_atoms *r)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2f438f76cceb..e77880b5094d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -122,6 +122,9 @@ static bool forever = false;
122static struct timespec ref_time; 122static struct timespec ref_time;
123static struct cpu_map *aggr_map; 123static struct cpu_map *aggr_map;
124static aggr_get_id_t aggr_get_id; 124static aggr_get_id_t aggr_get_id;
125static bool append_file;
126static const char *output_name;
127static int output_fd;
125 128
126static volatile int done = 0; 129static volatile int done = 0;
127 130
@@ -513,15 +516,6 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
513 516
514 if (evsel->cgrp) 517 if (evsel->cgrp)
515 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 518 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
516
517 if (csv_output || stat_config.interval)
518 return;
519
520 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
521 fprintf(output, " # %8.3f CPUs utilized ",
522 avg / avg_stats(&walltime_nsecs_stats));
523 else
524 fprintf(output, " ");
525} 519}
526 520
527static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) 521static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
@@ -529,7 +523,6 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
529 FILE *output = stat_config.output; 523 FILE *output = stat_config.output;
530 double sc = evsel->scale; 524 double sc = evsel->scale;
531 const char *fmt; 525 const char *fmt;
532 int cpu = cpu_map__id_to_cpu(id);
533 526
534 if (csv_output) { 527 if (csv_output) {
535 fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; 528 fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s";
@@ -542,9 +535,6 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
542 535
543 aggr_printout(evsel, id, nr); 536 aggr_printout(evsel, id, nr);
544 537
545 if (stat_config.aggr_mode == AGGR_GLOBAL)
546 cpu = 0;
547
548 fprintf(output, fmt, avg, csv_sep); 538 fprintf(output, fmt, avg, csv_sep);
549 539
550 if (evsel->unit) 540 if (evsel->unit)
@@ -556,12 +546,24 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
556 546
557 if (evsel->cgrp) 547 if (evsel->cgrp)
558 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 548 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
549}
559 550
560 if (csv_output || stat_config.interval) 551static void printout(int id, int nr, struct perf_evsel *counter, double uval)
561 return; 552{
553 int cpu = cpu_map__id_to_cpu(id);
554
555 if (stat_config.aggr_mode == AGGR_GLOBAL)
556 cpu = 0;
562 557
563 perf_stat__print_shadow_stats(output, evsel, avg, cpu, 558 if (nsec_counter(counter))
564 stat_config.aggr_mode); 559 nsec_printout(id, nr, counter, uval);
560 else
561 abs_printout(id, nr, counter, uval);
562
563 if (!csv_output && !stat_config.interval)
564 perf_stat__print_shadow_stats(stat_config.output, counter,
565 uval, cpu,
566 stat_config.aggr_mode);
565} 567}
566 568
567static void print_aggr(char *prefix) 569static void print_aggr(char *prefix)
@@ -617,12 +619,7 @@ static void print_aggr(char *prefix)
617 continue; 619 continue;
618 } 620 }
619 uval = val * counter->scale; 621 uval = val * counter->scale;
620 622 printout(id, nr, counter, uval);
621 if (nsec_counter(counter))
622 nsec_printout(id, nr, counter, uval);
623 else
624 abs_printout(id, nr, counter, uval);
625
626 if (!csv_output) 623 if (!csv_output)
627 print_noise(counter, 1.0); 624 print_noise(counter, 1.0);
628 625
@@ -653,11 +650,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
653 fprintf(output, "%s", prefix); 650 fprintf(output, "%s", prefix);
654 651
655 uval = val * counter->scale; 652 uval = val * counter->scale;
656 653 printout(thread, 0, counter, uval);
657 if (nsec_counter(counter))
658 nsec_printout(thread, 0, counter, uval);
659 else
660 abs_printout(thread, 0, counter, uval);
661 654
662 if (!csv_output) 655 if (!csv_output)
663 print_noise(counter, 1.0); 656 print_noise(counter, 1.0);
@@ -707,11 +700,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
707 } 700 }
708 701
709 uval = avg * counter->scale; 702 uval = avg * counter->scale;
710 703 printout(-1, 0, counter, uval);
711 if (nsec_counter(counter))
712 nsec_printout(-1, 0, counter, uval);
713 else
714 abs_printout(-1, 0, counter, uval);
715 704
716 print_noise(counter, avg); 705 print_noise(counter, avg);
717 706
@@ -764,12 +753,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
764 } 753 }
765 754
766 uval = val * counter->scale; 755 uval = val * counter->scale;
767 756 printout(cpu, 0, counter, uval);
768 if (nsec_counter(counter))
769 nsec_printout(cpu, 0, counter, uval);
770 else
771 abs_printout(cpu, 0, counter, uval);
772
773 if (!csv_output) 757 if (!csv_output)
774 print_noise(counter, 1.0); 758 print_noise(counter, 1.0);
775 print_running(run, ena); 759 print_running(run, ena);
@@ -946,6 +930,67 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
946 return 0; 930 return 0;
947} 931}
948 932
933static const struct option stat_options[] = {
934 OPT_BOOLEAN('T', "transaction", &transaction_run,
935 "hardware transaction statistics"),
936 OPT_CALLBACK('e', "event", &evsel_list, "event",
937 "event selector. use 'perf list' to list available events",
938 parse_events_option),
939 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
940 "event filter", parse_filter),
941 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
942 "child tasks do not inherit counters"),
943 OPT_STRING('p', "pid", &target.pid, "pid",
944 "stat events on existing process id"),
945 OPT_STRING('t', "tid", &target.tid, "tid",
946 "stat events on existing thread id"),
947 OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
948 "system-wide collection from all CPUs"),
949 OPT_BOOLEAN('g', "group", &group,
950 "put the counters into a counter group"),
951 OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
952 OPT_INCR('v', "verbose", &verbose,
953 "be more verbose (show counter open errors, etc)"),
954 OPT_INTEGER('r', "repeat", &run_count,
955 "repeat command and print average + stddev (max: 100, forever: 0)"),
956 OPT_BOOLEAN('n', "null", &null_run,
957 "null run - dont start any counters"),
958 OPT_INCR('d', "detailed", &detailed_run,
959 "detailed run - start a lot of events"),
960 OPT_BOOLEAN('S', "sync", &sync_run,
961 "call sync() before starting a run"),
962 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
963 "print large numbers with thousands\' separators",
964 stat__set_big_num),
965 OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
966 "list of cpus to monitor in system-wide"),
967 OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
968 "disable CPU count aggregation", AGGR_NONE),
969 OPT_STRING('x', "field-separator", &csv_sep, "separator",
970 "print counts with custom separator"),
971 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
972 "monitor event in cgroup name only", parse_cgroups),
973 OPT_STRING('o', "output", &output_name, "file", "output file name"),
974 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
975 OPT_INTEGER(0, "log-fd", &output_fd,
976 "log output to fd, instead of stderr"),
977 OPT_STRING(0, "pre", &pre_cmd, "command",
978 "command to run prior to the measured command"),
979 OPT_STRING(0, "post", &post_cmd, "command",
980 "command to run after to the measured command"),
981 OPT_UINTEGER('I', "interval-print", &stat_config.interval,
982 "print counts at regular interval in ms (>= 10)"),
983 OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
984 "aggregate counts per processor socket", AGGR_SOCKET),
985 OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
986 "aggregate counts per physical processor core", AGGR_CORE),
987 OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
988 "aggregate counts per thread", AGGR_THREAD),
989 OPT_UINTEGER('D', "delay", &initial_delay,
990 "ms to wait before starting measurement after program start"),
991 OPT_END()
992};
993
949static int perf_stat__get_socket(struct cpu_map *map, int cpu) 994static int perf_stat__get_socket(struct cpu_map *map, int cpu)
950{ 995{
951 return cpu_map__get_socket(map, cpu, NULL); 996 return cpu_map__get_socket(map, cpu, NULL);
@@ -1193,69 +1238,6 @@ static int add_default_attributes(void)
1193 1238
1194int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) 1239int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1195{ 1240{
1196 bool append_file = false;
1197 int output_fd = 0;
1198 const char *output_name = NULL;
1199 const struct option options[] = {
1200 OPT_BOOLEAN('T', "transaction", &transaction_run,
1201 "hardware transaction statistics"),
1202 OPT_CALLBACK('e', "event", &evsel_list, "event",
1203 "event selector. use 'perf list' to list available events",
1204 parse_events_option),
1205 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1206 "event filter", parse_filter),
1207 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1208 "child tasks do not inherit counters"),
1209 OPT_STRING('p', "pid", &target.pid, "pid",
1210 "stat events on existing process id"),
1211 OPT_STRING('t', "tid", &target.tid, "tid",
1212 "stat events on existing thread id"),
1213 OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1214 "system-wide collection from all CPUs"),
1215 OPT_BOOLEAN('g', "group", &group,
1216 "put the counters into a counter group"),
1217 OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
1218 OPT_INCR('v', "verbose", &verbose,
1219 "be more verbose (show counter open errors, etc)"),
1220 OPT_INTEGER('r', "repeat", &run_count,
1221 "repeat command and print average + stddev (max: 100, forever: 0)"),
1222 OPT_BOOLEAN('n', "null", &null_run,
1223 "null run - dont start any counters"),
1224 OPT_INCR('d', "detailed", &detailed_run,
1225 "detailed run - start a lot of events"),
1226 OPT_BOOLEAN('S', "sync", &sync_run,
1227 "call sync() before starting a run"),
1228 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1229 "print large numbers with thousands\' separators",
1230 stat__set_big_num),
1231 OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1232 "list of cpus to monitor in system-wide"),
1233 OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
1234 "disable CPU count aggregation", AGGR_NONE),
1235 OPT_STRING('x', "field-separator", &csv_sep, "separator",
1236 "print counts with custom separator"),
1237 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1238 "monitor event in cgroup name only", parse_cgroups),
1239 OPT_STRING('o', "output", &output_name, "file", "output file name"),
1240 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1241 OPT_INTEGER(0, "log-fd", &output_fd,
1242 "log output to fd, instead of stderr"),
1243 OPT_STRING(0, "pre", &pre_cmd, "command",
1244 "command to run prior to the measured command"),
1245 OPT_STRING(0, "post", &post_cmd, "command",
1246 "command to run after to the measured command"),
1247 OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1248 "print counts at regular interval in ms (>= 10)"),
1249 OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1250 "aggregate counts per processor socket", AGGR_SOCKET),
1251 OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
1252 "aggregate counts per physical processor core", AGGR_CORE),
1253 OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
1254 "aggregate counts per thread", AGGR_THREAD),
1255 OPT_UINTEGER('D', "delay", &initial_delay,
1256 "ms to wait before starting measurement after program start"),
1257 OPT_END()
1258 };
1259 const char * const stat_usage[] = { 1241 const char * const stat_usage[] = {
1260 "perf stat [<options>] [<command>]", 1242 "perf stat [<options>] [<command>]",
1261 NULL 1243 NULL
@@ -1271,7 +1253,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1271 if (evsel_list == NULL) 1253 if (evsel_list == NULL)
1272 return -ENOMEM; 1254 return -ENOMEM;
1273 1255
1274 argc = parse_options(argc, argv, options, stat_usage, 1256 argc = parse_options(argc, argv, stat_options, stat_usage,
1275 PARSE_OPT_STOP_AT_NON_OPTION); 1257 PARSE_OPT_STOP_AT_NON_OPTION);
1276 1258
1277 interval = stat_config.interval; 1259 interval = stat_config.interval;
@@ -1281,14 +1263,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1281 1263
1282 if (output_name && output_fd) { 1264 if (output_name && output_fd) {
1283 fprintf(stderr, "cannot use both --output and --log-fd\n"); 1265 fprintf(stderr, "cannot use both --output and --log-fd\n");
1284 parse_options_usage(stat_usage, options, "o", 1); 1266 parse_options_usage(stat_usage, stat_options, "o", 1);
1285 parse_options_usage(NULL, options, "log-fd", 0); 1267 parse_options_usage(NULL, stat_options, "log-fd", 0);
1286 goto out; 1268 goto out;
1287 } 1269 }
1288 1270
1289 if (output_fd < 0) { 1271 if (output_fd < 0) {
1290 fprintf(stderr, "argument to --log-fd must be a > 0\n"); 1272 fprintf(stderr, "argument to --log-fd must be a > 0\n");
1291 parse_options_usage(stat_usage, options, "log-fd", 0); 1273 parse_options_usage(stat_usage, stat_options, "log-fd", 0);
1292 goto out; 1274 goto out;
1293 } 1275 }
1294 1276
@@ -1328,8 +1310,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1328 /* User explicitly passed -B? */ 1310 /* User explicitly passed -B? */
1329 if (big_num_opt == 1) { 1311 if (big_num_opt == 1) {
1330 fprintf(stderr, "-B option not supported with -x\n"); 1312 fprintf(stderr, "-B option not supported with -x\n");
1331 parse_options_usage(stat_usage, options, "B", 1); 1313 parse_options_usage(stat_usage, stat_options, "B", 1);
1332 parse_options_usage(NULL, options, "x", 1); 1314 parse_options_usage(NULL, stat_options, "x", 1);
1333 goto out; 1315 goto out;
1334 } else /* Nope, so disable big number formatting */ 1316 } else /* Nope, so disable big number formatting */
1335 big_num = false; 1317 big_num = false;
@@ -1337,11 +1319,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1337 big_num = false; 1319 big_num = false;
1338 1320
1339 if (!argc && target__none(&target)) 1321 if (!argc && target__none(&target))
1340 usage_with_options(stat_usage, options); 1322 usage_with_options(stat_usage, stat_options);
1341 1323
1342 if (run_count < 0) { 1324 if (run_count < 0) {
1343 pr_err("Run count must be a positive number\n"); 1325 pr_err("Run count must be a positive number\n");
1344 parse_options_usage(stat_usage, options, "r", 1); 1326 parse_options_usage(stat_usage, stat_options, "r", 1);
1345 goto out; 1327 goto out;
1346 } else if (run_count == 0) { 1328 } else if (run_count == 0) {
1347 forever = true; 1329 forever = true;
@@ -1351,8 +1333,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1351 if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) { 1333 if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
1352 fprintf(stderr, "The --per-thread option is only available " 1334 fprintf(stderr, "The --per-thread option is only available "
1353 "when monitoring via -p -t options.\n"); 1335 "when monitoring via -p -t options.\n");
1354 parse_options_usage(NULL, options, "p", 1); 1336 parse_options_usage(NULL, stat_options, "p", 1);
1355 parse_options_usage(NULL, options, "t", 1); 1337 parse_options_usage(NULL, stat_options, "t", 1);
1356 goto out; 1338 goto out;
1357 } 1339 }
1358 1340
@@ -1366,9 +1348,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1366 fprintf(stderr, "both cgroup and no-aggregation " 1348 fprintf(stderr, "both cgroup and no-aggregation "
1367 "modes only available in system-wide mode\n"); 1349 "modes only available in system-wide mode\n");
1368 1350
1369 parse_options_usage(stat_usage, options, "G", 1); 1351 parse_options_usage(stat_usage, stat_options, "G", 1);
1370 parse_options_usage(NULL, options, "A", 1); 1352 parse_options_usage(NULL, stat_options, "A", 1);
1371 parse_options_usage(NULL, options, "a", 1); 1353 parse_options_usage(NULL, stat_options, "a", 1);
1372 goto out; 1354 goto out;
1373 } 1355 }
1374 1356
@@ -1380,12 +1362,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1380 if (perf_evlist__create_maps(evsel_list, &target) < 0) { 1362 if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1381 if (target__has_task(&target)) { 1363 if (target__has_task(&target)) {
1382 pr_err("Problems finding threads of monitor\n"); 1364 pr_err("Problems finding threads of monitor\n");
1383 parse_options_usage(stat_usage, options, "p", 1); 1365 parse_options_usage(stat_usage, stat_options, "p", 1);
1384 parse_options_usage(NULL, options, "t", 1); 1366 parse_options_usage(NULL, stat_options, "t", 1);
1385 } else if (target__has_cpu(&target)) { 1367 } else if (target__has_cpu(&target)) {
1386 perror("failed to parse CPUs map"); 1368 perror("failed to parse CPUs map");
1387 parse_options_usage(stat_usage, options, "C", 1); 1369 parse_options_usage(stat_usage, stat_options, "C", 1);
1388 parse_options_usage(NULL, options, "a", 1); 1370 parse_options_usage(NULL, stat_options, "a", 1);
1389 } 1371 }
1390 goto out; 1372 goto out;
1391 } 1373 }
@@ -1400,7 +1382,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1400 if (interval && interval < 100) { 1382 if (interval && interval < 100) {
1401 if (interval < 10) { 1383 if (interval < 10) {
1402 pr_err("print interval must be >= 10ms\n"); 1384 pr_err("print interval must be >= 10ms\n");
1403 parse_options_usage(stat_usage, options, "I", 1); 1385 parse_options_usage(stat_usage, stat_options, "I", 1);
1404 goto out; 1386 goto out;
1405 } else 1387 } else
1406 pr_warning("print interval < 100ms. " 1388 pr_warning("print interval < 100ms. "
diff --git a/tools/perf/tests/.gitignore b/tools/perf/tests/.gitignore
new file mode 100644
index 000000000000..489fc9ffbcb0
--- /dev/null
+++ b/tools/perf/tests/.gitignore
@@ -0,0 +1,2 @@
1llvm-src-base.c
2llvm-src-kbuild.c
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 50de2253cff6..f41ebf8849fe 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -31,9 +31,24 @@ perf-y += sample-parsing.o
31perf-y += parse-no-sample-id-all.o 31perf-y += parse-no-sample-id-all.o
32perf-y += kmod-path.o 32perf-y += kmod-path.o
33perf-y += thread-map.o 33perf-y += thread-map.o
34perf-y += llvm.o 34perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o
35perf-y += bpf.o
35perf-y += topology.o 36perf-y += topology.o
36 37
38$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c
39 $(call rule_mkdir)
40 $(Q)echo '#include <tests/llvm.h>' > $@
41 $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@
42 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
43 $(Q)echo ';' >> $@
44
45$(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c
46 $(call rule_mkdir)
47 $(Q)echo '#include <tests/llvm.h>' > $@
48 $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@
49 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
50 $(Q)echo ';' >> $@
51
37ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) 52ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
38perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o 53perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
39endif 54endif
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index 2dfc9ad0e6f2..638875a0960a 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -171,6 +171,5 @@ int test__attr(void)
171 !lstat(path_perf, &st)) 171 !lstat(path_perf, &st))
172 return run_dir(path_dir, path_perf); 172 return run_dir(path_dir, path_perf);
173 173
174 fprintf(stderr, " (omitted)"); 174 return TEST_SKIP;
175 return 0;
176} 175}
diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c
index 410a70b93b93..0ec9c2c03164 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -1,3 +1,7 @@
1/*
2 * bpf-script-example.c
3 * Test basic LLVM building
4 */
1#ifndef LINUX_VERSION_CODE 5#ifndef LINUX_VERSION_CODE
2# error Need LINUX_VERSION_CODE 6# error Need LINUX_VERSION_CODE
3# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' 7# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
diff --git a/tools/perf/tests/bpf-script-test-kbuild.c b/tools/perf/tests/bpf-script-test-kbuild.c
new file mode 100644
index 000000000000..3626924740d8
--- /dev/null
+++ b/tools/perf/tests/bpf-script-test-kbuild.c
@@ -0,0 +1,21 @@
1/*
2 * bpf-script-test-kbuild.c
3 * Test include from kernel header
4 */
5#ifndef LINUX_VERSION_CODE
6# error Need LINUX_VERSION_CODE
7# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
8#endif
9#define SEC(NAME) __attribute__((section(NAME), used))
10
11#include <uapi/linux/fs.h>
12#include <uapi/asm/ptrace.h>
13
14SEC("func=vfs_llseek")
15int bpf_func__vfs_llseek(void *ctx)
16{
17 return 0;
18}
19
20char _license[] SEC("license") = "GPL";
21int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
new file mode 100644
index 000000000000..ec16f7812c8b
--- /dev/null
+++ b/tools/perf/tests/bpf.c
@@ -0,0 +1,209 @@
1#include <stdio.h>
2#include <sys/epoll.h>
3#include <util/bpf-loader.h>
4#include <util/evlist.h>
5#include "tests.h"
6#include "llvm.h"
7#include "debug.h"
8#define NR_ITERS 111
9
10#ifdef HAVE_LIBBPF_SUPPORT
11
12static int epoll_pwait_loop(void)
13{
14 int i;
15
16 /* Should fail NR_ITERS times */
17 for (i = 0; i < NR_ITERS; i++)
18 epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
19 return 0;
20}
21
22static struct {
23 enum test_llvm__testcase prog_id;
24 const char *desc;
25 const char *name;
26 const char *msg_compile_fail;
27 const char *msg_load_fail;
28 int (*target_func)(void);
29 int expect_result;
30} bpf_testcase_table[] = {
31 {
32 LLVM_TESTCASE_BASE,
33 "Test basic BPF filtering",
34 "[basic_bpf_test]",
35 "fix 'perf test LLVM' first",
36 "load bpf object failed",
37 &epoll_pwait_loop,
38 (NR_ITERS + 1) / 2,
39 },
40};
41
42static int do_test(struct bpf_object *obj, int (*func)(void),
43 int expect)
44{
45 struct record_opts opts = {
46 .target = {
47 .uid = UINT_MAX,
48 .uses_mmap = true,
49 },
50 .freq = 0,
51 .mmap_pages = 256,
52 .default_interval = 1,
53 };
54
55 char pid[16];
56 char sbuf[STRERR_BUFSIZE];
57 struct perf_evlist *evlist;
58 int i, ret = TEST_FAIL, err = 0, count = 0;
59
60 struct parse_events_evlist parse_evlist;
61 struct parse_events_error parse_error;
62
63 bzero(&parse_error, sizeof(parse_error));
64 bzero(&parse_evlist, sizeof(parse_evlist));
65 parse_evlist.error = &parse_error;
66 INIT_LIST_HEAD(&parse_evlist.list);
67
68 err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj);
69 if (err || list_empty(&parse_evlist.list)) {
70 pr_debug("Failed to add events selected by BPF\n");
71 if (!err)
72 return TEST_FAIL;
73 }
74
75 snprintf(pid, sizeof(pid), "%d", getpid());
76 pid[sizeof(pid) - 1] = '\0';
77 opts.target.tid = opts.target.pid = pid;
78
79 /* Instead of perf_evlist__new_default, don't add default events */
80 evlist = perf_evlist__new();
81 if (!evlist) {
82 pr_debug("No ehough memory to create evlist\n");
83 return TEST_FAIL;
84 }
85
86 err = perf_evlist__create_maps(evlist, &opts.target);
87 if (err < 0) {
88 pr_debug("Not enough memory to create thread/cpu maps\n");
89 goto out_delete_evlist;
90 }
91
92 perf_evlist__splice_list_tail(evlist, &parse_evlist.list);
93 evlist->nr_groups = parse_evlist.nr_groups;
94
95 perf_evlist__config(evlist, &opts);
96
97 err = perf_evlist__open(evlist);
98 if (err < 0) {
99 pr_debug("perf_evlist__open: %s\n",
100 strerror_r(errno, sbuf, sizeof(sbuf)));
101 goto out_delete_evlist;
102 }
103
104 err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
105 if (err < 0) {
106 pr_debug("perf_evlist__mmap: %s\n",
107 strerror_r(errno, sbuf, sizeof(sbuf)));
108 goto out_delete_evlist;
109 }
110
111 perf_evlist__enable(evlist);
112 (*func)();
113 perf_evlist__disable(evlist);
114
115 for (i = 0; i < evlist->nr_mmaps; i++) {
116 union perf_event *event;
117
118 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
119 const u32 type = event->header.type;
120
121 if (type == PERF_RECORD_SAMPLE)
122 count ++;
123 }
124 }
125
126 if (count != expect)
127 pr_debug("BPF filter result incorrect\n");
128
129 ret = TEST_OK;
130
131out_delete_evlist:
132 perf_evlist__delete(evlist);
133 return ret;
134}
135
136static struct bpf_object *
137prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name)
138{
139 struct bpf_object *obj;
140
141 obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name);
142 if (IS_ERR(obj)) {
143 pr_debug("Compile BPF program failed.\n");
144 return NULL;
145 }
146 return obj;
147}
148
149static int __test__bpf(int index)
150{
151 int ret;
152 void *obj_buf;
153 size_t obj_buf_sz;
154 struct bpf_object *obj;
155
156 ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
157 bpf_testcase_table[index].prog_id,
158 true);
159 if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
160 pr_debug("Unable to get BPF object, %s\n",
161 bpf_testcase_table[index].msg_compile_fail);
162 if (index == 0)
163 return TEST_SKIP;
164 else
165 return TEST_FAIL;
166 }
167
168 obj = prepare_bpf(obj_buf, obj_buf_sz,
169 bpf_testcase_table[index].name);
170 if (!obj) {
171 ret = TEST_FAIL;
172 goto out;
173 }
174
175 ret = do_test(obj,
176 bpf_testcase_table[index].target_func,
177 bpf_testcase_table[index].expect_result);
178out:
179 bpf__clear();
180 return ret;
181}
182
183int test__bpf(void)
184{
185 unsigned int i;
186 int err;
187
188 if (geteuid() != 0) {
189 pr_debug("Only root can run BPF test\n");
190 return TEST_SKIP;
191 }
192
193 for (i = 0; i < ARRAY_SIZE(bpf_testcase_table); i++) {
194 err = __test__bpf(i);
195
196 if (err != TEST_OK)
197 return err;
198 }
199
200 return TEST_OK;
201}
202
203#else
204int test__bpf(void)
205{
206 pr_debug("Skip BPF test because BPF support is not compiled\n");
207 return TEST_SKIP;
208}
209#endif
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 66f72d3d6677..80c442eab767 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -166,6 +166,10 @@ static struct test generic_tests[] = {
166 .func = test_session_topology, 166 .func = test_session_topology,
167 }, 167 },
168 { 168 {
169 .desc = "Test BPF filter",
170 .func = test__bpf,
171 },
172 {
169 .func = NULL, 173 .func = NULL,
170 }, 174 },
171}; 175};
@@ -192,7 +196,7 @@ static bool perf_test__matches(struct test *test, int curr, int argc, const char
192 continue; 196 continue;
193 } 197 }
194 198
195 if (strstr(test->desc, argv[i])) 199 if (strcasestr(test->desc, argv[i]))
196 return true; 200 return true;
197 } 201 }
198 202
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 49b1959dda41..a767a6400c5c 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -613,16 +613,16 @@ int test__code_reading(void)
613 case TEST_CODE_READING_OK: 613 case TEST_CODE_READING_OK:
614 return 0; 614 return 0;
615 case TEST_CODE_READING_NO_VMLINUX: 615 case TEST_CODE_READING_NO_VMLINUX:
616 fprintf(stderr, " (no vmlinux)"); 616 pr_debug("no vmlinux\n");
617 return 0; 617 return 0;
618 case TEST_CODE_READING_NO_KCORE: 618 case TEST_CODE_READING_NO_KCORE:
619 fprintf(stderr, " (no kcore)"); 619 pr_debug("no kcore\n");
620 return 0; 620 return 0;
621 case TEST_CODE_READING_NO_ACCESS: 621 case TEST_CODE_READING_NO_ACCESS:
622 fprintf(stderr, " (no access)"); 622 pr_debug("no access\n");
623 return 0; 623 return 0;
624 case TEST_CODE_READING_NO_KERNEL_OBJ: 624 case TEST_CODE_READING_NO_KERNEL_OBJ:
625 fprintf(stderr, " (no kernel obj)"); 625 pr_debug("no kernel obj\n");
626 return 0; 626 return 0;
627 default: 627 default:
628 return -1; 628 return -1;
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 4d4b9837b630..a2e2269aa093 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -90,8 +90,8 @@ int test__keep_tracking(void)
90 evsel->attr.enable_on_exec = 0; 90 evsel->attr.enable_on_exec = 0;
91 91
92 if (perf_evlist__open(evlist) < 0) { 92 if (perf_evlist__open(evlist) < 0) {
93 fprintf(stderr, " (not supported)"); 93 pr_debug("Unable to open dummy and cycles event\n");
94 err = 0; 94 err = TEST_SKIP;
95 goto out_err; 95 goto out_err;
96 } 96 }
97 97
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index 52d55971f66f..bc4cf507cde5 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -2,6 +2,7 @@
2#include <bpf/libbpf.h> 2#include <bpf/libbpf.h>
3#include <util/llvm-utils.h> 3#include <util/llvm-utils.h>
4#include <util/cache.h> 4#include <util/cache.h>
5#include "llvm.h"
5#include "tests.h" 6#include "tests.h"
6#include "debug.h" 7#include "debug.h"
7 8
@@ -11,42 +12,58 @@ static int perf_config_cb(const char *var, const char *val,
11 return perf_default_config(var, val, arg); 12 return perf_default_config(var, val, arg);
12} 13}
13 14
14/*
15 * Randomly give it a "version" section since we don't really load it
16 * into kernel
17 */
18static const char test_bpf_prog[] =
19 "__attribute__((section(\"do_fork\"), used)) "
20 "int fork(void *ctx) {return 0;} "
21 "char _license[] __attribute__((section(\"license\"), used)) = \"GPL\";"
22 "int _version __attribute__((section(\"version\"), used)) = 0x40100;";
23
24#ifdef HAVE_LIBBPF_SUPPORT 15#ifdef HAVE_LIBBPF_SUPPORT
25static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) 16static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
26{ 17{
27 struct bpf_object *obj; 18 struct bpf_object *obj;
28 19
29 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL); 20 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL);
30 if (!obj) 21 if (IS_ERR(obj))
31 return -1; 22 return TEST_FAIL;
32 bpf_object__close(obj); 23 bpf_object__close(obj);
33 return 0; 24 return TEST_OK;
34} 25}
35#else 26#else
36static int test__bpf_parsing(void *obj_buf __maybe_unused, 27static int test__bpf_parsing(void *obj_buf __maybe_unused,
37 size_t obj_buf_sz __maybe_unused) 28 size_t obj_buf_sz __maybe_unused)
38{ 29{
39 fprintf(stderr, " (skip bpf parsing)"); 30 pr_debug("Skip bpf parsing\n");
40 return 0; 31 return TEST_OK;
41} 32}
42#endif 33#endif
43 34
44int test__llvm(void) 35static struct {
36 const char *source;
37 const char *desc;
38} bpf_source_table[__LLVM_TESTCASE_MAX] = {
39 [LLVM_TESTCASE_BASE] = {
40 .source = test_llvm__bpf_base_prog,
41 .desc = "Basic BPF llvm compiling test",
42 },
43 [LLVM_TESTCASE_KBUILD] = {
44 .source = test_llvm__bpf_test_kbuild_prog,
45 .desc = "Test kbuild searching",
46 },
47};
48
49
50int
51test_llvm__fetch_bpf_obj(void **p_obj_buf,
52 size_t *p_obj_buf_sz,
53 enum test_llvm__testcase index,
54 bool force)
45{ 55{
46 char *tmpl_new, *clang_opt_new; 56 const char *source;
47 void *obj_buf; 57 const char *desc;
48 size_t obj_buf_sz; 58 const char *tmpl_old, *clang_opt_old;
49 int err, old_verbose; 59 char *tmpl_new = NULL, *clang_opt_new = NULL;
60 int err, old_verbose, ret = TEST_FAIL;
61
62 if (index >= __LLVM_TESTCASE_MAX)
63 return TEST_FAIL;
64
65 source = bpf_source_table[index].source;
66 desc = bpf_source_table[index].desc;
50 67
51 perf_config(perf_config_cb, NULL); 68 perf_config(perf_config_cb, NULL);
52 69
@@ -54,45 +71,100 @@ int test__llvm(void)
54 * Skip this test if user's .perfconfig doesn't set [llvm] section 71 * Skip this test if user's .perfconfig doesn't set [llvm] section
55 * and clang is not found in $PATH, and this is not perf test -v 72 * and clang is not found in $PATH, and this is not perf test -v
56 */ 73 */
57 if (verbose == 0 && !llvm_param.user_set_param && llvm__search_clang()) { 74 if (!force && (verbose == 0 &&
58 fprintf(stderr, " (no clang, try 'perf test -v LLVM')"); 75 !llvm_param.user_set_param &&
76 llvm__search_clang())) {
77 pr_debug("No clang and no verbosive, skip this test\n");
59 return TEST_SKIP; 78 return TEST_SKIP;
60 } 79 }
61 80
62 old_verbose = verbose;
63 /* 81 /*
64 * llvm is verbosity when error. Suppress all error output if 82 * llvm is verbosity when error. Suppress all error output if
65 * not 'perf test -v'. 83 * not 'perf test -v'.
66 */ 84 */
85 old_verbose = verbose;
67 if (verbose == 0) 86 if (verbose == 0)
68 verbose = -1; 87 verbose = -1;
69 88
89 *p_obj_buf = NULL;
90 *p_obj_buf_sz = 0;
91
70 if (!llvm_param.clang_bpf_cmd_template) 92 if (!llvm_param.clang_bpf_cmd_template)
71 return -1; 93 goto out;
72 94
73 if (!llvm_param.clang_opt) 95 if (!llvm_param.clang_opt)
74 llvm_param.clang_opt = strdup(""); 96 llvm_param.clang_opt = strdup("");
75 97
76 err = asprintf(&tmpl_new, "echo '%s' | %s", test_bpf_prog, 98 err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
77 llvm_param.clang_bpf_cmd_template); 99 llvm_param.clang_bpf_cmd_template,
100 old_verbose ? "" : " 2>/dev/null");
78 if (err < 0) 101 if (err < 0)
79 return -1; 102 goto out;
80 err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt); 103 err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
81 if (err < 0) 104 if (err < 0)
82 return -1; 105 goto out;
83 106
107 tmpl_old = llvm_param.clang_bpf_cmd_template;
84 llvm_param.clang_bpf_cmd_template = tmpl_new; 108 llvm_param.clang_bpf_cmd_template = tmpl_new;
109 clang_opt_old = llvm_param.clang_opt;
85 llvm_param.clang_opt = clang_opt_new; 110 llvm_param.clang_opt = clang_opt_new;
86 err = llvm__compile_bpf("-", &obj_buf, &obj_buf_sz); 111
112 err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
113
114 llvm_param.clang_bpf_cmd_template = tmpl_old;
115 llvm_param.clang_opt = clang_opt_old;
87 116
88 verbose = old_verbose; 117 verbose = old_verbose;
89 if (err) { 118 if (err)
90 if (!verbose) 119 goto out;
91 fprintf(stderr, " (use -v to see error message)"); 120
92 return -1; 121 ret = TEST_OK;
93 } 122out:
123 free(tmpl_new);
124 free(clang_opt_new);
125 if (ret != TEST_OK)
126 pr_debug("Failed to compile test case: '%s'\n", desc);
127 return ret;
128}
129
130int test__llvm(void)
131{
132 enum test_llvm__testcase i;
133
134 for (i = 0; i < __LLVM_TESTCASE_MAX; i++) {
135 int ret;
136 void *obj_buf = NULL;
137 size_t obj_buf_sz = 0;
138
139 ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
140 i, false);
94 141
95 err = test__bpf_parsing(obj_buf, obj_buf_sz); 142 if (ret == TEST_OK) {
96 free(obj_buf); 143 ret = test__bpf_parsing(obj_buf, obj_buf_sz);
97 return err; 144 if (ret != TEST_OK)
145 pr_debug("Failed to parse test case '%s'\n",
146 bpf_source_table[i].desc);
147 }
148 free(obj_buf);
149
150 switch (ret) {
151 case TEST_SKIP:
152 return TEST_SKIP;
153 case TEST_OK:
154 break;
155 default:
156 /*
157 * Test 0 is the basic LLVM test. If test 0
158 * fail, the basic LLVM support not functional
159 * so the whole test should fail. If other test
160 * case fail, it can be fixed by adjusting
161 * config so don't report error.
162 */
163 if (i == 0)
164 return TEST_FAIL;
165 else
166 return TEST_SKIP;
167 }
168 }
169 return TEST_OK;
98} 170}
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
new file mode 100644
index 000000000000..d91d8f44efee
--- /dev/null
+++ b/tools/perf/tests/llvm.h
@@ -0,0 +1,18 @@
1#ifndef PERF_TEST_LLVM_H
2#define PERF_TEST_LLVM_H
3
4#include <stddef.h> /* for size_t */
5#include <stdbool.h> /* for bool */
6
7extern const char test_llvm__bpf_base_prog[];
8extern const char test_llvm__bpf_test_kbuild_prog[];
9
10enum test_llvm__testcase {
11 LLVM_TESTCASE_BASE,
12 LLVM_TESTCASE_KBUILD,
13 __LLVM_TESTCASE_MAX,
14};
15
16int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz,
17 enum test_llvm__testcase index, bool force);
18#endif
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 2cbd0c6901e3..8ea3dffc5065 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -221,6 +221,11 @@ test_O = $(if $(test_$1),$(test_$1),$(test_default_O))
221 221
222all: 222all:
223 223
224ifdef SHUF
225run := $(shell shuf -e $(run))
226run_O := $(shell shuf -e $(run_O))
227endif
228
224ifdef DEBUG 229ifdef DEBUG
225d := $(info run $(run)) 230d := $(info run $(run))
226d := $(info run_O $(run_O)) 231d := $(info run_O $(run_O))
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index e698742d4fec..a02af503100c 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -366,7 +366,7 @@ int test__switch_tracking(void)
366 366
367 /* Third event */ 367 /* Third event */
368 if (!perf_evlist__can_select_event(evlist, sched_switch)) { 368 if (!perf_evlist__can_select_event(evlist, sched_switch)) {
369 fprintf(stderr, " (no sched_switch)"); 369 pr_debug("No sched_switch\n");
370 err = 0; 370 err = 0;
371 goto out; 371 goto out;
372 } 372 }
@@ -442,7 +442,7 @@ int test__switch_tracking(void)
442 } 442 }
443 443
444 if (perf_evlist__open(evlist) < 0) { 444 if (perf_evlist__open(evlist) < 0) {
445 fprintf(stderr, " (not supported)"); 445 pr_debug("Not supported\n");
446 err = 0; 446 err = 0;
447 goto out; 447 goto out;
448 } 448 }
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index c80486969f83..3c8734a3abbc 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -66,6 +66,7 @@ int test__fdarray__add(void);
66int test__kmod_path__parse(void); 66int test__kmod_path__parse(void);
67int test__thread_map(void); 67int test__thread_map(void);
68int test__llvm(void); 68int test__llvm(void);
69int test__bpf(void);
69int test_session_topology(void); 70int test_session_topology(void);
70 71
71#if defined(__arm__) || defined(__aarch64__) 72#if defined(__arm__) || defined(__aarch64__)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 0fc8d7a2fea5..1dd1949b0e79 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1084,6 +1084,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
1084 struct kcore_extract kce; 1084 struct kcore_extract kce;
1085 bool delete_extract = false; 1085 bool delete_extract = false;
1086 int lineno = 0; 1086 int lineno = 0;
1087 int nline;
1087 1088
1088 if (filename) 1089 if (filename)
1089 symbol__join_symfs(symfs_filename, filename); 1090 symbol__join_symfs(symfs_filename, filename);
@@ -1179,6 +1180,9 @@ fallback:
1179 1180
1180 ret = decompress_to_file(m.ext, symfs_filename, fd); 1181 ret = decompress_to_file(m.ext, symfs_filename, fd);
1181 1182
1183 if (ret)
1184 pr_err("Cannot decompress %s %s\n", m.ext, symfs_filename);
1185
1182 free(m.ext); 1186 free(m.ext);
1183 close(fd); 1187 close(fd);
1184 1188
@@ -1204,13 +1208,25 @@ fallback:
1204 pr_debug("Executing: %s\n", command); 1208 pr_debug("Executing: %s\n", command);
1205 1209
1206 file = popen(command, "r"); 1210 file = popen(command, "r");
1207 if (!file) 1211 if (!file) {
1212 pr_err("Failure running %s\n", command);
1213 /*
1214 * If we were using debug info should retry with
1215 * original binary.
1216 */
1208 goto out_remove_tmp; 1217 goto out_remove_tmp;
1218 }
1209 1219
1210 while (!feof(file)) 1220 nline = 0;
1221 while (!feof(file)) {
1211 if (symbol__parse_objdump_line(sym, map, file, privsize, 1222 if (symbol__parse_objdump_line(sym, map, file, privsize,
1212 &lineno) < 0) 1223 &lineno) < 0)
1213 break; 1224 break;
1225 nline++;
1226 }
1227
1228 if (nline == 0)
1229 pr_err("No output from %s\n", command);
1214 1230
1215 /* 1231 /*
1216 * kallsyms does not have symbol sizes so there may a nop at the end. 1232 * kallsyms does not have symbol sizes so there may a nop at the end.
@@ -1604,6 +1620,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
1604 len = symbol__size(sym); 1620 len = symbol__size(sym);
1605 1621
1606 if (print_lines) { 1622 if (print_lines) {
1623 srcline_full_filename = full_paths;
1607 symbol__get_source_line(sym, map, evsel, &source_line, len); 1624 symbol__get_source_line(sym, map, evsel, &source_line, len);
1608 print_summary(&source_line, dso->long_name); 1625 print_summary(&source_line, dso->long_name);
1609 } 1626 }
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index ba6f7526b282..4c50411371db 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -26,18 +26,40 @@ static int libbpf_##name(const char *fmt, ...) \
26 return ret; \ 26 return ret; \
27} 27}
28 28
29DEFINE_PRINT_FN(warning, 0) 29DEFINE_PRINT_FN(warning, 1)
30DEFINE_PRINT_FN(info, 0) 30DEFINE_PRINT_FN(info, 1)
31DEFINE_PRINT_FN(debug, 1) 31DEFINE_PRINT_FN(debug, 1)
32 32
33struct bpf_prog_priv { 33struct bpf_prog_priv {
34 struct perf_probe_event pev; 34 struct perf_probe_event pev;
35}; 35};
36 36
37static bool libbpf_initialized;
38
39struct bpf_object *
40bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
41{
42 struct bpf_object *obj;
43
44 if (!libbpf_initialized) {
45 libbpf_set_print(libbpf_warning,
46 libbpf_info,
47 libbpf_debug);
48 libbpf_initialized = true;
49 }
50
51 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name);
52 if (IS_ERR(obj)) {
53 pr_debug("bpf: failed to load buffer\n");
54 return ERR_PTR(-EINVAL);
55 }
56
57 return obj;
58}
59
37struct bpf_object *bpf__prepare_load(const char *filename, bool source) 60struct bpf_object *bpf__prepare_load(const char *filename, bool source)
38{ 61{
39 struct bpf_object *obj; 62 struct bpf_object *obj;
40 static bool libbpf_initialized;
41 63
42 if (!libbpf_initialized) { 64 if (!libbpf_initialized) {
43 libbpf_set_print(libbpf_warning, 65 libbpf_set_print(libbpf_warning,
@@ -53,15 +75,15 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
53 75
54 err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz); 76 err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz);
55 if (err) 77 if (err)
56 return ERR_PTR(err); 78 return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
57 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); 79 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
58 free(obj_buf); 80 free(obj_buf);
59 } else 81 } else
60 obj = bpf_object__open(filename); 82 obj = bpf_object__open(filename);
61 83
62 if (!obj) { 84 if (IS_ERR(obj)) {
63 pr_debug("bpf: failed to load %s\n", filename); 85 pr_debug("bpf: failed to load %s\n", filename);
64 return ERR_PTR(-EINVAL); 86 return obj;
65 } 87 }
66 88
67 return obj; 89 return obj;
@@ -96,9 +118,9 @@ config_bpf_program(struct bpf_program *prog)
96 int err; 118 int err;
97 119
98 config_str = bpf_program__title(prog, false); 120 config_str = bpf_program__title(prog, false);
99 if (!config_str) { 121 if (IS_ERR(config_str)) {
100 pr_debug("bpf: unable to get title for program\n"); 122 pr_debug("bpf: unable to get title for program\n");
101 return -EINVAL; 123 return PTR_ERR(config_str);
102 } 124 }
103 125
104 priv = calloc(sizeof(*priv), 1); 126 priv = calloc(sizeof(*priv), 1);
@@ -113,14 +135,14 @@ config_bpf_program(struct bpf_program *prog)
113 if (err < 0) { 135 if (err < 0) {
114 pr_debug("bpf: '%s' is not a valid config string\n", 136 pr_debug("bpf: '%s' is not a valid config string\n",
115 config_str); 137 config_str);
116 err = -EINVAL; 138 err = -BPF_LOADER_ERRNO__CONFIG;
117 goto errout; 139 goto errout;
118 } 140 }
119 141
120 if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) { 142 if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
121 pr_debug("bpf: '%s': group for event is set and not '%s'.\n", 143 pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
122 config_str, PERF_BPF_PROBE_GROUP); 144 config_str, PERF_BPF_PROBE_GROUP);
123 err = -EINVAL; 145 err = -BPF_LOADER_ERRNO__GROUP;
124 goto errout; 146 goto errout;
125 } else if (!pev->group) 147 } else if (!pev->group)
126 pev->group = strdup(PERF_BPF_PROBE_GROUP); 148 pev->group = strdup(PERF_BPF_PROBE_GROUP);
@@ -132,9 +154,9 @@ config_bpf_program(struct bpf_program *prog)
132 } 154 }
133 155
134 if (!pev->event) { 156 if (!pev->event) {
135 pr_debug("bpf: '%s': event name is missing\n", 157 pr_debug("bpf: '%s': event name is missing. Section name should be 'key=value'\n",
136 config_str); 158 config_str);
137 err = -EINVAL; 159 err = -BPF_LOADER_ERRNO__EVENTNAME;
138 goto errout; 160 goto errout;
139 } 161 }
140 pr_debug("bpf: config '%s' is ok\n", config_str); 162 pr_debug("bpf: config '%s' is ok\n", config_str);
@@ -285,7 +307,7 @@ int bpf__foreach_tev(struct bpf_object *obj,
285 (void **)&priv); 307 (void **)&priv);
286 if (err || !priv) { 308 if (err || !priv) {
287 pr_debug("bpf: failed to get private field\n"); 309 pr_debug("bpf: failed to get private field\n");
288 return -EINVAL; 310 return -BPF_LOADER_ERRNO__INTERNAL;
289 } 311 }
290 312
291 pev = &priv->pev; 313 pev = &priv->pev;
@@ -308,13 +330,57 @@ int bpf__foreach_tev(struct bpf_object *obj,
308 return 0; 330 return 0;
309} 331}
310 332
333#define ERRNO_OFFSET(e) ((e) - __BPF_LOADER_ERRNO__START)
334#define ERRCODE_OFFSET(c) ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
335#define NR_ERRNO (__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
336
337static const char *bpf_loader_strerror_table[NR_ERRNO] = {
338 [ERRCODE_OFFSET(CONFIG)] = "Invalid config string",
339 [ERRCODE_OFFSET(GROUP)] = "Invalid group name",
340 [ERRCODE_OFFSET(EVENTNAME)] = "No event name found in config string",
341 [ERRCODE_OFFSET(INTERNAL)] = "BPF loader internal error",
342 [ERRCODE_OFFSET(COMPILE)] = "Error when compiling BPF scriptlet",
343};
344
345static int
346bpf_loader_strerror(int err, char *buf, size_t size)
347{
348 char sbuf[STRERR_BUFSIZE];
349 const char *msg;
350
351 if (!buf || !size)
352 return -1;
353
354 err = err > 0 ? err : -err;
355
356 if (err >= __LIBBPF_ERRNO__START)
357 return libbpf_strerror(err, buf, size);
358
359 if (err >= __BPF_LOADER_ERRNO__START && err < __BPF_LOADER_ERRNO__END) {
360 msg = bpf_loader_strerror_table[ERRNO_OFFSET(err)];
361 snprintf(buf, size, "%s", msg);
362 buf[size - 1] = '\0';
363 return 0;
364 }
365
366 if (err >= __BPF_LOADER_ERRNO__END)
367 snprintf(buf, size, "Unknown bpf loader error %d", err);
368 else
369 snprintf(buf, size, "%s",
370 strerror_r(err, sbuf, sizeof(sbuf)));
371
372 buf[size - 1] = '\0';
373 return -1;
374}
375
311#define bpf__strerror_head(err, buf, size) \ 376#define bpf__strerror_head(err, buf, size) \
312 char sbuf[STRERR_BUFSIZE], *emsg;\ 377 char sbuf[STRERR_BUFSIZE], *emsg;\
313 if (!size)\ 378 if (!size)\
314 return 0;\ 379 return 0;\
315 if (err < 0)\ 380 if (err < 0)\
316 err = -err;\ 381 err = -err;\
317 emsg = strerror_r(err, sbuf, sizeof(sbuf));\ 382 bpf_loader_strerror(err, sbuf, sizeof(sbuf));\
383 emsg = sbuf;\
318 switch (err) {\ 384 switch (err) {\
319 default:\ 385 default:\
320 scnprintf(buf, size, "%s", emsg);\ 386 scnprintf(buf, size, "%s", emsg);\
@@ -330,23 +396,62 @@ int bpf__foreach_tev(struct bpf_object *obj,
330 }\ 396 }\
331 buf[size - 1] = '\0'; 397 buf[size - 1] = '\0';
332 398
399int bpf__strerror_prepare_load(const char *filename, bool source,
400 int err, char *buf, size_t size)
401{
402 size_t n;
403 int ret;
404
405 n = snprintf(buf, size, "Failed to load %s%s: ",
406 filename, source ? " from source" : "");
407 if (n >= size) {
408 buf[size - 1] = '\0';
409 return 0;
410 }
411 buf += n;
412 size -= n;
413
414 ret = bpf_loader_strerror(err, buf, size);
415 buf[size - 1] = '\0';
416 return ret;
417}
418
333int bpf__strerror_probe(struct bpf_object *obj __maybe_unused, 419int bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
334 int err, char *buf, size_t size) 420 int err, char *buf, size_t size)
335{ 421{
336 bpf__strerror_head(err, buf, size); 422 bpf__strerror_head(err, buf, size);
337 bpf__strerror_entry(EEXIST, "Probe point exist. Try use 'perf probe -d \"*\"'"); 423 bpf__strerror_entry(EEXIST, "Probe point exist. Try use 'perf probe -d \"*\"'");
338 bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0\n"); 424 bpf__strerror_entry(EACCES, "You need to be root");
339 bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file\n"); 425 bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0");
426 bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file");
340 bpf__strerror_end(buf, size); 427 bpf__strerror_end(buf, size);
341 return 0; 428 return 0;
342} 429}
343 430
344int bpf__strerror_load(struct bpf_object *obj __maybe_unused, 431int bpf__strerror_load(struct bpf_object *obj,
345 int err, char *buf, size_t size) 432 int err, char *buf, size_t size)
346{ 433{
347 bpf__strerror_head(err, buf, size); 434 bpf__strerror_head(err, buf, size);
348 bpf__strerror_entry(EINVAL, "%s: Are you root and runing a CONFIG_BPF_SYSCALL kernel?", 435 case LIBBPF_ERRNO__KVER: {
349 emsg) 436 unsigned int obj_kver = bpf_object__get_kversion(obj);
437 unsigned int real_kver;
438
439 if (fetch_kernel_version(&real_kver, NULL, 0)) {
440 scnprintf(buf, size, "Unable to fetch kernel version");
441 break;
442 }
443
444 if (obj_kver != real_kver) {
445 scnprintf(buf, size,
446 "'version' ("KVER_FMT") doesn't match running kernel ("KVER_FMT")",
447 KVER_PARAM(obj_kver),
448 KVER_PARAM(real_kver));
449 break;
450 }
451
452 scnprintf(buf, size, "Failed to load program for unknown reason");
453 break;
454 }
350 bpf__strerror_end(buf, size); 455 bpf__strerror_end(buf, size);
351 return 0; 456 return 0;
352} 457}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index ccd8d7fd79d3..9caf3ae4acf3 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -8,9 +8,21 @@
8#include <linux/compiler.h> 8#include <linux/compiler.h>
9#include <linux/err.h> 9#include <linux/err.h>
10#include <string.h> 10#include <string.h>
11#include <bpf/libbpf.h>
11#include "probe-event.h" 12#include "probe-event.h"
12#include "debug.h" 13#include "debug.h"
13 14
15enum bpf_loader_errno {
16 __BPF_LOADER_ERRNO__START = __LIBBPF_ERRNO__START - 100,
17 /* Invalid config string */
18 BPF_LOADER_ERRNO__CONFIG = __BPF_LOADER_ERRNO__START,
19 BPF_LOADER_ERRNO__GROUP, /* Invalid group name */
20 BPF_LOADER_ERRNO__EVENTNAME, /* Event name is missing */
21 BPF_LOADER_ERRNO__INTERNAL, /* BPF loader internal error */
22 BPF_LOADER_ERRNO__COMPILE, /* Error when compiling BPF scriptlet */
23 __BPF_LOADER_ERRNO__END,
24};
25
14struct bpf_object; 26struct bpf_object;
15#define PERF_BPF_PROBE_GROUP "perf_bpf_probe" 27#define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
16 28
@@ -19,6 +31,11 @@ typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
19 31
20#ifdef HAVE_LIBBPF_SUPPORT 32#ifdef HAVE_LIBBPF_SUPPORT
21struct bpf_object *bpf__prepare_load(const char *filename, bool source); 33struct bpf_object *bpf__prepare_load(const char *filename, bool source);
34int bpf__strerror_prepare_load(const char *filename, bool source,
35 int err, char *buf, size_t size);
36
37struct bpf_object *bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz,
38 const char *name);
22 39
23void bpf__clear(void); 40void bpf__clear(void);
24 41
@@ -41,6 +58,13 @@ bpf__prepare_load(const char *filename __maybe_unused,
41 return ERR_PTR(-ENOTSUP); 58 return ERR_PTR(-ENOTSUP);
42} 59}
43 60
61static inline struct bpf_object *
62bpf__prepare_load_buffer(void *obj_buf __maybe_unused,
63 size_t obj_buf_sz __maybe_unused)
64{
65 return ERR_PTR(-ENOTSUP);
66}
67
44static inline void bpf__clear(void) { } 68static inline void bpf__clear(void) { }
45 69
46static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;} 70static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;}
@@ -67,6 +91,15 @@ __bpf_strerror(char *buf, size_t size)
67 return 0; 91 return 0;
68} 92}
69 93
94static inline
95int bpf__strerror_prepare_load(const char *filename __maybe_unused,
96 bool source __maybe_unused,
97 int err __maybe_unused,
98 char *buf, size_t size)
99{
100 return __bpf_strerror(buf, size);
101}
102
70static inline int 103static inline int
71bpf__strerror_probe(struct bpf_object *obj __maybe_unused, 104bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
72 int err __maybe_unused, 105 int err __maybe_unused,
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 4f6a4780bd5f..00724d496d38 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -4,17 +4,18 @@
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <sys/utsname.h>
8#include "util.h" 7#include "util.h"
9#include "debug.h" 8#include "debug.h"
10#include "llvm-utils.h" 9#include "llvm-utils.h"
11#include "cache.h" 10#include "cache.h"
12 11
13#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ 12#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \
14 "$CLANG_EXEC -D__KERNEL__ $CLANG_OPTIONS " \ 13 "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
15 "$KERNEL_INC_OPTIONS -Wno-unused-value " \ 14 "-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE " \
16 "-Wno-pointer-sign -working-directory " \ 15 "$CLANG_OPTIONS $KERNEL_INC_OPTIONS " \
17 "$WORKING_DIR -c \"$CLANG_SOURCE\" -target bpf -O2 -o -" 16 "-Wno-unused-value -Wno-pointer-sign " \
17 "-working-directory $WORKING_DIR " \
18 "-c \"$CLANG_SOURCE\" -target bpf -O2 -o -"
18 19
19struct llvm_param llvm_param = { 20struct llvm_param llvm_param = {
20 .clang_path = "clang", 21 .clang_path = "clang",
@@ -214,18 +215,19 @@ static int detect_kbuild_dir(char **kbuild_dir)
214 const char *suffix_dir = ""; 215 const char *suffix_dir = "";
215 216
216 char *autoconf_path; 217 char *autoconf_path;
217 struct utsname utsname;
218 218
219 int err; 219 int err;
220 220
221 if (!test_dir) { 221 if (!test_dir) {
222 err = uname(&utsname); 222 /* _UTSNAME_LENGTH is 65 */
223 if (err) { 223 char release[128];
224 pr_warning("uname failed: %s\n", strerror(errno)); 224
225 err = fetch_kernel_version(NULL, release,
226 sizeof(release));
227 if (err)
225 return -EINVAL; 228 return -EINVAL;
226 }
227 229
228 test_dir = utsname.release; 230 test_dir = release;
229 prefix_dir = "/lib/modules/"; 231 prefix_dir = "/lib/modules/";
230 suffix_dir = "/build"; 232 suffix_dir = "/build";
231 } 233 }
@@ -326,13 +328,15 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
326int llvm__compile_bpf(const char *path, void **p_obj_buf, 328int llvm__compile_bpf(const char *path, void **p_obj_buf,
327 size_t *p_obj_buf_sz) 329 size_t *p_obj_buf_sz)
328{ 330{
329 int err; 331 size_t obj_buf_sz;
330 char clang_path[PATH_MAX]; 332 void *obj_buf = NULL;
333 int err, nr_cpus_avail;
334 unsigned int kernel_version;
335 char linux_version_code_str[64];
331 const char *clang_opt = llvm_param.clang_opt; 336 const char *clang_opt = llvm_param.clang_opt;
332 const char *template = llvm_param.clang_bpf_cmd_template; 337 char clang_path[PATH_MAX], nr_cpus_avail_str[64];
333 char *kbuild_dir = NULL, *kbuild_include_opts = NULL; 338 char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
334 void *obj_buf = NULL; 339 const char *template = llvm_param.clang_bpf_cmd_template;
335 size_t obj_buf_sz;
336 340
337 if (!template) 341 if (!template)
338 template = CLANG_BPF_CMD_DEFAULT_TEMPLATE; 342 template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
@@ -354,6 +358,24 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
354 */ 358 */
355 get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); 359 get_kbuild_opts(&kbuild_dir, &kbuild_include_opts);
356 360
361 nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
362 if (nr_cpus_avail <= 0) {
363 pr_err(
364"WARNING:\tunable to get available CPUs in this system: %s\n"
365" \tUse 128 instead.\n", strerror(errno));
366 nr_cpus_avail = 128;
367 }
368 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
369 nr_cpus_avail);
370
371 if (fetch_kernel_version(&kernel_version, NULL, 0))
372 kernel_version = 0;
373
374 snprintf(linux_version_code_str, sizeof(linux_version_code_str),
375 "0x%x", kernel_version);
376
377 force_set_env("NR_CPUS", nr_cpus_avail_str);
378 force_set_env("LINUX_VERSION_CODE", linux_version_code_str);
357 force_set_env("CLANG_EXEC", clang_path); 379 force_set_env("CLANG_EXEC", clang_path);
358 force_set_env("CLANG_OPTIONS", clang_opt); 380 force_set_env("CLANG_OPTIONS", clang_opt);
359 force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts); 381 force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 4e38c396a897..afc6b56cf749 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -644,6 +644,12 @@ size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
644 return printed; 644 return printed;
645} 645}
646 646
647static void __map_groups__insert(struct map_groups *mg, struct map *map)
648{
649 __maps__insert(&mg->maps[map->type], map);
650 map->groups = mg;
651}
652
647static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) 653static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
648{ 654{
649 struct rb_root *root; 655 struct rb_root *root;
@@ -682,7 +688,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
682 } 688 }
683 689
684 before->end = map->start; 690 before->end = map->start;
685 __maps__insert(maps, before); 691 __map_groups__insert(pos->groups, before);
686 if (verbose >= 2) 692 if (verbose >= 2)
687 map__fprintf(before, fp); 693 map__fprintf(before, fp);
688 } 694 }
@@ -696,7 +702,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
696 } 702 }
697 703
698 after->start = map->end; 704 after->start = map->end;
699 __maps__insert(maps, after); 705 __map_groups__insert(pos->groups, after);
700 if (verbose >= 2) 706 if (verbose >= 2)
701 map__fprintf(after, fp); 707 map__fprintf(after, fp);
702 } 708 }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index bee60583839a..e48d9da75707 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -632,19 +632,20 @@ int parse_events_load_bpf(struct parse_events_evlist *data,
632 struct bpf_object *obj; 632 struct bpf_object *obj;
633 633
634 obj = bpf__prepare_load(bpf_file_name, source); 634 obj = bpf__prepare_load(bpf_file_name, source);
635 if (IS_ERR(obj) || !obj) { 635 if (IS_ERR(obj)) {
636 char errbuf[BUFSIZ]; 636 char errbuf[BUFSIZ];
637 int err; 637 int err;
638 638
639 err = obj ? PTR_ERR(obj) : -EINVAL; 639 err = PTR_ERR(obj);
640 640
641 if (err == -ENOTSUP) 641 if (err == -ENOTSUP)
642 snprintf(errbuf, sizeof(errbuf), 642 snprintf(errbuf, sizeof(errbuf),
643 "BPF support is not compiled"); 643 "BPF support is not compiled");
644 else 644 else
645 snprintf(errbuf, sizeof(errbuf), 645 bpf__strerror_prepare_load(bpf_file_name,
646 "BPF object file '%s' is invalid", 646 source,
647 bpf_file_name); 647 -err, errbuf,
648 sizeof(errbuf));
648 649
649 data->error->help = strdup("(add -v to see detail)"); 650 data->error->help = strdup("(add -v to see detail)");
650 data->error->str = strdup(errbuf); 651 data->error->str = strdup(errbuf);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index b51a8bfb40f9..03875f9154e7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1895,9 +1895,8 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
1895 sym = map__find_symbol(map, addr, NULL); 1895 sym = map__find_symbol(map, addr, NULL);
1896 } else { 1896 } else {
1897 if (tp->symbol && !addr) { 1897 if (tp->symbol && !addr) {
1898 ret = kernel_get_symbol_address_by_name(tp->symbol, 1898 if (kernel_get_symbol_address_by_name(tp->symbol,
1899 &addr, true, false); 1899 &addr, true, false) < 0)
1900 if (ret < 0)
1901 goto out; 1900 goto out;
1902 } 1901 }
1903 if (addr) { 1902 if (addr) {
@@ -1905,6 +1904,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
1905 sym = __find_kernel_function(addr, &map); 1904 sym = __find_kernel_function(addr, &map);
1906 } 1905 }
1907 } 1906 }
1907
1908 if (!sym) 1908 if (!sym)
1909 goto out; 1909 goto out;
1910 1910
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 89dbeb92c68e..e3b3b92e4458 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -138,6 +138,9 @@ struct strlist *probe_file__get_rawlist(int fd)
138 char *p; 138 char *p;
139 struct strlist *sl; 139 struct strlist *sl;
140 140
141 if (fd < 0)
142 return NULL;
143
141 sl = strlist__new(NULL, NULL); 144 sl = strlist__new(NULL, NULL);
142 145
143 fp = fdopen(dup(fd), "r"); 146 fp = fdopen(dup(fd), "r");
@@ -271,6 +274,9 @@ int probe_file__get_events(int fd, struct strfilter *filter,
271 const char *p; 274 const char *p;
272 int ret = -ENOENT; 275 int ret = -ENOENT;
273 276
277 if (!plist)
278 return -EINVAL;
279
274 namelist = __probe_file__get_namelist(fd, true); 280 namelist = __probe_file__get_namelist(fd, true);
275 if (!namelist) 281 if (!namelist)
276 return -ENOENT; 282 return -ENOENT;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 428149bc64d2..c35ffdd360fe 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -29,7 +29,7 @@ static int perf_session__open(struct perf_session *session)
29 struct perf_data_file *file = session->file; 29 struct perf_data_file *file = session->file;
30 30
31 if (perf_session__read_header(session) < 0) { 31 if (perf_session__read_header(session) < 0) {
32 pr_err("incompatible file format (rerun with -v to learn more)"); 32 pr_err("incompatible file format (rerun with -v to learn more)\n");
33 return -1; 33 return -1;
34 } 34 }
35 35
@@ -37,17 +37,17 @@ static int perf_session__open(struct perf_session *session)
37 return 0; 37 return 0;
38 38
39 if (!perf_evlist__valid_sample_type(session->evlist)) { 39 if (!perf_evlist__valid_sample_type(session->evlist)) {
40 pr_err("non matching sample_type"); 40 pr_err("non matching sample_type\n");
41 return -1; 41 return -1;
42 } 42 }
43 43
44 if (!perf_evlist__valid_sample_id_all(session->evlist)) { 44 if (!perf_evlist__valid_sample_id_all(session->evlist)) {
45 pr_err("non matching sample_id_all"); 45 pr_err("non matching sample_id_all\n");
46 return -1; 46 return -1;
47 } 47 }
48 48
49 if (!perf_evlist__valid_read_format(session->evlist)) { 49 if (!perf_evlist__valid_read_format(session->evlist)) {
50 pr_err("non matching read_format"); 50 pr_err("non matching read_format\n");
51 return -1; 51 return -1;
52 } 52 }
53 53
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 2a5d8d7698ae..6ac03146889d 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -413,6 +413,11 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
413 ratio = total / avg; 413 ratio = total / avg;
414 414
415 fprintf(out, " # %8.0f cycles / elision ", ratio); 415 fprintf(out, " # %8.0f cycles / elision ", ratio);
416 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) {
417 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
418 fprintf(out, " # %8.3f CPUs utilized ", avg / ratio);
419 else
420 fprintf(out, " ");
416 } else if (runtime_nsecs_stats[cpu].n != 0) { 421 } else if (runtime_nsecs_stats[cpu].n != 0) {
417 char unit = 'M'; 422 char unit = 'M';
418 423
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index cd12c25e4ea4..47b1e36c7ea0 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -3,6 +3,7 @@
3#include "debug.h" 3#include "debug.h"
4#include <api/fs/fs.h> 4#include <api/fs/fs.h>
5#include <sys/mman.h> 5#include <sys/mman.h>
6#include <sys/utsname.h>
6#ifdef HAVE_BACKTRACE_SUPPORT 7#ifdef HAVE_BACKTRACE_SUPPORT
7#include <execinfo.h> 8#include <execinfo.h>
8#endif 9#endif
@@ -665,3 +666,32 @@ bool find_process(const char *name)
665 closedir(dir); 666 closedir(dir);
666 return ret ? false : true; 667 return ret ? false : true;
667} 668}
669
670int
671fetch_kernel_version(unsigned int *puint, char *str,
672 size_t str_size)
673{
674 struct utsname utsname;
675 int version, patchlevel, sublevel, err;
676
677 if (uname(&utsname))
678 return -1;
679
680 if (str && str_size) {
681 strncpy(str, utsname.release, str_size);
682 str[str_size - 1] = '\0';
683 }
684
685 err = sscanf(utsname.release, "%d.%d.%d",
686 &version, &patchlevel, &sublevel);
687
688 if (err != 3) {
689 pr_debug("Unablt to get kernel version from uname '%s'\n",
690 utsname.release);
691 return -1;
692 }
693
694 if (puint)
695 *puint = (version << 16) + (patchlevel << 8) + sublevel;
696 return 0;
697}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 4cfb913aa9e0..dcc659017976 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -350,4 +350,12 @@ static inline char *asprintf_expr_not_in_ints(const char *var, size_t nints, int
350 350
351int get_stack_size(const char *str, unsigned long *_size); 351int get_stack_size(const char *str, unsigned long *_size);
352 352
353int fetch_kernel_version(unsigned int *puint,
354 char *str, size_t str_sz);
355#define KVER_VERSION(x) (((x) >> 16) & 0xff)
356#define KVER_PATCHLEVEL(x) (((x) >> 8) & 0xff)
357#define KVER_SUBLEVEL(x) ((x) & 0xff)
358#define KVER_FMT "%d.%d.%d"
359#define KVER_PARAM(x) KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x)
360
353#endif /* GIT_COMPAT_UTIL_H */ 361#endif /* GIT_COMPAT_UTIL_H */