diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-06-20 04:49:08 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-06-20 04:49:08 -0400 |
commit | 007b811b4041989ec2dc91b9614aa2c41332723e (patch) | |
tree | 34ba98f00635fea2d0f3087e8859afe7b83e74d0 /tools/perf | |
parent | 2eb0fc9bfe7485fec16030b85ff586e7aaea2b6f (diff) | |
parent | dfe1c6d7efa8ead6878b73216d4c891a28207528 (diff) |
Merge tag 'perf-core-for-mingo-4.13-20170719' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
User visible changes:
- Allow adding and removing fields to the default 'perf script' columns,
using + or - as field prefixes to do so (Andi Kleen)
- Display titles in left frame in the annotate browser (Jin Yao)
- Allow resolving the DSO name with 'perf script -F brstack{sym,off},dso'
(Mark Santaniello)
- Support function filtering in 'perf ftrace' (Namhyung Kim)
- Allow specifying function call depth in 'perf ftrace' (Namhyumg Kim)
Infrastructure changes:
- Adopt __noreturn, __printf, __scanf, noinline, __packed and __aligned
__alignment__(()) markers, to make the tools/ source code base to be
more compact and look more like kernel code (Arnaldo Carvalho de Melo)
- Remove unnecessary check in annotate_browser_write() (Jin Yao)
- Return arch from symbol__disassemble() so that callers, such as
the annotate TUI browser to use arch specific formattings, such
as the upcoming instruction micro-op fusion on Intel Core (Jin Yao)
- Remove superfluous check before use in the coresight code base (Kim
Phillips)
- Remove unused SAMPLE_SIZE defines and BTS priv array (Kim Phillips)
- Error handling fix/tidy ups in 'perf config' (Taeung Song)
- Avoid error in the BPF proggie built with clang in 'perf test llvm'
when PROFILE_ALL_BRANCHES is set (Wang Nan)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
35 files changed, 482 insertions, 161 deletions
diff --git a/tools/perf/Documentation/perf-ftrace.txt b/tools/perf/Documentation/perf-ftrace.txt index 6e6a8b22c859..721a447f046e 100644 --- a/tools/perf/Documentation/perf-ftrace.txt +++ b/tools/perf/Documentation/perf-ftrace.txt | |||
@@ -48,6 +48,39 @@ OPTIONS | |||
48 | Ranges of CPUs are specified with -: 0-2. | 48 | Ranges of CPUs are specified with -: 0-2. |
49 | Default is to trace on all online CPUs. | 49 | Default is to trace on all online CPUs. |
50 | 50 | ||
51 | -T:: | ||
52 | --trace-funcs=:: | ||
53 | Only trace functions given by the argument. Multiple functions | ||
54 | can be given by using this option more than once. The function | ||
55 | argument also can be a glob pattern. It will be passed to | ||
56 | 'set_ftrace_filter' in tracefs. | ||
57 | |||
58 | -N:: | ||
59 | --notrace-funcs=:: | ||
60 | Do not trace functions given by the argument. Like -T option, | ||
61 | this can be used more than once to specify multiple functions | ||
62 | (or glob patterns). It will be passed to 'set_ftrace_notrace' | ||
63 | in tracefs. | ||
64 | |||
65 | -G:: | ||
66 | --graph-funcs=:: | ||
67 | Set graph filter on the given function (or a glob pattern). | ||
68 | This is useful for the function_graph tracer only and enables | ||
69 | tracing for functions executed from the given function. | ||
70 | This can be used more than once to specify multiple functions. | ||
71 | It will be passed to 'set_graph_function' in tracefs. | ||
72 | |||
73 | -g:: | ||
74 | --nograph-funcs=:: | ||
75 | Set graph notrace filter on the given function (or a glob pattern). | ||
76 | Like -G option, this is useful for the function_graph tracer only | ||
77 | and disables tracing for function executed from the given function. | ||
78 | This can be used more than once to specify multiple functions. | ||
79 | It will be passed to 'set_graph_notrace' in tracefs. | ||
80 | |||
81 | -D:: | ||
82 | --graph-depth=:: | ||
83 | Set max depth for function graph tracer to follow | ||
51 | 84 | ||
52 | SEE ALSO | 85 | SEE ALSO |
53 | -------- | 86 | -------- |
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 3517e204a2b3..e2468ed6a307 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt | |||
@@ -116,7 +116,7 @@ OPTIONS | |||
116 | --fields:: | 116 | --fields:: |
117 | Comma separated list of fields to print. Options are: | 117 | Comma separated list of fields to print. Options are: |
118 | comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, | 118 | comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, |
119 | srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, | 119 | srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff, |
120 | callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw, | 120 | callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw, |
121 | to indicate to which event type the field list applies. | 121 | to indicate to which event type the field list applies. |
122 | e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace | 122 | e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace |
@@ -130,6 +130,14 @@ OPTIONS | |||
130 | i.e., the specified fields apply to all event types if the type string | 130 | i.e., the specified fields apply to all event types if the type string |
131 | is not given. | 131 | is not given. |
132 | 132 | ||
133 | In addition to overriding fields, it is also possible to add or remove | ||
134 | fields from the defaults. For example | ||
135 | |||
136 | -F -cpu,+insn | ||
137 | |||
138 | removes the cpu field and adds the insn field. Adding/removing fields | ||
139 | cannot be mixed with normal overriding. | ||
140 | |||
133 | The arguments are processed in the order received. A later usage can | 141 | The arguments are processed in the order received. A later usage can |
134 | reset a prior request. e.g.: | 142 | reset a prior request. e.g.: |
135 | 143 | ||
@@ -203,6 +211,8 @@ OPTIONS | |||
203 | is printed. This is the full execution path leading to the sample. This is only supported when the | 211 | is printed. This is the full execution path leading to the sample. This is only supported when the |
204 | sample was recorded with perf record -b or -j any. | 212 | sample was recorded with perf record -b or -j any. |
205 | 213 | ||
214 | The brstackoff field will print an offset into a specific dso/binary. | ||
215 | |||
206 | -k:: | 216 | -k:: |
207 | --vmlinux=<file>:: | 217 | --vmlinux=<file>:: |
208 | vmlinux pathname | 218 | vmlinux pathname |
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 29361d9b635a..7ce3d1a25133 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <api/fs/fs.h> | 18 | #include <api/fs/fs.h> |
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/compiler.h> | ||
20 | #include <linux/coresight-pmu.h> | 21 | #include <linux/coresight-pmu.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
22 | #include <linux/log2.h> | 23 | #include <linux/log2.h> |
@@ -202,19 +203,18 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, | |||
202 | pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME, | 203 | pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME, |
203 | opts->auxtrace_snapshot_size); | 204 | opts->auxtrace_snapshot_size); |
204 | 205 | ||
205 | if (cs_etm_evsel) { | 206 | /* |
206 | /* | 207 | * To obtain the auxtrace buffer file descriptor, the auxtrace |
207 | * To obtain the auxtrace buffer file descriptor, the auxtrace | 208 | * event must come first. |
208 | * event must come first. | 209 | */ |
209 | */ | 210 | perf_evlist__to_front(evlist, cs_etm_evsel); |
210 | perf_evlist__to_front(evlist, cs_etm_evsel); | 211 | |
211 | /* | 212 | /* |
212 | * In the case of per-cpu mmaps, we need the CPU on the | 213 | * In the case of per-cpu mmaps, we need the CPU on the |
213 | * AUX event. | 214 | * AUX event. |
214 | */ | 215 | */ |
215 | if (!cpu_map__empty(cpus)) | 216 | if (!cpu_map__empty(cpus)) |
216 | perf_evsel__set_sample_bit(cs_etm_evsel, CPU); | 217 | perf_evsel__set_sample_bit(cs_etm_evsel, CPU); |
217 | } | ||
218 | 218 | ||
219 | /* Add dummy event to keep tracking */ | 219 | /* Add dummy event to keep tracking */ |
220 | if (opts->full_auxtrace) { | 220 | if (opts->full_auxtrace) { |
@@ -583,8 +583,7 @@ static FILE *cs_device__open_file(const char *name) | |||
583 | 583 | ||
584 | } | 584 | } |
585 | 585 | ||
586 | static __attribute__((format(printf, 2, 3))) | 586 | static int __printf(2, 3) cs_device__print_file(const char *name, const char *fmt, ...) |
587 | int cs_device__print_file(const char *name, const char *fmt, ...) | ||
588 | { | 587 | { |
589 | va_list args; | 588 | va_list args; |
590 | FILE *file; | 589 | FILE *file; |
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index af2bce7a2cd6..781df40b2966 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c | |||
@@ -35,10 +35,6 @@ | |||
35 | #define KiB_MASK(x) (KiB(x) - 1) | 35 | #define KiB_MASK(x) (KiB(x) - 1) |
36 | #define MiB_MASK(x) (MiB(x) - 1) | 36 | #define MiB_MASK(x) (MiB(x) - 1) |
37 | 37 | ||
38 | #define INTEL_BTS_DFLT_SAMPLE_SIZE KiB(4) | ||
39 | |||
40 | #define INTEL_BTS_MAX_SAMPLE_SIZE KiB(60) | ||
41 | |||
42 | struct intel_bts_snapshot_ref { | 38 | struct intel_bts_snapshot_ref { |
43 | void *ref_buf; | 39 | void *ref_buf; |
44 | size_t ref_offset; | 40 | size_t ref_offset; |
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index f630de0206a1..6fe667b3269e 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c | |||
@@ -40,10 +40,6 @@ | |||
40 | #define KiB_MASK(x) (KiB(x) - 1) | 40 | #define KiB_MASK(x) (KiB(x) - 1) |
41 | #define MiB_MASK(x) (MiB(x) - 1) | 41 | #define MiB_MASK(x) (MiB(x) - 1) |
42 | 42 | ||
43 | #define INTEL_PT_DEFAULT_SAMPLE_SIZE KiB(4) | ||
44 | |||
45 | #define INTEL_PT_MAX_SAMPLE_SIZE KiB(60) | ||
46 | |||
47 | #define INTEL_PT_PSB_PERIOD_NEAR 256 | 43 | #define INTEL_PT_PSB_PERIOD_NEAR 256 |
48 | 44 | ||
49 | struct intel_pt_snapshot_ref { | 45 | struct intel_pt_snapshot_ref { |
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 27de0c8c5c19..469d65b21122 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
@@ -700,7 +700,7 @@ static inline uint32_t lfsr_32(uint32_t lfsr) | |||
700 | * kernel (KSM, zero page, etc.) cannot optimize away RAM | 700 | * kernel (KSM, zero page, etc.) cannot optimize away RAM |
701 | * accesses: | 701 | * accesses: |
702 | */ | 702 | */ |
703 | static inline u64 access_data(u64 *data __attribute__((unused)), u64 val) | 703 | static inline u64 access_data(u64 *data, u64 val) |
704 | { | 704 | { |
705 | if (g->p.data_reads) | 705 | if (g->p.data_reads) |
706 | val += *data; | 706 | val += *data; |
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 80668fa7556e..ece45582a48d 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c | |||
@@ -156,7 +156,7 @@ static int parse_config_arg(char *arg, char **var, char **value) | |||
156 | 156 | ||
157 | int cmd_config(int argc, const char **argv) | 157 | int cmd_config(int argc, const char **argv) |
158 | { | 158 | { |
159 | int i, ret = 0; | 159 | int i, ret = -1; |
160 | struct perf_config_set *set; | 160 | struct perf_config_set *set; |
161 | char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); | 161 | char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); |
162 | const char *config_filename; | 162 | const char *config_filename; |
@@ -186,10 +186,8 @@ int cmd_config(int argc, const char **argv) | |||
186 | * because of reinitializing with options config file location. | 186 | * because of reinitializing with options config file location. |
187 | */ | 187 | */ |
188 | set = perf_config_set__new(); | 188 | set = perf_config_set__new(); |
189 | if (!set) { | 189 | if (!set) |
190 | ret = -1; | ||
191 | goto out_err; | 190 | goto out_err; |
192 | } | ||
193 | 191 | ||
194 | switch (actions) { | 192 | switch (actions) { |
195 | case ACTION_LIST: | 193 | case ACTION_LIST: |
@@ -197,41 +195,54 @@ int cmd_config(int argc, const char **argv) | |||
197 | pr_err("Error: takes no arguments\n"); | 195 | pr_err("Error: takes no arguments\n"); |
198 | parse_options_usage(config_usage, config_options, "l", 1); | 196 | parse_options_usage(config_usage, config_options, "l", 1); |
199 | } else { | 197 | } else { |
200 | ret = show_config(set); | 198 | if (show_config(set) < 0) { |
201 | if (ret < 0) | ||
202 | pr_err("Nothing configured, " | 199 | pr_err("Nothing configured, " |
203 | "please check your %s \n", config_filename); | 200 | "please check your %s \n", config_filename); |
201 | goto out_err; | ||
202 | } | ||
204 | } | 203 | } |
205 | break; | 204 | break; |
206 | default: | 205 | default: |
207 | if (argc) { | 206 | if (!argc) { |
208 | for (i = 0; argv[i]; i++) { | 207 | usage_with_options(config_usage, config_options); |
209 | char *var, *value; | 208 | break; |
210 | char *arg = strdup(argv[i]); | 209 | } |
211 | |||
212 | if (!arg) { | ||
213 | pr_err("%s: strdup failed\n", __func__); | ||
214 | ret = -1; | ||
215 | break; | ||
216 | } | ||
217 | 210 | ||
218 | if (parse_config_arg(arg, &var, &value) < 0) { | 211 | for (i = 0; argv[i]; i++) { |
219 | free(arg); | 212 | char *var, *value; |
220 | ret = -1; | 213 | char *arg = strdup(argv[i]); |
221 | break; | 214 | |
222 | } | 215 | if (!arg) { |
216 | pr_err("%s: strdup failed\n", __func__); | ||
217 | goto out_err; | ||
218 | } | ||
223 | 219 | ||
224 | if (value == NULL) | 220 | if (parse_config_arg(arg, &var, &value) < 0) { |
225 | ret = show_spec_config(set, var); | ||
226 | else | ||
227 | ret = set_config(set, config_filename, var, value); | ||
228 | free(arg); | 221 | free(arg); |
222 | goto out_err; | ||
229 | } | 223 | } |
230 | } else | 224 | |
231 | usage_with_options(config_usage, config_options); | 225 | if (value == NULL) { |
226 | if (show_spec_config(set, var) < 0) { | ||
227 | pr_err("%s is not configured: %s\n", | ||
228 | var, config_filename); | ||
229 | free(arg); | ||
230 | goto out_err; | ||
231 | } | ||
232 | } else { | ||
233 | if (set_config(set, config_filename, var, value) < 0) { | ||
234 | pr_err("Failed to set '%s=%s' on %s\n", | ||
235 | var, value, config_filename); | ||
236 | free(arg); | ||
237 | goto out_err; | ||
238 | } | ||
239 | } | ||
240 | free(arg); | ||
241 | } | ||
232 | } | 242 | } |
233 | 243 | ||
234 | perf_config_set__delete(set); | 244 | ret = 0; |
235 | out_err: | 245 | out_err: |
246 | perf_config_set__delete(set); | ||
236 | return ret; | 247 | return ret; |
237 | } | 248 | } |
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 9e0b35cd0eea..dd26c62c9893 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c | |||
@@ -28,9 +28,19 @@ | |||
28 | #define DEFAULT_TRACER "function_graph" | 28 | #define DEFAULT_TRACER "function_graph" |
29 | 29 | ||
30 | struct perf_ftrace { | 30 | struct perf_ftrace { |
31 | struct perf_evlist *evlist; | 31 | struct perf_evlist *evlist; |
32 | struct target target; | 32 | struct target target; |
33 | const char *tracer; | 33 | const char *tracer; |
34 | struct list_head filters; | ||
35 | struct list_head notrace; | ||
36 | struct list_head graph_funcs; | ||
37 | struct list_head nograph_funcs; | ||
38 | int graph_depth; | ||
39 | }; | ||
40 | |||
41 | struct filter_entry { | ||
42 | struct list_head list; | ||
43 | char name[]; | ||
34 | }; | 44 | }; |
35 | 45 | ||
36 | static bool done; | 46 | static bool done; |
@@ -61,6 +71,7 @@ static int __write_tracing_file(const char *name, const char *val, bool append) | |||
61 | int fd, ret = -1; | 71 | int fd, ret = -1; |
62 | ssize_t size = strlen(val); | 72 | ssize_t size = strlen(val); |
63 | int flags = O_WRONLY; | 73 | int flags = O_WRONLY; |
74 | char errbuf[512]; | ||
64 | 75 | ||
65 | file = get_tracing_file(name); | 76 | file = get_tracing_file(name); |
66 | if (!file) { | 77 | if (!file) { |
@@ -75,14 +86,16 @@ static int __write_tracing_file(const char *name, const char *val, bool append) | |||
75 | 86 | ||
76 | fd = open(file, flags); | 87 | fd = open(file, flags); |
77 | if (fd < 0) { | 88 | if (fd < 0) { |
78 | pr_debug("cannot open tracing file: %s\n", name); | 89 | pr_debug("cannot open tracing file: %s: %s\n", |
90 | name, str_error_r(errno, errbuf, sizeof(errbuf))); | ||
79 | goto out; | 91 | goto out; |
80 | } | 92 | } |
81 | 93 | ||
82 | if (write(fd, val, size) == size) | 94 | if (write(fd, val, size) == size) |
83 | ret = 0; | 95 | ret = 0; |
84 | else | 96 | else |
85 | pr_debug("write '%s' to tracing/%s failed\n", val, name); | 97 | pr_debug("write '%s' to tracing/%s failed: %s\n", |
98 | val, name, str_error_r(errno, errbuf, sizeof(errbuf))); | ||
86 | 99 | ||
87 | close(fd); | 100 | close(fd); |
88 | out: | 101 | out: |
@@ -101,6 +114,7 @@ static int append_tracing_file(const char *name, const char *val) | |||
101 | } | 114 | } |
102 | 115 | ||
103 | static int reset_tracing_cpu(void); | 116 | static int reset_tracing_cpu(void); |
117 | static void reset_tracing_filters(void); | ||
104 | 118 | ||
105 | static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) | 119 | static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) |
106 | { | 120 | { |
@@ -116,6 +130,10 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) | |||
116 | if (reset_tracing_cpu() < 0) | 130 | if (reset_tracing_cpu() < 0) |
117 | return -1; | 131 | return -1; |
118 | 132 | ||
133 | if (write_tracing_file("max_graph_depth", "0") < 0) | ||
134 | return -1; | ||
135 | |||
136 | reset_tracing_filters(); | ||
119 | return 0; | 137 | return 0; |
120 | } | 138 | } |
121 | 139 | ||
@@ -181,6 +199,68 @@ static int reset_tracing_cpu(void) | |||
181 | return ret; | 199 | return ret; |
182 | } | 200 | } |
183 | 201 | ||
202 | static int __set_tracing_filter(const char *filter_file, struct list_head *funcs) | ||
203 | { | ||
204 | struct filter_entry *pos; | ||
205 | |||
206 | list_for_each_entry(pos, funcs, list) { | ||
207 | if (append_tracing_file(filter_file, pos->name) < 0) | ||
208 | return -1; | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int set_tracing_filters(struct perf_ftrace *ftrace) | ||
215 | { | ||
216 | int ret; | ||
217 | |||
218 | ret = __set_tracing_filter("set_ftrace_filter", &ftrace->filters); | ||
219 | if (ret < 0) | ||
220 | return ret; | ||
221 | |||
222 | ret = __set_tracing_filter("set_ftrace_notrace", &ftrace->notrace); | ||
223 | if (ret < 0) | ||
224 | return ret; | ||
225 | |||
226 | ret = __set_tracing_filter("set_graph_function", &ftrace->graph_funcs); | ||
227 | if (ret < 0) | ||
228 | return ret; | ||
229 | |||
230 | /* old kernels do not have this filter */ | ||
231 | __set_tracing_filter("set_graph_notrace", &ftrace->nograph_funcs); | ||
232 | |||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | static void reset_tracing_filters(void) | ||
237 | { | ||
238 | write_tracing_file("set_ftrace_filter", " "); | ||
239 | write_tracing_file("set_ftrace_notrace", " "); | ||
240 | write_tracing_file("set_graph_function", " "); | ||
241 | write_tracing_file("set_graph_notrace", " "); | ||
242 | } | ||
243 | |||
244 | static int set_tracing_depth(struct perf_ftrace *ftrace) | ||
245 | { | ||
246 | char buf[16]; | ||
247 | |||
248 | if (ftrace->graph_depth == 0) | ||
249 | return 0; | ||
250 | |||
251 | if (ftrace->graph_depth < 0) { | ||
252 | pr_err("invalid graph depth: %d\n", ftrace->graph_depth); | ||
253 | return -1; | ||
254 | } | ||
255 | |||
256 | snprintf(buf, sizeof(buf), "%d", ftrace->graph_depth); | ||
257 | |||
258 | if (write_tracing_file("max_graph_depth", buf) < 0) | ||
259 | return -1; | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
184 | static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) | 264 | static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) |
185 | { | 265 | { |
186 | char *trace_file; | 266 | char *trace_file; |
@@ -223,11 +303,23 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) | |||
223 | goto out_reset; | 303 | goto out_reset; |
224 | } | 304 | } |
225 | 305 | ||
306 | if (set_tracing_filters(ftrace) < 0) { | ||
307 | pr_err("failed to set tracing filters\n"); | ||
308 | goto out_reset; | ||
309 | } | ||
310 | |||
311 | if (set_tracing_depth(ftrace) < 0) { | ||
312 | pr_err("failed to set graph depth\n"); | ||
313 | goto out_reset; | ||
314 | } | ||
315 | |||
226 | if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { | 316 | if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { |
227 | pr_err("failed to set current_tracer to %s\n", ftrace->tracer); | 317 | pr_err("failed to set current_tracer to %s\n", ftrace->tracer); |
228 | goto out_reset; | 318 | goto out_reset; |
229 | } | 319 | } |
230 | 320 | ||
321 | setup_pager(); | ||
322 | |||
231 | trace_file = get_tracing_file("trace_pipe"); | 323 | trace_file = get_tracing_file("trace_pipe"); |
232 | if (!trace_file) { | 324 | if (!trace_file) { |
233 | pr_err("failed to open trace_pipe\n"); | 325 | pr_err("failed to open trace_pipe\n"); |
@@ -251,8 +343,6 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) | |||
251 | goto out_close_fd; | 343 | goto out_close_fd; |
252 | } | 344 | } |
253 | 345 | ||
254 | setup_pager(); | ||
255 | |||
256 | perf_evlist__start_workload(ftrace->evlist); | 346 | perf_evlist__start_workload(ftrace->evlist); |
257 | 347 | ||
258 | while (!done) { | 348 | while (!done) { |
@@ -307,6 +397,32 @@ static int perf_ftrace_config(const char *var, const char *value, void *cb) | |||
307 | return -1; | 397 | return -1; |
308 | } | 398 | } |
309 | 399 | ||
400 | static int parse_filter_func(const struct option *opt, const char *str, | ||
401 | int unset __maybe_unused) | ||
402 | { | ||
403 | struct list_head *head = opt->value; | ||
404 | struct filter_entry *entry; | ||
405 | |||
406 | entry = malloc(sizeof(*entry) + strlen(str) + 1); | ||
407 | if (entry == NULL) | ||
408 | return -ENOMEM; | ||
409 | |||
410 | strcpy(entry->name, str); | ||
411 | list_add_tail(&entry->list, head); | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static void delete_filter_func(struct list_head *head) | ||
417 | { | ||
418 | struct filter_entry *pos, *tmp; | ||
419 | |||
420 | list_for_each_entry_safe(pos, tmp, head, list) { | ||
421 | list_del(&pos->list); | ||
422 | free(pos); | ||
423 | } | ||
424 | } | ||
425 | |||
310 | int cmd_ftrace(int argc, const char **argv) | 426 | int cmd_ftrace(int argc, const char **argv) |
311 | { | 427 | { |
312 | int ret; | 428 | int ret; |
@@ -330,9 +446,24 @@ int cmd_ftrace(int argc, const char **argv) | |||
330 | "system-wide collection from all CPUs"), | 446 | "system-wide collection from all CPUs"), |
331 | OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu", | 447 | OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu", |
332 | "list of cpus to monitor"), | 448 | "list of cpus to monitor"), |
449 | OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func", | ||
450 | "trace given functions only", parse_filter_func), | ||
451 | OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func", | ||
452 | "do not trace given functions", parse_filter_func), | ||
453 | OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func", | ||
454 | "Set graph filter on given functions", parse_filter_func), | ||
455 | OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func", | ||
456 | "Set nograph filter on given functions", parse_filter_func), | ||
457 | OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth, | ||
458 | "Max depth for function graph tracer"), | ||
333 | OPT_END() | 459 | OPT_END() |
334 | }; | 460 | }; |
335 | 461 | ||
462 | INIT_LIST_HEAD(&ftrace.filters); | ||
463 | INIT_LIST_HEAD(&ftrace.notrace); | ||
464 | INIT_LIST_HEAD(&ftrace.graph_funcs); | ||
465 | INIT_LIST_HEAD(&ftrace.nograph_funcs); | ||
466 | |||
336 | ret = perf_config(perf_ftrace_config, &ftrace); | 467 | ret = perf_config(perf_ftrace_config, &ftrace); |
337 | if (ret < 0) | 468 | if (ret < 0) |
338 | return -1; | 469 | return -1; |
@@ -348,12 +479,14 @@ int cmd_ftrace(int argc, const char **argv) | |||
348 | 479 | ||
349 | target__strerror(&ftrace.target, ret, errbuf, 512); | 480 | target__strerror(&ftrace.target, ret, errbuf, 512); |
350 | pr_err("%s\n", errbuf); | 481 | pr_err("%s\n", errbuf); |
351 | return -EINVAL; | 482 | goto out_delete_filters; |
352 | } | 483 | } |
353 | 484 | ||
354 | ftrace.evlist = perf_evlist__new(); | 485 | ftrace.evlist = perf_evlist__new(); |
355 | if (ftrace.evlist == NULL) | 486 | if (ftrace.evlist == NULL) { |
356 | return -ENOMEM; | 487 | ret = -ENOMEM; |
488 | goto out_delete_filters; | ||
489 | } | ||
357 | 490 | ||
358 | ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target); | 491 | ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target); |
359 | if (ret < 0) | 492 | if (ret < 0) |
@@ -364,5 +497,11 @@ int cmd_ftrace(int argc, const char **argv) | |||
364 | out_delete_evlist: | 497 | out_delete_evlist: |
365 | perf_evlist__delete(ftrace.evlist); | 498 | perf_evlist__delete(ftrace.evlist); |
366 | 499 | ||
500 | out_delete_filters: | ||
501 | delete_filter_func(&ftrace.filters); | ||
502 | delete_filter_func(&ftrace.notrace); | ||
503 | delete_filter_func(&ftrace.graph_funcs); | ||
504 | delete_filter_func(&ftrace.nograph_funcs); | ||
505 | |||
367 | return ret; | 506 | return ret; |
368 | } | 507 | } |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 4761b0d7fcb5..db5261c3f719 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -85,6 +85,7 @@ enum perf_output_field { | |||
85 | PERF_OUTPUT_INSN = 1U << 21, | 85 | PERF_OUTPUT_INSN = 1U << 21, |
86 | PERF_OUTPUT_INSNLEN = 1U << 22, | 86 | PERF_OUTPUT_INSNLEN = 1U << 22, |
87 | PERF_OUTPUT_BRSTACKINSN = 1U << 23, | 87 | PERF_OUTPUT_BRSTACKINSN = 1U << 23, |
88 | PERF_OUTPUT_BRSTACKOFF = 1U << 24, | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | struct output_option { | 91 | struct output_option { |
@@ -115,6 +116,7 @@ struct output_option { | |||
115 | {.str = "insn", .field = PERF_OUTPUT_INSN}, | 116 | {.str = "insn", .field = PERF_OUTPUT_INSN}, |
116 | {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, | 117 | {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, |
117 | {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, | 118 | {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, |
119 | {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, | ||
118 | }; | 120 | }; |
119 | 121 | ||
120 | /* default set to maintain compatibility with current format */ | 122 | /* default set to maintain compatibility with current format */ |
@@ -298,10 +300,10 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
298 | "selected.\n"); | 300 | "selected.\n"); |
299 | return -EINVAL; | 301 | return -EINVAL; |
300 | } | 302 | } |
301 | if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { | 303 | if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR) && |
302 | pr_err("Display of DSO requested but neither sample IP nor " | 304 | !PRINT_FIELD(BRSTACK) && !PRINT_FIELD(BRSTACKSYM) && !PRINT_FIELD(BRSTACKOFF)) { |
303 | "sample address\nis selected. Hence, no addresses to convert " | 305 | pr_err("Display of DSO requested but no address to convert. Select\n" |
304 | "to DSO.\n"); | 306 | "sample IP, sample address, brstack, brstacksym, or brstackoff.\n"); |
305 | return -EINVAL; | 307 | return -EINVAL; |
306 | } | 308 | } |
307 | if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { | 309 | if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { |
@@ -514,18 +516,43 @@ mispred_str(struct branch_entry *br) | |||
514 | return br->flags.predicted ? 'P' : 'M'; | 516 | return br->flags.predicted ? 'P' : 'M'; |
515 | } | 517 | } |
516 | 518 | ||
517 | static void print_sample_brstack(struct perf_sample *sample) | 519 | static void print_sample_brstack(struct perf_sample *sample, |
520 | struct thread *thread, | ||
521 | struct perf_event_attr *attr) | ||
518 | { | 522 | { |
519 | struct branch_stack *br = sample->branch_stack; | 523 | struct branch_stack *br = sample->branch_stack; |
520 | u64 i; | 524 | struct addr_location alf, alt; |
525 | u64 i, from, to; | ||
521 | 526 | ||
522 | if (!(br && br->nr)) | 527 | if (!(br && br->nr)) |
523 | return; | 528 | return; |
524 | 529 | ||
525 | for (i = 0; i < br->nr; i++) { | 530 | for (i = 0; i < br->nr; i++) { |
526 | printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ", | 531 | from = br->entries[i].from; |
527 | br->entries[i].from, | 532 | to = br->entries[i].to; |
528 | br->entries[i].to, | 533 | |
534 | if (PRINT_FIELD(DSO)) { | ||
535 | memset(&alf, 0, sizeof(alf)); | ||
536 | memset(&alt, 0, sizeof(alt)); | ||
537 | thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); | ||
538 | thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); | ||
539 | } | ||
540 | |||
541 | printf("0x%"PRIx64, from); | ||
542 | if (PRINT_FIELD(DSO)) { | ||
543 | printf("("); | ||
544 | map__fprintf_dsoname(alf.map, stdout); | ||
545 | printf(")"); | ||
546 | } | ||
547 | |||
548 | printf("/0x%"PRIx64, to); | ||
549 | if (PRINT_FIELD(DSO)) { | ||
550 | printf("("); | ||
551 | map__fprintf_dsoname(alt.map, stdout); | ||
552 | printf(")"); | ||
553 | } | ||
554 | |||
555 | printf("/%c/%c/%c/%d ", | ||
529 | mispred_str( br->entries + i), | 556 | mispred_str( br->entries + i), |
530 | br->entries[i].flags.in_tx? 'X' : '-', | 557 | br->entries[i].flags.in_tx? 'X' : '-', |
531 | br->entries[i].flags.abort? 'A' : '-', | 558 | br->entries[i].flags.abort? 'A' : '-', |
@@ -534,7 +561,8 @@ static void print_sample_brstack(struct perf_sample *sample) | |||
534 | } | 561 | } |
535 | 562 | ||
536 | static void print_sample_brstacksym(struct perf_sample *sample, | 563 | static void print_sample_brstacksym(struct perf_sample *sample, |
537 | struct thread *thread) | 564 | struct thread *thread, |
565 | struct perf_event_attr *attr) | ||
538 | { | 566 | { |
539 | struct branch_stack *br = sample->branch_stack; | 567 | struct branch_stack *br = sample->branch_stack; |
540 | struct addr_location alf, alt; | 568 | struct addr_location alf, alt; |
@@ -559,8 +587,18 @@ static void print_sample_brstacksym(struct perf_sample *sample, | |||
559 | alt.sym = map__find_symbol(alt.map, alt.addr); | 587 | alt.sym = map__find_symbol(alt.map, alt.addr); |
560 | 588 | ||
561 | symbol__fprintf_symname_offs(alf.sym, &alf, stdout); | 589 | symbol__fprintf_symname_offs(alf.sym, &alf, stdout); |
590 | if (PRINT_FIELD(DSO)) { | ||
591 | printf("("); | ||
592 | map__fprintf_dsoname(alf.map, stdout); | ||
593 | printf(")"); | ||
594 | } | ||
562 | putchar('/'); | 595 | putchar('/'); |
563 | symbol__fprintf_symname_offs(alt.sym, &alt, stdout); | 596 | symbol__fprintf_symname_offs(alt.sym, &alt, stdout); |
597 | if (PRINT_FIELD(DSO)) { | ||
598 | printf("("); | ||
599 | map__fprintf_dsoname(alt.map, stdout); | ||
600 | printf(")"); | ||
601 | } | ||
564 | printf("/%c/%c/%c/%d ", | 602 | printf("/%c/%c/%c/%d ", |
565 | mispred_str( br->entries + i), | 603 | mispred_str( br->entries + i), |
566 | br->entries[i].flags.in_tx? 'X' : '-', | 604 | br->entries[i].flags.in_tx? 'X' : '-', |
@@ -569,6 +607,51 @@ static void print_sample_brstacksym(struct perf_sample *sample, | |||
569 | } | 607 | } |
570 | } | 608 | } |
571 | 609 | ||
610 | static void print_sample_brstackoff(struct perf_sample *sample, | ||
611 | struct thread *thread, | ||
612 | struct perf_event_attr *attr) | ||
613 | { | ||
614 | struct branch_stack *br = sample->branch_stack; | ||
615 | struct addr_location alf, alt; | ||
616 | u64 i, from, to; | ||
617 | |||
618 | if (!(br && br->nr)) | ||
619 | return; | ||
620 | |||
621 | for (i = 0; i < br->nr; i++) { | ||
622 | |||
623 | memset(&alf, 0, sizeof(alf)); | ||
624 | memset(&alt, 0, sizeof(alt)); | ||
625 | from = br->entries[i].from; | ||
626 | to = br->entries[i].to; | ||
627 | |||
628 | thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); | ||
629 | if (alf.map && !alf.map->dso->adjust_symbols) | ||
630 | from = map__map_ip(alf.map, from); | ||
631 | |||
632 | thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); | ||
633 | if (alt.map && !alt.map->dso->adjust_symbols) | ||
634 | to = map__map_ip(alt.map, to); | ||
635 | |||
636 | printf("0x%"PRIx64, from); | ||
637 | if (PRINT_FIELD(DSO)) { | ||
638 | printf("("); | ||
639 | map__fprintf_dsoname(alf.map, stdout); | ||
640 | printf(")"); | ||
641 | } | ||
642 | printf("/0x%"PRIx64, to); | ||
643 | if (PRINT_FIELD(DSO)) { | ||
644 | printf("("); | ||
645 | map__fprintf_dsoname(alt.map, stdout); | ||
646 | printf(")"); | ||
647 | } | ||
648 | printf("/%c/%c/%c/%d ", | ||
649 | mispred_str(br->entries + i), | ||
650 | br->entries[i].flags.in_tx ? 'X' : '-', | ||
651 | br->entries[i].flags.abort ? 'A' : '-', | ||
652 | br->entries[i].flags.cycles); | ||
653 | } | ||
654 | } | ||
572 | #define MAXBB 16384UL | 655 | #define MAXBB 16384UL |
573 | 656 | ||
574 | static int grab_bb(u8 *buffer, u64 start, u64 end, | 657 | static int grab_bb(u8 *buffer, u64 start, u64 end, |
@@ -1187,9 +1270,11 @@ static void process_event(struct perf_script *script, | |||
1187 | print_sample_iregs(sample, attr); | 1270 | print_sample_iregs(sample, attr); |
1188 | 1271 | ||
1189 | if (PRINT_FIELD(BRSTACK)) | 1272 | if (PRINT_FIELD(BRSTACK)) |
1190 | print_sample_brstack(sample); | 1273 | print_sample_brstack(sample, thread, attr); |
1191 | else if (PRINT_FIELD(BRSTACKSYM)) | 1274 | else if (PRINT_FIELD(BRSTACKSYM)) |
1192 | print_sample_brstacksym(sample, thread); | 1275 | print_sample_brstacksym(sample, thread, attr); |
1276 | else if (PRINT_FIELD(BRSTACKOFF)) | ||
1277 | print_sample_brstackoff(sample, thread, attr); | ||
1193 | 1278 | ||
1194 | if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) | 1279 | if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) |
1195 | print_sample_bpf_output(sample); | 1280 | print_sample_bpf_output(sample); |
@@ -1727,6 +1812,7 @@ static int parse_output_fields(const struct option *opt __maybe_unused, | |||
1727 | int rc = 0; | 1812 | int rc = 0; |
1728 | char *str = strdup(arg); | 1813 | char *str = strdup(arg); |
1729 | int type = -1; | 1814 | int type = -1; |
1815 | enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT; | ||
1730 | 1816 | ||
1731 | if (!str) | 1817 | if (!str) |
1732 | return -ENOMEM; | 1818 | return -ENOMEM; |
@@ -1772,6 +1858,10 @@ static int parse_output_fields(const struct option *opt __maybe_unused, | |||
1772 | goto out; | 1858 | goto out; |
1773 | } | 1859 | } |
1774 | 1860 | ||
1861 | /* Don't override defaults for +- */ | ||
1862 | if (strchr(str, '+') || strchr(str, '-')) | ||
1863 | goto parse; | ||
1864 | |||
1775 | if (output_set_by_user()) | 1865 | if (output_set_by_user()) |
1776 | pr_warning("Overriding previous field request for all events.\n"); | 1866 | pr_warning("Overriding previous field request for all events.\n"); |
1777 | 1867 | ||
@@ -1782,13 +1872,30 @@ static int parse_output_fields(const struct option *opt __maybe_unused, | |||
1782 | } | 1872 | } |
1783 | } | 1873 | } |
1784 | 1874 | ||
1875 | parse: | ||
1785 | for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) { | 1876 | for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) { |
1877 | if (*tok == '+') { | ||
1878 | if (change == SET) | ||
1879 | goto out_badmix; | ||
1880 | change = ADD; | ||
1881 | tok++; | ||
1882 | } else if (*tok == '-') { | ||
1883 | if (change == SET) | ||
1884 | goto out_badmix; | ||
1885 | change = REMOVE; | ||
1886 | tok++; | ||
1887 | } else { | ||
1888 | if (change != SET && change != DEFAULT) | ||
1889 | goto out_badmix; | ||
1890 | change = SET; | ||
1891 | } | ||
1892 | |||
1786 | for (i = 0; i < imax; ++i) { | 1893 | for (i = 0; i < imax; ++i) { |
1787 | if (strcmp(tok, all_output_options[i].str) == 0) | 1894 | if (strcmp(tok, all_output_options[i].str) == 0) |
1788 | break; | 1895 | break; |
1789 | } | 1896 | } |
1790 | if (i == imax && strcmp(tok, "flags") == 0) { | 1897 | if (i == imax && strcmp(tok, "flags") == 0) { |
1791 | print_flags = true; | 1898 | print_flags = change == REMOVE ? false : true; |
1792 | continue; | 1899 | continue; |
1793 | } | 1900 | } |
1794 | if (i == imax) { | 1901 | if (i == imax) { |
@@ -1805,8 +1912,12 @@ static int parse_output_fields(const struct option *opt __maybe_unused, | |||
1805 | if (output[j].invalid_fields & all_output_options[i].field) { | 1912 | if (output[j].invalid_fields & all_output_options[i].field) { |
1806 | pr_warning("\'%s\' not valid for %s events. Ignoring.\n", | 1913 | pr_warning("\'%s\' not valid for %s events. Ignoring.\n", |
1807 | all_output_options[i].str, event_type(j)); | 1914 | all_output_options[i].str, event_type(j)); |
1808 | } else | 1915 | } else { |
1809 | output[j].fields |= all_output_options[i].field; | 1916 | if (change == REMOVE) |
1917 | output[j].fields &= ~all_output_options[i].field; | ||
1918 | else | ||
1919 | output[j].fields |= all_output_options[i].field; | ||
1920 | } | ||
1810 | } | 1921 | } |
1811 | } else { | 1922 | } else { |
1812 | if (output[type].invalid_fields & all_output_options[i].field) { | 1923 | if (output[type].invalid_fields & all_output_options[i].field) { |
@@ -1826,7 +1937,11 @@ static int parse_output_fields(const struct option *opt __maybe_unused, | |||
1826 | "Events will not be displayed.\n", event_type(type)); | 1937 | "Events will not be displayed.\n", event_type(type)); |
1827 | } | 1938 | } |
1828 | } | 1939 | } |
1940 | goto out; | ||
1829 | 1941 | ||
1942 | out_badmix: | ||
1943 | fprintf(stderr, "Cannot mix +-field with overridden fields\n"); | ||
1944 | rc = -EINVAL; | ||
1830 | out: | 1945 | out: |
1831 | free(str); | 1946 | free(str); |
1832 | return rc; | 1947 | return rc; |
@@ -2444,6 +2559,7 @@ int cmd_script(int argc, const char **argv) | |||
2444 | symbol__config_symfs), | 2559 | symbol__config_symfs), |
2445 | OPT_CALLBACK('F', "fields", NULL, "str", | 2560 | OPT_CALLBACK('F', "fields", NULL, "str", |
2446 | "comma separated output fields prepend with 'type:'. " | 2561 | "comma separated output fields prepend with 'type:'. " |
2562 | "+field to add and -field to remove." | ||
2447 | "Valid types: hw,sw,trace,raw. " | 2563 | "Valid types: hw,sw,trace,raw. " |
2448 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," | 2564 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," |
2449 | "addr,symoff,period,iregs,brstack,brstacksym,flags," | 2565 | "addr,symoff,period,iregs,brstack,brstacksym,flags," |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 10b6362ca0bf..2bcfa46913c8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -134,7 +134,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) | |||
134 | return err; | 134 | return err; |
135 | } | 135 | } |
136 | 136 | ||
137 | err = symbol__disassemble(sym, map, NULL, 0); | 137 | err = symbol__disassemble(sym, map, NULL, 0, NULL); |
138 | if (err == 0) { | 138 | if (err == 0) { |
139 | out_assign: | 139 | out_assign: |
140 | top->sym_filter_entry = he; | 140 | top->sym_filter_entry = he; |
diff --git a/tools/perf/jvmti/jvmti_agent.h b/tools/perf/jvmti/jvmti_agent.h index bedf5d0ba9ff..c53a41f48b63 100644 --- a/tools/perf/jvmti/jvmti_agent.h +++ b/tools/perf/jvmti/jvmti_agent.h | |||
@@ -5,8 +5,6 @@ | |||
5 | #include <stdint.h> | 5 | #include <stdint.h> |
6 | #include <jvmti.h> | 6 | #include <jvmti.h> |
7 | 7 | ||
8 | #define __unused __attribute__((unused)) | ||
9 | |||
10 | #if defined(__cplusplus) | 8 | #if defined(__cplusplus) |
11 | extern "C" { | 9 | extern "C" { |
12 | #endif | 10 | #endif |
diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c index 5612641c69b4..6d710904c837 100644 --- a/tools/perf/jvmti/libjvmti.c +++ b/tools/perf/jvmti/libjvmti.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/compiler.h> | ||
1 | #include <sys/types.h> | 2 | #include <sys/types.h> |
2 | #include <stdio.h> | 3 | #include <stdio.h> |
3 | #include <string.h> | 4 | #include <string.h> |
@@ -238,7 +239,7 @@ code_generated_cb(jvmtiEnv *jvmti, | |||
238 | } | 239 | } |
239 | 240 | ||
240 | JNIEXPORT jint JNICALL | 241 | JNIEXPORT jint JNICALL |
241 | Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __unused) | 242 | Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __maybe_unused) |
242 | { | 243 | { |
243 | jvmtiEventCallbacks cb; | 244 | jvmtiEventCallbacks cb; |
244 | jvmtiCapabilities caps1; | 245 | jvmtiCapabilities caps1; |
@@ -313,7 +314,7 @@ Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __unused) | |||
313 | } | 314 | } |
314 | 315 | ||
315 | JNIEXPORT void JNICALL | 316 | JNIEXPORT void JNICALL |
316 | Agent_OnUnload(JavaVM *jvm __unused) | 317 | Agent_OnUnload(JavaVM *jvm __maybe_unused) |
317 | { | 318 | { |
318 | int ret; | 319 | int ret; |
319 | 320 | ||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index baa073f38334..bd0aabb2bd0f 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c | |||
@@ -48,10 +48,6 @@ | |||
48 | #include "json.h" | 48 | #include "json.h" |
49 | #include "jevents.h" | 49 | #include "jevents.h" |
50 | 50 | ||
51 | #ifndef __maybe_unused | ||
52 | #define __maybe_unused __attribute__((unused)) | ||
53 | #endif | ||
54 | |||
55 | int verbose; | 51 | int verbose; |
56 | char *prog; | 52 | char *prog; |
57 | 53 | ||
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 8ba2c4618fe9..39bbb97cd30a 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c | |||
@@ -62,8 +62,7 @@ static void __test_function(volatile long *ptr) | |||
62 | } | 62 | } |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | __attribute__ ((noinline)) | 65 | static noinline int test_function(void) |
66 | static int test_function(void) | ||
67 | { | 66 | { |
68 | __test_function(&the_var); | 67 | __test_function(&the_var); |
69 | the_var++; | 68 | the_var++; |
diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index 89f92fa67cc4..3b1ac6f31b15 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c | |||
@@ -28,8 +28,7 @@ | |||
28 | 28 | ||
29 | static int overflows; | 29 | static int overflows; |
30 | 30 | ||
31 | __attribute__ ((noinline)) | 31 | static noinline int test_function(void) |
32 | static int test_function(void) | ||
33 | { | 32 | { |
34 | return time(NULL); | 33 | return time(NULL); |
35 | } | 34 | } |
diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index 7230e62c70fc..b4ebc75e25ae 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c | |||
@@ -10,6 +10,15 @@ | |||
10 | 10 | ||
11 | #include <uapi/linux/fs.h> | 11 | #include <uapi/linux/fs.h> |
12 | 12 | ||
13 | /* | ||
14 | * If CONFIG_PROFILE_ALL_BRANCHES is selected, | ||
15 | * 'if' is redefined after include kernel header. | ||
16 | * Recover 'if' for BPF object code. | ||
17 | */ | ||
18 | #ifdef if | ||
19 | # undef if | ||
20 | #endif | ||
21 | |||
13 | #define FMODE_READ 0x1 | 22 | #define FMODE_READ 0x1 |
14 | #define FMODE_WRITE 0x2 | 23 | #define FMODE_WRITE 0x2 |
15 | 24 | ||
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index dfe5c89e2049..3e56d08f7995 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c | |||
@@ -76,8 +76,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) | |||
76 | return strcmp((const char *) symbol, funcs[idx]); | 76 | return strcmp((const char *) symbol, funcs[idx]); |
77 | } | 77 | } |
78 | 78 | ||
79 | __attribute__ ((noinline)) | 79 | static noinline int unwind_thread(struct thread *thread) |
80 | static int unwind_thread(struct thread *thread) | ||
81 | { | 80 | { |
82 | struct perf_sample sample; | 81 | struct perf_sample sample; |
83 | unsigned long cnt = 0; | 82 | unsigned long cnt = 0; |
@@ -108,8 +107,7 @@ static int unwind_thread(struct thread *thread) | |||
108 | 107 | ||
109 | static int global_unwind_retval = -INT_MAX; | 108 | static int global_unwind_retval = -INT_MAX; |
110 | 109 | ||
111 | __attribute__ ((noinline)) | 110 | static noinline int compare(void *p1, void *p2) |
112 | static int compare(void *p1, void *p2) | ||
113 | { | 111 | { |
114 | /* Any possible value should be 'thread' */ | 112 | /* Any possible value should be 'thread' */ |
115 | struct thread *thread = *(struct thread **)p1; | 113 | struct thread *thread = *(struct thread **)p1; |
@@ -128,8 +126,7 @@ static int compare(void *p1, void *p2) | |||
128 | return p1 - p2; | 126 | return p1 - p2; |
129 | } | 127 | } |
130 | 128 | ||
131 | __attribute__ ((noinline)) | 129 | static noinline int krava_3(struct thread *thread) |
132 | static int krava_3(struct thread *thread) | ||
133 | { | 130 | { |
134 | struct thread *array[2] = {thread, thread}; | 131 | struct thread *array[2] = {thread, thread}; |
135 | void *fp = &bsearch; | 132 | void *fp = &bsearch; |
@@ -147,14 +144,12 @@ static int krava_3(struct thread *thread) | |||
147 | return global_unwind_retval; | 144 | return global_unwind_retval; |
148 | } | 145 | } |
149 | 146 | ||
150 | __attribute__ ((noinline)) | 147 | static noinline int krava_2(struct thread *thread) |
151 | static int krava_2(struct thread *thread) | ||
152 | { | 148 | { |
153 | return krava_3(thread); | 149 | return krava_3(thread); |
154 | } | 150 | } |
155 | 151 | ||
156 | __attribute__ ((noinline)) | 152 | static noinline int krava_1(struct thread *thread) |
157 | static int krava_1(struct thread *thread) | ||
158 | { | 153 | { |
159 | return krava_2(thread); | 154 | return krava_2(thread); |
160 | } | 155 | } |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index d990ad08a3c6..27f41f28dcb4 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -46,12 +46,15 @@ static struct annotate_browser_opt { | |||
46 | .jump_arrows = true, | 46 | .jump_arrows = true, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct arch; | ||
50 | |||
49 | struct annotate_browser { | 51 | struct annotate_browser { |
50 | struct ui_browser b; | 52 | struct ui_browser b; |
51 | struct rb_root entries; | 53 | struct rb_root entries; |
52 | struct rb_node *curr_hot; | 54 | struct rb_node *curr_hot; |
53 | struct disasm_line *selection; | 55 | struct disasm_line *selection; |
54 | struct disasm_line **offsets; | 56 | struct disasm_line **offsets; |
57 | struct arch *arch; | ||
55 | int nr_events; | 58 | int nr_events; |
56 | u64 start; | 59 | u64 start; |
57 | int nr_asm_entries; | 60 | int nr_asm_entries; |
@@ -125,43 +128,57 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
125 | int i, pcnt_width = annotate_browser__pcnt_width(ab); | 128 | int i, pcnt_width = annotate_browser__pcnt_width(ab); |
126 | double percent_max = 0.0; | 129 | double percent_max = 0.0; |
127 | char bf[256]; | 130 | char bf[256]; |
131 | bool show_title = false; | ||
128 | 132 | ||
129 | for (i = 0; i < ab->nr_events; i++) { | 133 | for (i = 0; i < ab->nr_events; i++) { |
130 | if (bdl->samples[i].percent > percent_max) | 134 | if (bdl->samples[i].percent > percent_max) |
131 | percent_max = bdl->samples[i].percent; | 135 | percent_max = bdl->samples[i].percent; |
132 | } | 136 | } |
133 | 137 | ||
138 | if ((row == 0) && (dl->offset == -1 || percent_max == 0.0)) { | ||
139 | if (ab->have_cycles) { | ||
140 | if (dl->ipc == 0.0 && dl->cycles == 0) | ||
141 | show_title = true; | ||
142 | } else | ||
143 | show_title = true; | ||
144 | } | ||
145 | |||
134 | if (dl->offset != -1 && percent_max != 0.0) { | 146 | if (dl->offset != -1 && percent_max != 0.0) { |
135 | if (percent_max != 0.0) { | 147 | for (i = 0; i < ab->nr_events; i++) { |
136 | for (i = 0; i < ab->nr_events; i++) { | 148 | ui_browser__set_percent_color(browser, |
137 | ui_browser__set_percent_color(browser, | 149 | bdl->samples[i].percent, |
138 | bdl->samples[i].percent, | 150 | current_entry); |
139 | current_entry); | 151 | if (annotate_browser__opts.show_total_period) { |
140 | if (annotate_browser__opts.show_total_period) { | 152 | ui_browser__printf(browser, "%6" PRIu64 " ", |
141 | ui_browser__printf(browser, "%6" PRIu64 " ", | 153 | bdl->samples[i].nr); |
142 | bdl->samples[i].nr); | 154 | } else { |
143 | } else { | 155 | ui_browser__printf(browser, "%6.2f ", |
144 | ui_browser__printf(browser, "%6.2f ", | 156 | bdl->samples[i].percent); |
145 | bdl->samples[i].percent); | ||
146 | } | ||
147 | } | 157 | } |
148 | } else { | ||
149 | ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); | ||
150 | } | 158 | } |
151 | } else { | 159 | } else { |
152 | ui_browser__set_percent_color(browser, 0, current_entry); | 160 | ui_browser__set_percent_color(browser, 0, current_entry); |
153 | ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); | 161 | |
162 | if (!show_title) | ||
163 | ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); | ||
164 | else | ||
165 | ui_browser__printf(browser, "%*s", 7, "Percent"); | ||
154 | } | 166 | } |
155 | if (ab->have_cycles) { | 167 | if (ab->have_cycles) { |
156 | if (dl->ipc) | 168 | if (dl->ipc) |
157 | ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); | 169 | ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); |
158 | else | 170 | else if (!show_title) |
159 | ui_browser__write_nstring(browser, " ", IPC_WIDTH); | 171 | ui_browser__write_nstring(browser, " ", IPC_WIDTH); |
172 | else | ||
173 | ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC"); | ||
174 | |||
160 | if (dl->cycles) | 175 | if (dl->cycles) |
161 | ui_browser__printf(browser, "%*" PRIu64 " ", | 176 | ui_browser__printf(browser, "%*" PRIu64 " ", |
162 | CYCLES_WIDTH - 1, dl->cycles); | 177 | CYCLES_WIDTH - 1, dl->cycles); |
163 | else | 178 | else if (!show_title) |
164 | ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); | 179 | ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); |
180 | else | ||
181 | ui_browser__printf(browser, "%*s ", CYCLES_WIDTH - 1, "Cycle"); | ||
165 | } | 182 | } |
166 | 183 | ||
167 | SLsmg_write_char(' '); | 184 | SLsmg_write_char(' '); |
@@ -1056,7 +1073,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1056 | (nr_pcnt - 1); | 1073 | (nr_pcnt - 1); |
1057 | } | 1074 | } |
1058 | 1075 | ||
1059 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), sizeof_bdl); | 1076 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), |
1077 | sizeof_bdl, &browser.arch); | ||
1060 | if (err) { | 1078 | if (err) { |
1061 | char msg[BUFSIZ]; | 1079 | char msg[BUFSIZ]; |
1062 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); | 1080 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); |
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index e99ba86158d2..d903fd493416 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c | |||
@@ -168,7 +168,8 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, | |||
168 | if (map->dso->annotate_warned) | 168 | if (map->dso->annotate_warned) |
169 | return -1; | 169 | return -1; |
170 | 170 | ||
171 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0); | 171 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), |
172 | 0, NULL); | ||
172 | if (err) { | 173 | if (err) { |
173 | char msg[BUFSIZ]; | 174 | char msg[BUFSIZ]; |
174 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); | 175 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ddbd56df9187..be1caabb9290 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -1379,7 +1379,9 @@ static const char *annotate__norm_arch(const char *arch_name) | |||
1379 | return normalize_arch((char *)arch_name); | 1379 | return normalize_arch((char *)arch_name); |
1380 | } | 1380 | } |
1381 | 1381 | ||
1382 | int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize) | 1382 | int symbol__disassemble(struct symbol *sym, struct map *map, |
1383 | const char *arch_name, size_t privsize, | ||
1384 | struct arch **parch) | ||
1383 | { | 1385 | { |
1384 | struct dso *dso = map->dso; | 1386 | struct dso *dso = map->dso; |
1385 | char command[PATH_MAX * 2]; | 1387 | char command[PATH_MAX * 2]; |
@@ -1405,6 +1407,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na | |||
1405 | if (arch == NULL) | 1407 | if (arch == NULL) |
1406 | return -ENOTSUP; | 1408 | return -ENOTSUP; |
1407 | 1409 | ||
1410 | if (parch) | ||
1411 | *parch = arch; | ||
1412 | |||
1408 | if (arch->init) { | 1413 | if (arch->init) { |
1409 | err = arch->init(arch); | 1414 | err = arch->init(arch); |
1410 | if (err) { | 1415 | if (err) { |
@@ -1901,7 +1906,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
1901 | struct rb_root source_line = RB_ROOT; | 1906 | struct rb_root source_line = RB_ROOT; |
1902 | u64 len; | 1907 | u64 len; |
1903 | 1908 | ||
1904 | if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0) < 0) | 1909 | if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), |
1910 | 0, NULL) < 0) | ||
1905 | return -1; | 1911 | return -1; |
1906 | 1912 | ||
1907 | len = symbol__size(sym); | 1913 | len = symbol__size(sym); |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 948aa8e6fd39..21055034aedd 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -158,7 +158,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); | |||
158 | int symbol__alloc_hist(struct symbol *sym); | 158 | int symbol__alloc_hist(struct symbol *sym); |
159 | void symbol__annotate_zero_histograms(struct symbol *sym); | 159 | void symbol__annotate_zero_histograms(struct symbol *sym); |
160 | 160 | ||
161 | int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize); | 161 | int symbol__disassemble(struct symbol *sym, struct map *map, |
162 | const char *arch_name, size_t privsize, | ||
163 | struct arch **parch); | ||
162 | 164 | ||
163 | enum symbol_disassemble_errno { | 165 | enum symbol_disassemble_errno { |
164 | SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, | 166 | SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, |
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 0328f297a748..0175765c05b9 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <subcmd/pager.h> | 5 | #include <subcmd/pager.h> |
6 | #include "../ui/ui.h" | 6 | #include "../ui/ui.h" |
7 | 7 | ||
8 | #include <linux/compiler.h> | ||
8 | #include <linux/string.h> | 9 | #include <linux/string.h> |
9 | 10 | ||
10 | #define CMD_EXEC_PATH "--exec-path" | 11 | #define CMD_EXEC_PATH "--exec-path" |
@@ -24,6 +25,6 @@ static inline int is_absolute_path(const char *path) | |||
24 | return path[0] == '/'; | 25 | return path[0] == '/'; |
25 | } | 26 | } |
26 | 27 | ||
27 | char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | 28 | char *mkpath(const char *fmt, ...) __printf(1, 2); |
28 | 29 | ||
29 | #endif /* __PERF_CACHE_H */ | 30 | #endif /* __PERF_CACHE_H */ |
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 8a23ea1a71c7..c818bdb1c1ab 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | #include <string.h> | 6 | #include <string.h> |
7 | #include <linux/compiler.h> | ||
7 | #include "event.h" | 8 | #include "event.h" |
8 | #include "../ui/helpline.h" | 9 | #include "../ui/helpline.h" |
9 | #include "../ui/progress.h" | 10 | #include "../ui/progress.h" |
@@ -40,16 +41,16 @@ extern int debug_data_convert; | |||
40 | 41 | ||
41 | #define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */ | 42 | #define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */ |
42 | 43 | ||
43 | int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); | 44 | int dump_printf(const char *fmt, ...) __printf(1, 2); |
44 | void trace_event(union perf_event *event); | 45 | void trace_event(union perf_event *event); |
45 | 46 | ||
46 | int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); | 47 | int ui__error(const char *format, ...) __printf(1, 2); |
47 | int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); | 48 | int ui__warning(const char *format, ...) __printf(1, 2); |
48 | 49 | ||
49 | void pr_stat(const char *fmt, ...); | 50 | void pr_stat(const char *fmt, ...); |
50 | 51 | ||
51 | int eprintf(int level, int var, const char *fmt, ...) __attribute__((format(printf, 3, 4))); | 52 | int eprintf(int level, int var, const char *fmt, ...) __printf(3, 4); |
52 | int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __attribute__((format(printf, 4, 5))); | 53 | int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __printf(4, 5); |
53 | int veprintf(int level, int var, const char *fmt, va_list args); | 54 | int veprintf(int level, int var, const char *fmt, va_list args); |
54 | 55 | ||
55 | int perf_debug_option(const char *str); | 56 | int perf_debug_option(const char *str); |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 94cea4398a13..8d601fbdd8d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __PERF_EVLIST_H | 1 | #ifndef __PERF_EVLIST_H |
2 | #define __PERF_EVLIST_H 1 | 2 | #define __PERF_EVLIST_H 1 |
3 | 3 | ||
4 | #include <linux/compiler.h> | ||
4 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
5 | #include <linux/refcount.h> | 6 | #include <linux/refcount.h> |
6 | #include <linux/list.h> | 7 | #include <linux/list.h> |
@@ -34,7 +35,7 @@ struct perf_mmap { | |||
34 | refcount_t refcnt; | 35 | refcount_t refcnt; |
35 | u64 prev; | 36 | u64 prev; |
36 | struct auxtrace_mmap auxtrace_mmap; | 37 | struct auxtrace_mmap auxtrace_mmap; |
37 | char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); | 38 | char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8); |
38 | }; | 39 | }; |
39 | 40 | ||
40 | static inline size_t | 41 | static inline size_t |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index cda44b0e821c..7f78f27f5382 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <traceevent/event-parse.h> | 15 | #include <traceevent/event-parse.h> |
16 | #include <linux/hw_breakpoint.h> | 16 | #include <linux/hw_breakpoint.h> |
17 | #include <linux/perf_event.h> | 17 | #include <linux/perf_event.h> |
18 | #include <linux/compiler.h> | ||
18 | #include <linux/err.h> | 19 | #include <linux/err.h> |
19 | #include <sys/ioctl.h> | 20 | #include <sys/ioctl.h> |
20 | #include <sys/resource.h> | 21 | #include <sys/resource.h> |
@@ -1441,7 +1442,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, | |||
1441 | } | 1442 | } |
1442 | 1443 | ||
1443 | static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, | 1444 | static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, |
1444 | void *priv __attribute__((unused))) | 1445 | void *priv __maybe_unused) |
1445 | { | 1446 | { |
1446 | return fprintf(fp, " %-32s %s\n", name, val); | 1447 | return fprintf(fp, " %-32s %s\n", name, val); |
1447 | } | 1448 | } |
diff --git a/tools/perf/util/genelf_debug.c b/tools/perf/util/genelf_debug.c index 5980f7d256b1..40789d8603d0 100644 --- a/tools/perf/util/genelf_debug.c +++ b/tools/perf/util/genelf_debug.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * @remark Copyright 2007 OProfile authors | 11 | * @remark Copyright 2007 OProfile authors |
12 | * @author Philippe Elie | 12 | * @author Philippe Elie |
13 | */ | 13 | */ |
14 | #include <linux/compiler.h> | ||
14 | #include <sys/types.h> | 15 | #include <sys/types.h> |
15 | #include <stdio.h> | 16 | #include <stdio.h> |
16 | #include <getopt.h> | 17 | #include <getopt.h> |
@@ -125,7 +126,7 @@ struct debug_line_header { | |||
125 | * and filesize, last entry is followed by en empty string. | 126 | * and filesize, last entry is followed by en empty string. |
126 | */ | 127 | */ |
127 | /* follow the first program statement */ | 128 | /* follow the first program statement */ |
128 | } __attribute__((packed)); | 129 | } __packed; |
129 | 130 | ||
130 | /* DWARF 2 spec talk only about one possible compilation unit header while | 131 | /* DWARF 2 spec talk only about one possible compilation unit header while |
131 | * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not | 132 | * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not |
@@ -138,7 +139,7 @@ struct compilation_unit_header { | |||
138 | uhalf version; | 139 | uhalf version; |
139 | uword debug_abbrev_offset; | 140 | uword debug_abbrev_offset; |
140 | ubyte pointer_size; | 141 | ubyte pointer_size; |
141 | } __attribute__((packed)); | 142 | } __packed; |
142 | 143 | ||
143 | #define DW_LNS_num_opcode (DW_LNS_set_isa + 1) | 144 | #define DW_LNS_num_opcode (DW_LNS_set_isa + 1) |
144 | 145 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index b5baff3007bb..76ed7d03e500 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <linux/compiler.h> | ||
11 | #include <linux/list.h> | 12 | #include <linux/list.h> |
12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
13 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
@@ -1274,7 +1275,7 @@ error: | |||
1274 | } | 1275 | } |
1275 | 1276 | ||
1276 | static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, | 1277 | static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, |
1277 | void *priv __attribute__((unused))) | 1278 | void *priv __maybe_unused) |
1278 | { | 1279 | { |
1279 | return fprintf(fp, ", %s = %s", name, val); | 1280 | return fprintf(fp, ", %s = %s", name, val); |
1280 | } | 1281 | } |
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index b2834ac7b1f5..218ee2bac9a5 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c | |||
@@ -866,8 +866,6 @@ static void intel_bts_print_info(u64 *arr, int start, int finish) | |||
866 | fprintf(stdout, intel_bts_info_fmts[i], arr[i]); | 866 | fprintf(stdout, intel_bts_info_fmts[i], arr[i]); |
867 | } | 867 | } |
868 | 868 | ||
869 | u64 intel_bts_auxtrace_info_priv[INTEL_BTS_AUXTRACE_PRIV_SIZE]; | ||
870 | |||
871 | int intel_bts_process_auxtrace_info(union perf_event *event, | 869 | int intel_bts_process_auxtrace_info(union perf_event *event, |
872 | struct perf_session *session) | 870 | struct perf_session *session) |
873 | { | 871 | { |
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.h b/tools/perf/util/intel-pt-decoder/intel-pt-log.h index debe751dc3d6..45b64f93f358 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-log.h +++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #ifndef INCLUDE__INTEL_PT_LOG_H__ | 16 | #ifndef INCLUDE__INTEL_PT_LOG_H__ |
17 | #define INCLUDE__INTEL_PT_LOG_H__ | 17 | #define INCLUDE__INTEL_PT_LOG_H__ |
18 | 18 | ||
19 | #include <linux/compiler.h> | ||
19 | #include <stdint.h> | 20 | #include <stdint.h> |
20 | #include <inttypes.h> | 21 | #include <inttypes.h> |
21 | 22 | ||
@@ -34,8 +35,7 @@ void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip); | |||
34 | void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, | 35 | void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, |
35 | uint64_t ip); | 36 | uint64_t ip); |
36 | 37 | ||
37 | __attribute__((format(printf, 1, 2))) | 38 | void __intel_pt_log(const char *fmt, ...) __printf(1, 2); |
38 | void __intel_pt_log(const char *fmt, ...); | ||
39 | 39 | ||
40 | #define intel_pt_log(fmt, ...) \ | 40 | #define intel_pt_log(fmt, ...) \ |
41 | do { \ | 41 | do { \ |
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index ea7f450dc609..389e9729331f 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __PMU_H | 2 | #define __PMU_H |
3 | 3 | ||
4 | #include <linux/bitmap.h> | 4 | #include <linux/bitmap.h> |
5 | #include <linux/compiler.h> | ||
5 | #include <linux/perf_event.h> | 6 | #include <linux/perf_event.h> |
6 | #include <stdbool.h> | 7 | #include <stdbool.h> |
7 | #include "evsel.h" | 8 | #include "evsel.h" |
@@ -83,8 +84,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet, | |||
83 | bool long_desc, bool details_flag); | 84 | bool long_desc, bool details_flag); |
84 | bool pmu_have_event(const char *pname, const char *name); | 85 | bool pmu_have_event(const char *pname, const char *name); |
85 | 86 | ||
86 | int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, | 87 | int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4); |
87 | ...) __attribute__((format(scanf, 3, 4))); | ||
88 | 88 | ||
89 | int perf_pmu__test(void); | 89 | int perf_pmu__test(void); |
90 | 90 | ||
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 373842656fb6..5812947418dd 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _PROBE_EVENT_H | 1 | #ifndef _PROBE_EVENT_H |
2 | #define _PROBE_EVENT_H | 2 | #define _PROBE_EVENT_H |
3 | 3 | ||
4 | #include <linux/compiler.h> | ||
4 | #include <stdbool.h> | 5 | #include <stdbool.h> |
5 | #include "intlist.h" | 6 | #include "intlist.h" |
6 | 7 | ||
@@ -171,8 +172,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev, | |||
171 | struct symbol *sym); | 172 | struct symbol *sym); |
172 | 173 | ||
173 | /* If there is no space to write, returns -E2BIG. */ | 174 | /* If there is no space to write, returns -E2BIG. */ |
174 | int e_snprintf(char *str, size_t size, const char *format, ...) | 175 | int e_snprintf(char *str, size_t size, const char *format, ...) __printf(3, 4); |
175 | __attribute__((format(printf, 3, 4))); | ||
176 | 176 | ||
177 | /* Maximum index number of event-name postfix */ | 177 | /* Maximum index number of event-name postfix */ |
178 | #define MAX_EVENT_INDEX 1024 | 178 | #define MAX_EVENT_INDEX 1024 |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 40de3cb40d21..57b7a00e6f16 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <stdbool.h> | 28 | #include <stdbool.h> |
29 | #include <errno.h> | 29 | #include <errno.h> |
30 | #include <linux/bitmap.h> | 30 | #include <linux/bitmap.h> |
31 | #include <linux/compiler.h> | ||
31 | #include <linux/time64.h> | 32 | #include <linux/time64.h> |
32 | 33 | ||
33 | #include "../../perf.h" | 34 | #include "../../perf.h" |
@@ -84,7 +85,7 @@ struct tables { | |||
84 | 85 | ||
85 | static struct tables tables_global; | 86 | static struct tables tables_global; |
86 | 87 | ||
87 | static void handler_call_die(const char *handler_name) NORETURN; | 88 | static void handler_call_die(const char *handler_name) __noreturn; |
88 | static void handler_call_die(const char *handler_name) | 89 | static void handler_call_die(const char *handler_name) |
89 | { | 90 | { |
90 | PyErr_Print(); | 91 | PyErr_Print(); |
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h index 318424ea561d..802d743378af 100644 --- a/tools/perf/util/strbuf.h +++ b/tools/perf/util/strbuf.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <stdarg.h> | 42 | #include <stdarg.h> |
43 | #include <stddef.h> | 43 | #include <stddef.h> |
44 | #include <string.h> | 44 | #include <string.h> |
45 | #include <linux/compiler.h> | ||
45 | #include <sys/types.h> | 46 | #include <sys/types.h> |
46 | 47 | ||
47 | extern char strbuf_slopbuf[]; | 48 | extern char strbuf_slopbuf[]; |
@@ -85,8 +86,7 @@ static inline int strbuf_addstr(struct strbuf *sb, const char *s) { | |||
85 | return strbuf_add(sb, s, strlen(s)); | 86 | return strbuf_add(sb, s, strlen(s)); |
86 | } | 87 | } |
87 | 88 | ||
88 | __attribute__((format(printf,2,3))) | 89 | int strbuf_addf(struct strbuf *sb, const char *fmt, ...) __printf(2, 3); |
89 | int strbuf_addf(struct strbuf *sb, const char *fmt, ...); | ||
90 | 90 | ||
91 | /* XXX: if read fails, any partial read is undone */ | 91 | /* XXX: if read fails, any partial read is undone */ |
92 | ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); | 92 | ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); |
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c index 996046a66fe5..aacb65e079aa 100644 --- a/tools/perf/util/usage.c +++ b/tools/perf/util/usage.c | |||
@@ -16,13 +16,13 @@ static void report(const char *prefix, const char *err, va_list params) | |||
16 | fprintf(stderr, " %s%s\n", prefix, msg); | 16 | fprintf(stderr, " %s%s\n", prefix, msg); |
17 | } | 17 | } |
18 | 18 | ||
19 | static NORETURN void usage_builtin(const char *err) | 19 | static __noreturn void usage_builtin(const char *err) |
20 | { | 20 | { |
21 | fprintf(stderr, "\n Usage: %s\n", err); | 21 | fprintf(stderr, "\n Usage: %s\n", err); |
22 | exit(129); | 22 | exit(129); |
23 | } | 23 | } |
24 | 24 | ||
25 | static NORETURN void die_builtin(const char *err, va_list params) | 25 | static __noreturn void die_builtin(const char *err, va_list params) |
26 | { | 26 | { |
27 | report(" Fatal: ", err, params); | 27 | report(" Fatal: ", err, params); |
28 | exit(128); | 28 | exit(128); |
@@ -40,7 +40,7 @@ static void warn_builtin(const char *warn, va_list params) | |||
40 | 40 | ||
41 | /* If we are in a dlopen()ed .so write to a global variable would segfault | 41 | /* If we are in a dlopen()ed .so write to a global variable would segfault |
42 | * (ugh), so keep things static. */ | 42 | * (ugh), so keep things static. */ |
43 | static void (*usage_routine)(const char *err) NORETURN = usage_builtin; | 43 | static void (*usage_routine)(const char *err) __noreturn = usage_builtin; |
44 | static void (*error_routine)(const char *err, va_list params) = error_builtin; | 44 | static void (*error_routine)(const char *err, va_list params) = error_builtin; |
45 | static void (*warn_routine)(const char *err, va_list params) = warn_builtin; | 45 | static void (*warn_routine)(const char *err, va_list params) = warn_builtin; |
46 | 46 | ||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 5dfb9bb6482d..21c6db173bcc 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -11,22 +11,14 @@ | |||
11 | #include <stddef.h> | 11 | #include <stddef.h> |
12 | #include <stdlib.h> | 12 | #include <stdlib.h> |
13 | #include <stdarg.h> | 13 | #include <stdarg.h> |
14 | #include <linux/compiler.h> | ||
14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
15 | 16 | ||
16 | #ifdef __GNUC__ | ||
17 | #define NORETURN __attribute__((__noreturn__)) | ||
18 | #else | ||
19 | #define NORETURN | ||
20 | #ifndef __attribute__ | ||
21 | #define __attribute__(x) | ||
22 | #endif | ||
23 | #endif | ||
24 | |||
25 | /* General helper functions */ | 17 | /* General helper functions */ |
26 | void usage(const char *err) NORETURN; | 18 | void usage(const char *err) __noreturn; |
27 | void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); | 19 | void die(const char *err, ...) __noreturn __printf(1, 2); |
28 | int error(const char *err, ...) __attribute__((format (printf, 1, 2))); | 20 | int error(const char *err, ...) __printf(1, 2); |
29 | void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); | 21 | void warning(const char *err, ...) __printf(1, 2); |
30 | 22 | ||
31 | void set_warning_routine(void (*routine)(const char *err, va_list params)); | 23 | void set_warning_routine(void (*routine)(const char *err, va_list params)); |
32 | 24 | ||