diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-10-17 16:38:29 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-10-17 16:38:29 -0400 |
commit | a8f23d8f8af43d49cd3331681913b76e4951e1a4 (patch) | |
tree | 1ad8998584d57a5ebb5a03ca86c2e032bd0815f9 /tools | |
parent | 97a07f10c38064dea492794c99445f6260afcdc1 (diff) |
perf trace: Improve messages related to /proc/sys/kernel/perf_event_paranoid
kernel/events/core.c has:
/*
* perf event paranoia level:
* -1 - not paranoid at all
* 0 - disallow raw tracepoint access for unpriv
* 1 - disallow cpu events for unpriv
* 2 - disallow kernel profiling for unpriv
*/
int sysctl_perf_event_paranoid __read_mostly = 1;
So, with the default being 1, a non-root user can trace his stuff:
[acme@zoo ~]$ cat /proc/sys/kernel/perf_event_paranoid
1
[acme@zoo ~]$ yes > /dev/null &
[1] 15338
[acme@zoo ~]$ trace -p 15338 | head -5
0.005 ( 0.005 ms): write(fd: 1</dev/null>, buf: 0x7fe6db765000, count: 4096 ) = 4096
0.045 ( 0.001 ms): write(fd: 1</dev/null>, buf: 0x7fe6db765000, count: 4096 ) = 4096
0.085 ( 0.001 ms): write(fd: 1</dev/null>, buf: 0x7fe6db765000, count: 4096 ) = 4096
0.125 ( 0.001 ms): write(fd: 1</dev/null>, buf: 0x7fe6db765000, count: 4096 ) = 4096
0.165 ( 0.001 ms): write(fd: 1</dev/null>, buf: 0x7fe6db765000, count: 4096 ) = 4096
[acme@zoo ~]$
[acme@zoo ~]$ trace --duration 1 sleep 1
1002.148 (1001.218 ms): nanosleep(rqtp: 0x7fff46c79250 ) = 0
[acme@zoo ~]$
[acme@zoo ~]$ trace -- usleep 1 | tail -5
0.905 ( 0.002 ms): brk( ) = 0x1c82000
0.910 ( 0.003 ms): brk(brk: 0x1ca3000 ) = 0x1ca3000
0.913 ( 0.001 ms): brk( ) = 0x1ca3000
0.990 ( 0.059 ms): nanosleep(rqtp: 0x7fffe31a3280 ) = 0
0.995 ( 0.000 ms): exit_group(
[acme@zoo ~]$
But can't do system wide tracing:
[acme@zoo ~]$ trace
Error: Operation not permitted.
Hint: Check /proc/sys/kernel/perf_event_paranoid setting.
Hint: For system wide tracing it needs to be set to -1.
Hint: The current value is 1.
[acme@zoo ~]$
[acme@zoo ~]$ trace --cpu 0
Error: Operation not permitted.
Hint: Check /proc/sys/kernel/perf_event_paranoid setting.
Hint: For system wide tracing it needs to be set to -1.
Hint: The current value is 1.
[acme@zoo ~]$
If the paranoid level is >= 2, i.e. turn this perf stuff off for !root users:
[acme@zoo ~]$ sudo sh -c 'echo 2 > /proc/sys/kernel/perf_event_paranoid'
[acme@zoo ~]$ cat /proc/sys/kernel/perf_event_paranoid
2
[acme@zoo ~]$
[acme@zoo ~]$ trace usleep 1
Error: Permission denied.
Hint: Check /proc/sys/kernel/perf_event_paranoid setting.
Hint: For your workloads it needs to be <= 1
Hint: For system wide tracing it needs to be set to -1.
Hint: The current value is 2.
[acme@zoo ~]$
[acme@zoo ~]$ trace
Error: Permission denied.
Hint: Check /proc/sys/kernel/perf_event_paranoid setting.
Hint: For your workloads it needs to be <= 1
Hint: For system wide tracing it needs to be set to -1.
Hint: The current value is 2.
[acme@zoo ~]$
[acme@zoo ~]$ trace --cpu 1
Error: Permission denied.
Hint: Check /proc/sys/kernel/perf_event_paranoid setting.
Hint: For your workloads it needs to be <= 1
Hint: For system wide tracing it needs to be set to -1.
Hint: The current value is 2.
[acme@zoo ~]$
If the user manages to get what he/she wants, convincing root not
to be paranoid at all...
[root@zoo ~]# echo -1 > /proc/sys/kernel/perf_event_paranoid
[root@zoo ~]# cat /proc/sys/kernel/perf_event_paranoid
-1
[root@zoo ~]#
[acme@zoo ~]$ ps -eo user,pid,comm | grep Xorg
root 729 Xorg
[acme@zoo ~]$
[acme@zoo ~]$ trace -a --duration 0.001 -e \!select,ioctl,writev | grep Xorg | head -5
23.143 ( 0.003 ms): Xorg/729 setitimer(which: REAL, value: 0x7fffaadf16e0 ) = 0
23.152 ( 0.004 ms): Xorg/729 read(fd: 31, buf: 0x2544af0, count: 4096 ) = 8
23.161 ( 0.002 ms): Xorg/729 read(fd: 31, buf: 0x2544af0, count: 4096 ) = -1 EAGAIN Resource temporarily unavailable
23.175 ( 0.002 ms): Xorg/729 setitimer(which: REAL, value: 0x7fffaadf16e0 ) = 0
23.235 ( 0.002 ms): Xorg/729 setitimer(which: REAL, value: 0x7fffaadf16e0 ) = 0
[acme@zoo ~]$
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-di28olfwd28rvkox7v3hqhu1@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-trace.c | 17 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 36 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 1 |
3 files changed, 48 insertions, 6 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 78b0d6a5fdff..db959ac3d46e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -1713,10 +1713,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
1713 | } | 1713 | } |
1714 | 1714 | ||
1715 | err = perf_evlist__open(evlist); | 1715 | err = perf_evlist__open(evlist); |
1716 | if (err < 0) { | 1716 | if (err < 0) |
1717 | fprintf(trace->output, "Couldn't create the events: %s\n", strerror(errno)); | 1717 | goto out_error_open; |
1718 | goto out_delete_maps; | ||
1719 | } | ||
1720 | 1718 | ||
1721 | err = perf_evlist__mmap(evlist, UINT_MAX, false); | 1719 | err = perf_evlist__mmap(evlist, UINT_MAX, false); |
1722 | if (err < 0) { | 1720 | if (err < 0) { |
@@ -1813,14 +1811,21 @@ out_delete_evlist: | |||
1813 | out: | 1811 | out: |
1814 | trace->live = false; | 1812 | trace->live = false; |
1815 | return err; | 1813 | return err; |
1816 | out_error_tp: | ||
1817 | { | 1814 | { |
1818 | char errbuf[BUFSIZ]; | 1815 | char errbuf[BUFSIZ]; |
1816 | |||
1817 | out_error_tp: | ||
1819 | perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); | 1818 | perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); |
1819 | goto out_error; | ||
1820 | |||
1821 | out_error_open: | ||
1822 | perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); | ||
1823 | |||
1824 | out_error: | ||
1820 | fprintf(trace->output, "%s\n", errbuf); | 1825 | fprintf(trace->output, "%s\n", errbuf); |
1821 | } | ||
1822 | goto out_delete_evlist; | 1826 | goto out_delete_evlist; |
1823 | } | 1827 | } |
1828 | } | ||
1824 | 1829 | ||
1825 | static int trace__replay(struct trace *trace) | 1830 | static int trace__replay(struct trace *trace) |
1826 | { | 1831 | { |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6737420891cd..0b5425b4d8d6 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -1153,3 +1153,39 @@ int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused, | |||
1153 | 1153 | ||
1154 | return 0; | 1154 | return 0; |
1155 | } | 1155 | } |
1156 | |||
1157 | int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, | ||
1158 | int err, char *buf, size_t size) | ||
1159 | { | ||
1160 | int printed, value; | ||
1161 | char sbuf[128], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); | ||
1162 | |||
1163 | switch (err) { | ||
1164 | case EACCES: | ||
1165 | case EPERM: | ||
1166 | printed = scnprintf(buf, size, | ||
1167 | "Error:\t%s.\n" | ||
1168 | "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); | ||
1169 | |||
1170 | if (filename__read_int("/proc/sys/kernel/perf_event_paranoid", &value)) | ||
1171 | break; | ||
1172 | |||
1173 | printed += scnprintf(buf + printed, size - printed, "\nHint:\t"); | ||
1174 | |||
1175 | if (value >= 2) { | ||
1176 | printed += scnprintf(buf + printed, size - printed, | ||
1177 | "For your workloads it needs to be <= 1\nHint:\t"); | ||
1178 | } | ||
1179 | printed += scnprintf(buf + printed, size - printed, | ||
1180 | "For system wide tracing it needs to be set to -1"); | ||
1181 | |||
1182 | printed += scnprintf(buf + printed, size - printed, | ||
1183 | ".\nHint:\tThe current value is %d.", value); | ||
1184 | break; | ||
1185 | default: | ||
1186 | scnprintf(buf, size, "%s", emsg); | ||
1187 | break; | ||
1188 | } | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 386de1036442..7f8f1aeb9cfe 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -169,6 +169,7 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist) | |||
169 | size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); | 169 | size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); |
170 | 170 | ||
171 | int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); | 171 | int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); |
172 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); | ||
172 | 173 | ||
173 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) | 174 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) |
174 | { | 175 | { |