mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 02:34:01 +08:00
perf tool: Provide an option to print perf_event_open args and return value
Perf record with verbose=2 already prints this information along with whole lot of other traces which requires lot of scrolling. Introduce an option to print only perf_event_open() arguments and return value. Sample o/p: $ perf --debug perf-event-open=1 record -- ls > /dev/null ------------------------------------------------------------ perf_event_attr: size 112 { sample_period, sample_freq } 4000 sample_type IP|TID|TIME|PERIOD read_format ID disabled 1 inherit 1 exclude_kernel 1 mmap 1 comm 1 freq 1 enable_on_exec 1 task 1 precise_ip 3 sample_id_all 1 exclude_guest 1 mmap2 1 comm_exec 1 ksymbol 1 bpf_event 1 ------------------------------------------------------------ sys_perf_event_open: pid 4308 cpu 0 group_fd -1 flags 0x8 = 4 sys_perf_event_open: pid 4308 cpu 1 group_fd -1 flags 0x8 = 5 sys_perf_event_open: pid 4308 cpu 2 group_fd -1 flags 0x8 = 6 sys_perf_event_open: pid 4308 cpu 3 group_fd -1 flags 0x8 = 8 sys_perf_event_open: pid 4308 cpu 4 group_fd -1 flags 0x8 = 9 sys_perf_event_open: pid 4308 cpu 5 group_fd -1 flags 0x8 = 10 sys_perf_event_open: pid 4308 cpu 6 group_fd -1 flags 0x8 = 11 sys_perf_event_open: pid 4308 cpu 7 group_fd -1 flags 0x8 = 12 ------------------------------------------------------------ perf_event_attr: type 1 size 112 config 0x9 watermark 1 sample_id_all 1 bpf_event 1 { wakeup_events, wakeup_watermark } 1 ------------------------------------------------------------ sys_perf_event_open: pid -1 cpu 0 group_fd -1 flags 0x8 sys_perf_event_open failed, error -13 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.002 MB perf.data (9 samples) ] Committer notes: Just like the 'verbose' variable this new 'debug_peo_args' needs to be added to util/python.c, since we don't link the debug.o file in the python binding, which ended up making 'perf test python' fail with: # perf test -v python 18: 'import perf' in python : --- start --- test child forked, pid 19237 Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: /tmp/build/perf/python/perf.so: undefined symbol: debug_peo_args test child finished with -1 ---- end ---- 'import perf' in python: FAILED! # After adding that new variable to util/python.c: # perf test -v python 18: 'import perf' in python : --- start --- test child forked, pid 22364 test child finished with 0 ---- end ---- 'import perf' in python: Ok # Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lore.kernel.org/lkml/20191108094128.28769-1-ravi.bangoria@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
7b018e2987
commit
ccd26741f5
@ -24,6 +24,8 @@ OPTIONS
|
|||||||
data-convert - data convert command debug messages
|
data-convert - data convert command debug messages
|
||||||
stderr - write debug output (option -v) to stderr
|
stderr - write debug output (option -v) to stderr
|
||||||
in browser mode
|
in browser mode
|
||||||
|
perf-event-open - Print perf_event_open() arguments and
|
||||||
|
return value
|
||||||
|
|
||||||
--buildid-dir::
|
--buildid-dir::
|
||||||
Setup buildid cache directory. It has higher priority than
|
Setup buildid cache directory. It has higher priority than
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
|
||||||
int verbose;
|
int verbose;
|
||||||
|
int debug_peo_args;
|
||||||
bool dump_trace = false, quiet = false;
|
bool dump_trace = false, quiet = false;
|
||||||
int debug_ordered_events;
|
int debug_ordered_events;
|
||||||
static int redirect_to_stderr;
|
static int redirect_to_stderr;
|
||||||
@ -180,6 +181,7 @@ static struct debug_variable {
|
|||||||
{ .name = "ordered-events", .ptr = &debug_ordered_events},
|
{ .name = "ordered-events", .ptr = &debug_ordered_events},
|
||||||
{ .name = "stderr", .ptr = &redirect_to_stderr},
|
{ .name = "stderr", .ptr = &redirect_to_stderr},
|
||||||
{ .name = "data-convert", .ptr = &debug_data_convert },
|
{ .name = "data-convert", .ptr = &debug_data_convert },
|
||||||
|
{ .name = "perf-event-open", .ptr = &debug_peo_args },
|
||||||
{ .name = NULL, }
|
{ .name = NULL, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
extern int verbose;
|
extern int verbose;
|
||||||
|
extern int debug_peo_args;
|
||||||
extern bool quiet, dump_trace;
|
extern bool quiet, dump_trace;
|
||||||
extern int debug_ordered_events;
|
extern int debug_ordered_events;
|
||||||
extern int debug_data_convert;
|
extern int debug_data_convert;
|
||||||
@ -30,6 +31,14 @@ extern int debug_data_convert;
|
|||||||
#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__)
|
#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__)
|
#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Special macro to print perf_event_open arguments/return value. */
|
||||||
|
#define pr_debug2_peo(fmt, ...) { \
|
||||||
|
if (debug_peo_args) \
|
||||||
|
pr_debugN(0, pr_fmt(fmt), ##__VA_ARGS__); \
|
||||||
|
else \
|
||||||
|
pr_debugN(2, pr_fmt(fmt), ##__VA_ARGS__); \
|
||||||
|
}
|
||||||
|
|
||||||
#define pr_time_N(n, var, t, fmt, ...) \
|
#define pr_time_N(n, var, t, fmt, ...) \
|
||||||
eprintf_time(n, var, t, fmt, ##__VA_ARGS__)
|
eprintf_time(n, var, t, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
@ -1524,7 +1524,7 @@ static int __open_attr__fprintf(FILE *fp, const char *name, const char *val,
|
|||||||
|
|
||||||
static void display_attr(struct perf_event_attr *attr)
|
static void display_attr(struct perf_event_attr *attr)
|
||||||
{
|
{
|
||||||
if (verbose >= 2) {
|
if (verbose >= 2 || debug_peo_args) {
|
||||||
fprintf(stderr, "%.60s\n", graph_dotted_line);
|
fprintf(stderr, "%.60s\n", graph_dotted_line);
|
||||||
fprintf(stderr, "perf_event_attr:\n");
|
fprintf(stderr, "perf_event_attr:\n");
|
||||||
perf_event_attr__fprintf(stderr, attr, __open_attr__fprintf, NULL);
|
perf_event_attr__fprintf(stderr, attr, __open_attr__fprintf, NULL);
|
||||||
@ -1540,7 +1540,7 @@ static int perf_event_open(struct evsel *evsel,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
pr_debug2("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx",
|
pr_debug2_peo("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx",
|
||||||
pid, cpu, group_fd, flags);
|
pid, cpu, group_fd, flags);
|
||||||
|
|
||||||
fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, group_fd, flags);
|
fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, group_fd, flags);
|
||||||
@ -1560,9 +1560,9 @@ static int perf_event_open(struct evsel *evsel,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug2("\nsys_perf_event_open failed, error %d\n", -ENOTSUP);
|
pr_debug2_peo("\nsys_perf_event_open failed, error %d\n", -ENOTSUP);
|
||||||
evsel->core.attr.precise_ip--;
|
evsel->core.attr.precise_ip--;
|
||||||
pr_debug2("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip);
|
pr_debug2_peo("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip);
|
||||||
display_attr(&evsel->core.attr);
|
display_attr(&evsel->core.attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1681,12 +1681,12 @@ retry_open:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug2("\nsys_perf_event_open failed, error %d\n",
|
pr_debug2_peo("\nsys_perf_event_open failed, error %d\n",
|
||||||
err);
|
err);
|
||||||
goto try_fallback;
|
goto try_fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug2(" = %d\n", fd);
|
pr_debug2_peo(" = %d\n", fd);
|
||||||
|
|
||||||
if (evsel->bpf_fd >= 0) {
|
if (evsel->bpf_fd >= 0) {
|
||||||
int evt_fd = fd;
|
int evt_fd = fd;
|
||||||
@ -1754,58 +1754,58 @@ try_fallback:
|
|||||||
*/
|
*/
|
||||||
if (!perf_missing_features.aux_output && evsel->core.attr.aux_output) {
|
if (!perf_missing_features.aux_output && evsel->core.attr.aux_output) {
|
||||||
perf_missing_features.aux_output = true;
|
perf_missing_features.aux_output = true;
|
||||||
pr_debug2("Kernel has no attr.aux_output support, bailing out\n");
|
pr_debug2_peo("Kernel has no attr.aux_output support, bailing out\n");
|
||||||
goto out_close;
|
goto out_close;
|
||||||
} else if (!perf_missing_features.bpf && evsel->core.attr.bpf_event) {
|
} else if (!perf_missing_features.bpf && evsel->core.attr.bpf_event) {
|
||||||
perf_missing_features.bpf = true;
|
perf_missing_features.bpf = true;
|
||||||
pr_debug2("switching off bpf_event\n");
|
pr_debug2_peo("switching off bpf_event\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.ksymbol && evsel->core.attr.ksymbol) {
|
} else if (!perf_missing_features.ksymbol && evsel->core.attr.ksymbol) {
|
||||||
perf_missing_features.ksymbol = true;
|
perf_missing_features.ksymbol = true;
|
||||||
pr_debug2("switching off ksymbol\n");
|
pr_debug2_peo("switching off ksymbol\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.write_backward && evsel->core.attr.write_backward) {
|
} else if (!perf_missing_features.write_backward && evsel->core.attr.write_backward) {
|
||||||
perf_missing_features.write_backward = true;
|
perf_missing_features.write_backward = true;
|
||||||
pr_debug2("switching off write_backward\n");
|
pr_debug2_peo("switching off write_backward\n");
|
||||||
goto out_close;
|
goto out_close;
|
||||||
} else if (!perf_missing_features.clockid_wrong && evsel->core.attr.use_clockid) {
|
} else if (!perf_missing_features.clockid_wrong && evsel->core.attr.use_clockid) {
|
||||||
perf_missing_features.clockid_wrong = true;
|
perf_missing_features.clockid_wrong = true;
|
||||||
pr_debug2("switching off clockid\n");
|
pr_debug2_peo("switching off clockid\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.clockid && evsel->core.attr.use_clockid) {
|
} else if (!perf_missing_features.clockid && evsel->core.attr.use_clockid) {
|
||||||
perf_missing_features.clockid = true;
|
perf_missing_features.clockid = true;
|
||||||
pr_debug2("switching off use_clockid\n");
|
pr_debug2_peo("switching off use_clockid\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
|
} else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
|
||||||
perf_missing_features.cloexec = true;
|
perf_missing_features.cloexec = true;
|
||||||
pr_debug2("switching off cloexec flag\n");
|
pr_debug2_peo("switching off cloexec flag\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.mmap2 && evsel->core.attr.mmap2) {
|
} else if (!perf_missing_features.mmap2 && evsel->core.attr.mmap2) {
|
||||||
perf_missing_features.mmap2 = true;
|
perf_missing_features.mmap2 = true;
|
||||||
pr_debug2("switching off mmap2\n");
|
pr_debug2_peo("switching off mmap2\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.exclude_guest &&
|
} else if (!perf_missing_features.exclude_guest &&
|
||||||
(evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host)) {
|
(evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host)) {
|
||||||
perf_missing_features.exclude_guest = true;
|
perf_missing_features.exclude_guest = true;
|
||||||
pr_debug2("switching off exclude_guest, exclude_host\n");
|
pr_debug2_peo("switching off exclude_guest, exclude_host\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.sample_id_all) {
|
} else if (!perf_missing_features.sample_id_all) {
|
||||||
perf_missing_features.sample_id_all = true;
|
perf_missing_features.sample_id_all = true;
|
||||||
pr_debug2("switching off sample_id_all\n");
|
pr_debug2_peo("switching off sample_id_all\n");
|
||||||
goto retry_sample_id;
|
goto retry_sample_id;
|
||||||
} else if (!perf_missing_features.lbr_flags &&
|
} else if (!perf_missing_features.lbr_flags &&
|
||||||
(evsel->core.attr.branch_sample_type &
|
(evsel->core.attr.branch_sample_type &
|
||||||
(PERF_SAMPLE_BRANCH_NO_CYCLES |
|
(PERF_SAMPLE_BRANCH_NO_CYCLES |
|
||||||
PERF_SAMPLE_BRANCH_NO_FLAGS))) {
|
PERF_SAMPLE_BRANCH_NO_FLAGS))) {
|
||||||
perf_missing_features.lbr_flags = true;
|
perf_missing_features.lbr_flags = true;
|
||||||
pr_debug2("switching off branch sample type no (cycles/flags)\n");
|
pr_debug2_peo("switching off branch sample type no (cycles/flags)\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
} else if (!perf_missing_features.group_read &&
|
} else if (!perf_missing_features.group_read &&
|
||||||
evsel->core.attr.inherit &&
|
evsel->core.attr.inherit &&
|
||||||
(evsel->core.attr.read_format & PERF_FORMAT_GROUP) &&
|
(evsel->core.attr.read_format & PERF_FORMAT_GROUP) &&
|
||||||
perf_evsel__is_group_leader(evsel)) {
|
perf_evsel__is_group_leader(evsel)) {
|
||||||
perf_missing_features.group_read = true;
|
perf_missing_features.group_read = true;
|
||||||
pr_debug2("switching off group read\n");
|
pr_debug2_peo("switching off group read\n");
|
||||||
goto fallback_missing_features;
|
goto fallback_missing_features;
|
||||||
}
|
}
|
||||||
out_close:
|
out_close:
|
||||||
|
@ -65,6 +65,7 @@ struct perf_env perf_env;
|
|||||||
* implementing 'verbose' and 'eprintf'.
|
* implementing 'verbose' and 'eprintf'.
|
||||||
*/
|
*/
|
||||||
int verbose;
|
int verbose;
|
||||||
|
int debug_peo_args;
|
||||||
|
|
||||||
int eprintf(int level, int var, const char *fmt, ...);
|
int eprintf(int level, int var, const char *fmt, ...);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user