diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-12-11 14:48:41 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-12-11 15:22:39 -0500 |
commit | 2376c67a7bbc7849b806688ba2efb8520c21c458 (patch) | |
tree | 03d6f5612b7822d6a85e9251aa3eab931237d6ba | |
parent | 75d9a10854db6aab2400cd6a844c392107be4c64 (diff) |
perf top: Use perf_evlist__config()
Using struct perf_record_opts to specify how to configure the evsel
perf_event_attrs.
This gets top closer to record in the way it sets up evsels, with the
aim of sharing more and more to the point that both will be a single
utility.
In this direction top now uses the same callchain option parsing as
record and that brings DWARF callchains to top, something that was
already available for record.
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: Namhyung Kim <namhyung@gmail.com>
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-u03o0bsrqcjgskciso3pvsjr@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-top.txt | 2 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 204 | ||||
-rw-r--r-- | tools/perf/util/top.c | 22 | ||||
-rw-r--r-- | tools/perf/util/top.h | 8 |
4 files changed, 79 insertions, 157 deletions
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 5b80d84d6b4a..a414bc95fd52 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt | |||
@@ -60,7 +60,7 @@ Default is to monitor all CPUS. | |||
60 | 60 | ||
61 | -i:: | 61 | -i:: |
62 | --inherit:: | 62 | --inherit:: |
63 | Child tasks inherit counters, only makes sens with -p option. | 63 | Child tasks do not inherit counters. |
64 | 64 | ||
65 | -k <path>:: | 65 | -k <path>:: |
66 | --vmlinux=<path>:: | 66 | --vmlinux=<path>:: |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index a30647487ba3..b7d2ea62dbc6 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -596,7 +596,7 @@ static void *display_thread_tui(void *arg) | |||
596 | * via --uid. | 596 | * via --uid. |
597 | */ | 597 | */ |
598 | list_for_each_entry(pos, &top->evlist->entries, node) | 598 | list_for_each_entry(pos, &top->evlist->entries, node) |
599 | pos->hists.uid_filter_str = top->target.uid_str; | 599 | pos->hists.uid_filter_str = top->record_opts.target.uid_str; |
600 | 600 | ||
601 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, | 601 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, |
602 | &top->session->header.env); | 602 | &top->session->header.env); |
@@ -894,34 +894,13 @@ static void perf_top__start_counters(struct perf_top *top) | |||
894 | { | 894 | { |
895 | struct perf_evsel *counter; | 895 | struct perf_evsel *counter; |
896 | struct perf_evlist *evlist = top->evlist; | 896 | struct perf_evlist *evlist = top->evlist; |
897 | struct perf_record_opts *opts = &top->record_opts; | ||
897 | 898 | ||
898 | if (top->group) | 899 | perf_evlist__config(evlist, opts); |
899 | perf_evlist__set_leader(evlist); | ||
900 | 900 | ||
901 | list_for_each_entry(counter, &evlist->entries, node) { | 901 | list_for_each_entry(counter, &evlist->entries, node) { |
902 | struct perf_event_attr *attr = &counter->attr; | 902 | struct perf_event_attr *attr = &counter->attr; |
903 | 903 | ||
904 | perf_evsel__set_sample_bit(counter, IP); | ||
905 | perf_evsel__set_sample_bit(counter, TID); | ||
906 | |||
907 | if (top->freq) { | ||
908 | perf_evsel__set_sample_bit(counter, PERIOD); | ||
909 | attr->freq = 1; | ||
910 | attr->sample_freq = top->freq; | ||
911 | } | ||
912 | |||
913 | if (evlist->nr_entries > 1) | ||
914 | perf_evsel__set_sample_id(counter); | ||
915 | |||
916 | if (perf_target__has_cpu(&top->target)) | ||
917 | perf_evsel__set_sample_bit(counter, CPU); | ||
918 | |||
919 | if (symbol_conf.use_callchain) | ||
920 | perf_evsel__set_sample_bit(counter, CALLCHAIN); | ||
921 | |||
922 | attr->mmap = 1; | ||
923 | attr->comm = 1; | ||
924 | attr->inherit = top->inherit; | ||
925 | fallback_missing_features: | 904 | fallback_missing_features: |
926 | if (top->exclude_guest_missing) | 905 | if (top->exclude_guest_missing) |
927 | attr->exclude_guest = attr->exclude_host = 0; | 906 | attr->exclude_guest = attr->exclude_host = 0; |
@@ -995,7 +974,7 @@ try_again: | |||
995 | } | 974 | } |
996 | } | 975 | } |
997 | 976 | ||
998 | if (perf_evlist__mmap(evlist, top->mmap_pages, false) < 0) { | 977 | if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { |
999 | ui__error("Failed to mmap with %d (%s)\n", | 978 | ui__error("Failed to mmap with %d (%s)\n", |
1000 | errno, strerror(errno)); | 979 | errno, strerror(errno)); |
1001 | goto out_err; | 980 | goto out_err; |
@@ -1015,7 +994,7 @@ static int perf_top__setup_sample_type(struct perf_top *top) | |||
1015 | ui__error("Selected -g but \"sym\" not present in --sort/-s."); | 994 | ui__error("Selected -g but \"sym\" not present in --sort/-s."); |
1016 | return -EINVAL; | 995 | return -EINVAL; |
1017 | } | 996 | } |
1018 | } else if (!top->dont_use_callchains && callchain_param.mode != CHAIN_NONE) { | 997 | } else if (callchain_param.mode != CHAIN_NONE) { |
1019 | if (callchain_register_param(&callchain_param) < 0) { | 998 | if (callchain_register_param(&callchain_param) < 0) { |
1020 | ui__error("Can't register callchain params.\n"); | 999 | ui__error("Can't register callchain params.\n"); |
1021 | return -EINVAL; | 1000 | return -EINVAL; |
@@ -1027,6 +1006,7 @@ static int perf_top__setup_sample_type(struct perf_top *top) | |||
1027 | 1006 | ||
1028 | static int __cmd_top(struct perf_top *top) | 1007 | static int __cmd_top(struct perf_top *top) |
1029 | { | 1008 | { |
1009 | struct perf_record_opts *opts = &top->record_opts; | ||
1030 | pthread_t thread; | 1010 | pthread_t thread; |
1031 | int ret; | 1011 | int ret; |
1032 | /* | 1012 | /* |
@@ -1041,7 +1021,7 @@ static int __cmd_top(struct perf_top *top) | |||
1041 | if (ret) | 1021 | if (ret) |
1042 | goto out_delete; | 1022 | goto out_delete; |
1043 | 1023 | ||
1044 | if (perf_target__has_task(&top->target)) | 1024 | if (perf_target__has_task(&opts->target)) |
1045 | perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, | 1025 | perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, |
1046 | perf_event__process, | 1026 | perf_event__process, |
1047 | &top->session->host_machine); | 1027 | &top->session->host_machine); |
@@ -1052,6 +1032,17 @@ static int __cmd_top(struct perf_top *top) | |||
1052 | top->session->evlist = top->evlist; | 1032 | top->session->evlist = top->evlist; |
1053 | perf_session__set_id_hdr_size(top->session); | 1033 | perf_session__set_id_hdr_size(top->session); |
1054 | 1034 | ||
1035 | /* | ||
1036 | * When perf is starting the traced process, all the events (apart from | ||
1037 | * group members) have enable_on_exec=1 set, so don't spoil it by | ||
1038 | * prematurely enabling them. | ||
1039 | * | ||
1040 | * XXX 'top' still doesn't start workloads like record, trace, but should, | ||
1041 | * so leave the check here. | ||
1042 | */ | ||
1043 | if (!perf_target__none(&opts->target)) | ||
1044 | perf_evlist__enable(top->evlist); | ||
1045 | |||
1055 | /* Wait for a minimal set of events before starting the snapshot */ | 1046 | /* Wait for a minimal set of events before starting the snapshot */ |
1056 | poll(top->evlist->pollfd, top->evlist->nr_fds, 100); | 1047 | poll(top->evlist->pollfd, top->evlist->nr_fds, 100); |
1057 | 1048 | ||
@@ -1092,116 +1083,56 @@ out_delete: | |||
1092 | static int | 1083 | static int |
1093 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) | 1084 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) |
1094 | { | 1085 | { |
1095 | struct perf_top *top = (struct perf_top *)opt->value; | ||
1096 | char *tok, *tok2; | ||
1097 | char *endptr; | ||
1098 | |||
1099 | /* | 1086 | /* |
1100 | * --no-call-graph | 1087 | * --no-call-graph |
1101 | */ | 1088 | */ |
1102 | if (unset) { | 1089 | if (unset) |
1103 | top->dont_use_callchains = true; | ||
1104 | return 0; | 1090 | return 0; |
1105 | } | ||
1106 | 1091 | ||
1107 | symbol_conf.use_callchain = true; | 1092 | symbol_conf.use_callchain = true; |
1108 | 1093 | ||
1109 | if (!arg) | 1094 | return record_parse_callchain_opt(opt, arg, unset); |
1110 | return 0; | ||
1111 | |||
1112 | tok = strtok((char *)arg, ","); | ||
1113 | if (!tok) | ||
1114 | return -1; | ||
1115 | |||
1116 | /* get the output mode */ | ||
1117 | if (!strncmp(tok, "graph", strlen(arg))) | ||
1118 | callchain_param.mode = CHAIN_GRAPH_ABS; | ||
1119 | |||
1120 | else if (!strncmp(tok, "flat", strlen(arg))) | ||
1121 | callchain_param.mode = CHAIN_FLAT; | ||
1122 | |||
1123 | else if (!strncmp(tok, "fractal", strlen(arg))) | ||
1124 | callchain_param.mode = CHAIN_GRAPH_REL; | ||
1125 | |||
1126 | else if (!strncmp(tok, "none", strlen(arg))) { | ||
1127 | callchain_param.mode = CHAIN_NONE; | ||
1128 | symbol_conf.use_callchain = false; | ||
1129 | |||
1130 | return 0; | ||
1131 | } else | ||
1132 | return -1; | ||
1133 | |||
1134 | /* get the min percentage */ | ||
1135 | tok = strtok(NULL, ","); | ||
1136 | if (!tok) | ||
1137 | goto setup; | ||
1138 | |||
1139 | callchain_param.min_percent = strtod(tok, &endptr); | ||
1140 | if (tok == endptr) | ||
1141 | return -1; | ||
1142 | |||
1143 | /* get the print limit */ | ||
1144 | tok2 = strtok(NULL, ","); | ||
1145 | if (!tok2) | ||
1146 | goto setup; | ||
1147 | |||
1148 | if (tok2[0] != 'c') { | ||
1149 | callchain_param.print_limit = strtod(tok2, &endptr); | ||
1150 | tok2 = strtok(NULL, ","); | ||
1151 | if (!tok2) | ||
1152 | goto setup; | ||
1153 | } | ||
1154 | |||
1155 | /* get the call chain order */ | ||
1156 | if (!strcmp(tok2, "caller")) | ||
1157 | callchain_param.order = ORDER_CALLER; | ||
1158 | else if (!strcmp(tok2, "callee")) | ||
1159 | callchain_param.order = ORDER_CALLEE; | ||
1160 | else | ||
1161 | return -1; | ||
1162 | setup: | ||
1163 | if (callchain_register_param(&callchain_param) < 0) { | ||
1164 | fprintf(stderr, "Can't register callchain params\n"); | ||
1165 | return -1; | ||
1166 | } | ||
1167 | return 0; | ||
1168 | } | 1095 | } |
1169 | 1096 | ||
1170 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | 1097 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) |
1171 | { | 1098 | { |
1172 | struct perf_evsel *pos; | ||
1173 | int status; | 1099 | int status; |
1174 | char errbuf[BUFSIZ]; | 1100 | char errbuf[BUFSIZ]; |
1175 | struct perf_top top = { | 1101 | struct perf_top top = { |
1176 | .count_filter = 5, | 1102 | .count_filter = 5, |
1177 | .delay_secs = 2, | 1103 | .delay_secs = 2, |
1178 | .freq = 4000, /* 4 KHz */ | 1104 | .record_opts = { |
1179 | .mmap_pages = 128, | 1105 | .mmap_pages = UINT_MAX, |
1180 | .sym_pcnt_filter = 5, | 1106 | .user_freq = UINT_MAX, |
1181 | .target = { | 1107 | .user_interval = ULLONG_MAX, |
1182 | .uses_mmap = true, | 1108 | .freq = 4000, /* 4 KHz */ |
1109 | .target = { | ||
1110 | .uses_mmap = true, | ||
1111 | }, | ||
1183 | }, | 1112 | }, |
1113 | .sym_pcnt_filter = 5, | ||
1184 | }; | 1114 | }; |
1185 | char callchain_default_opt[] = "fractal,0.5,callee"; | 1115 | struct perf_record_opts *opts = &top.record_opts; |
1116 | struct perf_target *target = &opts->target; | ||
1186 | const struct option options[] = { | 1117 | const struct option options[] = { |
1187 | OPT_CALLBACK('e', "event", &top.evlist, "event", | 1118 | OPT_CALLBACK('e', "event", &top.evlist, "event", |
1188 | "event selector. use 'perf list' to list available events", | 1119 | "event selector. use 'perf list' to list available events", |
1189 | parse_events_option), | 1120 | parse_events_option), |
1190 | OPT_INTEGER('c', "count", &top.default_interval, | 1121 | OPT_U64('c', "count", &opts->user_interval, "event period to sample"), |
1191 | "event period to sample"), | 1122 | OPT_STRING('p', "pid", &target->pid, "pid", |
1192 | OPT_STRING('p', "pid", &top.target.pid, "pid", | ||
1193 | "profile events on existing process id"), | 1123 | "profile events on existing process id"), |
1194 | OPT_STRING('t', "tid", &top.target.tid, "tid", | 1124 | OPT_STRING('t', "tid", &target->tid, "tid", |
1195 | "profile events on existing thread id"), | 1125 | "profile events on existing thread id"), |
1196 | OPT_BOOLEAN('a', "all-cpus", &top.target.system_wide, | 1126 | OPT_BOOLEAN('a', "all-cpus", &target->system_wide, |
1197 | "system-wide collection from all CPUs"), | 1127 | "system-wide collection from all CPUs"), |
1198 | OPT_STRING('C', "cpu", &top.target.cpu_list, "cpu", | 1128 | OPT_STRING('C', "cpu", &target->cpu_list, "cpu", |
1199 | "list of cpus to monitor"), | 1129 | "list of cpus to monitor"), |
1200 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, | 1130 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, |
1201 | "file", "vmlinux pathname"), | 1131 | "file", "vmlinux pathname"), |
1202 | OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols, | 1132 | OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols, |
1203 | "hide kernel symbols"), | 1133 | "hide kernel symbols"), |
1204 | OPT_UINTEGER('m', "mmap-pages", &top.mmap_pages, "number of mmap data pages"), | 1134 | OPT_UINTEGER('m', "mmap-pages", &opts->mmap_pages, |
1135 | "number of mmap data pages"), | ||
1205 | OPT_INTEGER('r', "realtime", &top.realtime_prio, | 1136 | OPT_INTEGER('r', "realtime", &top.realtime_prio, |
1206 | "collect data with this RT SCHED_FIFO priority"), | 1137 | "collect data with this RT SCHED_FIFO priority"), |
1207 | OPT_INTEGER('d', "delay", &top.delay_secs, | 1138 | OPT_INTEGER('d', "delay", &top.delay_secs, |
@@ -1210,16 +1141,14 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1210 | "dump the symbol table used for profiling"), | 1141 | "dump the symbol table used for profiling"), |
1211 | OPT_INTEGER('f', "count-filter", &top.count_filter, | 1142 | OPT_INTEGER('f', "count-filter", &top.count_filter, |
1212 | "only display functions with more events than this"), | 1143 | "only display functions with more events than this"), |
1213 | OPT_BOOLEAN('g', "group", &top.group, | 1144 | OPT_BOOLEAN('g', "group", &opts->group, |
1214 | "put the counters into a counter group"), | 1145 | "put the counters into a counter group"), |
1215 | OPT_BOOLEAN('i', "inherit", &top.inherit, | 1146 | OPT_BOOLEAN('i', "no-inherit", &opts->no_inherit, |
1216 | "child tasks inherit counters"), | 1147 | "child tasks do not inherit counters"), |
1217 | OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name", | 1148 | OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name", |
1218 | "symbol to annotate"), | 1149 | "symbol to annotate"), |
1219 | OPT_BOOLEAN('z', "zero", &top.zero, | 1150 | OPT_BOOLEAN('z', "zero", &top.zero, "zero history across updates"), |
1220 | "zero history across updates"), | 1151 | OPT_UINTEGER('F', "freq", &opts->user_freq, "profile at this frequency"), |
1221 | OPT_INTEGER('F', "freq", &top.freq, | ||
1222 | "profile at this frequency"), | ||
1223 | OPT_INTEGER('E', "entries", &top.print_entries, | 1152 | OPT_INTEGER('E', "entries", &top.print_entries, |
1224 | "display this many functions"), | 1153 | "display this many functions"), |
1225 | OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols, | 1154 | OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols, |
@@ -1232,10 +1161,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1232 | "sort by key(s): pid, comm, dso, symbol, parent"), | 1161 | "sort by key(s): pid, comm, dso, symbol, parent"), |
1233 | OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, | 1162 | OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, |
1234 | "Show a column with the number of samples"), | 1163 | "Show a column with the number of samples"), |
1235 | OPT_CALLBACK_DEFAULT('G', "call-graph", &top, "output_type,min_percent, call_order", | 1164 | OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts, |
1236 | "Display callchains using output_type (graph, flat, fractal, or none), min percent threshold and callchain order. " | 1165 | "mode[,dump_size]", record_callchain_help, |
1237 | "Default: fractal,0.5,callee", &parse_callchain_opt, | 1166 | &parse_callchain_opt, "fp"), |
1238 | callchain_default_opt), | ||
1239 | OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, | 1167 | OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, |
1240 | "Show a column with the sum of periods"), | 1168 | "Show a column with the sum of periods"), |
1241 | OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", | 1169 | OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", |
@@ -1250,7 +1178,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1250 | "Display raw encoding of assembly instructions (default)"), | 1178 | "Display raw encoding of assembly instructions (default)"), |
1251 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", | 1179 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", |
1252 | "Specify disassembler style (e.g. -M intel for intel syntax)"), | 1180 | "Specify disassembler style (e.g. -M intel for intel syntax)"), |
1253 | OPT_STRING('u', "uid", &top.target.uid_str, "user", "user to profile"), | 1181 | OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), |
1254 | OPT_END() | 1182 | OPT_END() |
1255 | }; | 1183 | }; |
1256 | const char * const top_usage[] = { | 1184 | const char * const top_usage[] = { |
@@ -1280,27 +1208,27 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1280 | 1208 | ||
1281 | setup_browser(false); | 1209 | setup_browser(false); |
1282 | 1210 | ||
1283 | status = perf_target__validate(&top.target); | 1211 | status = perf_target__validate(target); |
1284 | if (status) { | 1212 | if (status) { |
1285 | perf_target__strerror(&top.target, status, errbuf, BUFSIZ); | 1213 | perf_target__strerror(target, status, errbuf, BUFSIZ); |
1286 | ui__warning("%s", errbuf); | 1214 | ui__warning("%s", errbuf); |
1287 | } | 1215 | } |
1288 | 1216 | ||
1289 | status = perf_target__parse_uid(&top.target); | 1217 | status = perf_target__parse_uid(target); |
1290 | if (status) { | 1218 | if (status) { |
1291 | int saved_errno = errno; | 1219 | int saved_errno = errno; |
1292 | 1220 | ||
1293 | perf_target__strerror(&top.target, status, errbuf, BUFSIZ); | 1221 | perf_target__strerror(target, status, errbuf, BUFSIZ); |
1294 | ui__error("%s", errbuf); | 1222 | ui__error("%s", errbuf); |
1295 | 1223 | ||
1296 | status = -saved_errno; | 1224 | status = -saved_errno; |
1297 | goto out_delete_evlist; | 1225 | goto out_delete_evlist; |
1298 | } | 1226 | } |
1299 | 1227 | ||
1300 | if (perf_target__none(&top.target)) | 1228 | if (perf_target__none(target)) |
1301 | top.target.system_wide = true; | 1229 | target->system_wide = true; |
1302 | 1230 | ||
1303 | if (perf_evlist__create_maps(top.evlist, &top.target) < 0) | 1231 | if (perf_evlist__create_maps(top.evlist, target) < 0) |
1304 | usage_with_options(top_usage, options); | 1232 | usage_with_options(top_usage, options); |
1305 | 1233 | ||
1306 | if (!top.evlist->nr_entries && | 1234 | if (!top.evlist->nr_entries && |
@@ -1314,24 +1242,22 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1314 | if (top.delay_secs < 1) | 1242 | if (top.delay_secs < 1) |
1315 | top.delay_secs = 1; | 1243 | top.delay_secs = 1; |
1316 | 1244 | ||
1245 | if (opts->user_interval != ULLONG_MAX) | ||
1246 | opts->default_interval = opts->user_interval; | ||
1247 | if (opts->user_freq != UINT_MAX) | ||
1248 | opts->freq = opts->user_freq; | ||
1249 | |||
1317 | /* | 1250 | /* |
1318 | * User specified count overrides default frequency. | 1251 | * User specified count overrides default frequency. |
1319 | */ | 1252 | */ |
1320 | if (top.default_interval) | 1253 | if (opts->default_interval) |
1321 | top.freq = 0; | 1254 | opts->freq = 0; |
1322 | else if (top.freq) { | 1255 | else if (opts->freq) { |
1323 | top.default_interval = top.freq; | 1256 | opts->default_interval = opts->freq; |
1324 | } else { | 1257 | } else { |
1325 | ui__error("frequency and count are zero, aborting\n"); | 1258 | ui__error("frequency and count are zero, aborting\n"); |
1326 | exit(EXIT_FAILURE); | 1259 | status = -EINVAL; |
1327 | } | 1260 | goto out_delete_evlist; |
1328 | |||
1329 | list_for_each_entry(pos, &top.evlist->entries, node) { | ||
1330 | /* | ||
1331 | * Fill in the ones not specifically initialized via -c: | ||
1332 | */ | ||
1333 | if (!pos->attr.sample_period) | ||
1334 | pos->attr.sample_period = top.default_interval; | ||
1335 | } | 1261 | } |
1336 | 1262 | ||
1337 | top.sym_evsel = perf_evlist__first(top.evlist); | 1263 | top.sym_evsel = perf_evlist__first(top.evlist); |
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 884dde9b9bc1..54d37a4753c5 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c | |||
@@ -26,6 +26,8 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | |||
26 | float samples_per_sec = top->samples / top->delay_secs; | 26 | float samples_per_sec = top->samples / top->delay_secs; |
27 | float ksamples_per_sec = top->kernel_samples / top->delay_secs; | 27 | float ksamples_per_sec = top->kernel_samples / top->delay_secs; |
28 | float esamples_percent = (100.0 * top->exact_samples) / top->samples; | 28 | float esamples_percent = (100.0 * top->exact_samples) / top->samples; |
29 | struct perf_record_opts *opts = &top->record_opts; | ||
30 | struct perf_target *target = &opts->target; | ||
29 | size_t ret = 0; | 31 | size_t ret = 0; |
30 | 32 | ||
31 | if (!perf_guest) { | 33 | if (!perf_guest) { |
@@ -61,31 +63,31 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | |||
61 | struct perf_evsel *first = perf_evlist__first(top->evlist); | 63 | struct perf_evsel *first = perf_evlist__first(top->evlist); |
62 | ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", | 64 | ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", |
63 | (uint64_t)first->attr.sample_period, | 65 | (uint64_t)first->attr.sample_period, |
64 | top->freq ? "Hz" : ""); | 66 | opts->freq ? "Hz" : ""); |
65 | } | 67 | } |
66 | 68 | ||
67 | ret += SNPRINTF(bf + ret, size - ret, "%s", perf_evsel__name(top->sym_evsel)); | 69 | ret += SNPRINTF(bf + ret, size - ret, "%s", perf_evsel__name(top->sym_evsel)); |
68 | 70 | ||
69 | ret += SNPRINTF(bf + ret, size - ret, "], "); | 71 | ret += SNPRINTF(bf + ret, size - ret, "], "); |
70 | 72 | ||
71 | if (top->target.pid) | 73 | if (target->pid) |
72 | ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s", | 74 | ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s", |
73 | top->target.pid); | 75 | target->pid); |
74 | else if (top->target.tid) | 76 | else if (target->tid) |
75 | ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s", | 77 | ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s", |
76 | top->target.tid); | 78 | target->tid); |
77 | else if (top->target.uid_str != NULL) | 79 | else if (target->uid_str != NULL) |
78 | ret += SNPRINTF(bf + ret, size - ret, " (uid: %s", | 80 | ret += SNPRINTF(bf + ret, size - ret, " (uid: %s", |
79 | top->target.uid_str); | 81 | target->uid_str); |
80 | else | 82 | else |
81 | ret += SNPRINTF(bf + ret, size - ret, " (all"); | 83 | ret += SNPRINTF(bf + ret, size - ret, " (all"); |
82 | 84 | ||
83 | if (top->target.cpu_list) | 85 | if (target->cpu_list) |
84 | ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", | 86 | ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", |
85 | top->evlist->cpus->nr > 1 ? "s" : "", | 87 | top->evlist->cpus->nr > 1 ? "s" : "", |
86 | top->target.cpu_list); | 88 | target->cpu_list); |
87 | else { | 89 | else { |
88 | if (top->target.tid) | 90 | if (target->tid) |
89 | ret += SNPRINTF(bf + ret, size - ret, ")"); | 91 | ret += SNPRINTF(bf + ret, size - ret, ")"); |
90 | else | 92 | else |
91 | ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", | 93 | ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", |
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 86ff1b15059b..927c229c2d9a 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
@@ -14,7 +14,7 @@ struct perf_session; | |||
14 | struct perf_top { | 14 | struct perf_top { |
15 | struct perf_tool tool; | 15 | struct perf_tool tool; |
16 | struct perf_evlist *evlist; | 16 | struct perf_evlist *evlist; |
17 | struct perf_target target; | 17 | struct perf_record_opts record_opts; |
18 | /* | 18 | /* |
19 | * Symbols will be added here in perf_event__process_sample and will | 19 | * Symbols will be added here in perf_event__process_sample and will |
20 | * get out after decayed. | 20 | * get out after decayed. |
@@ -24,15 +24,11 @@ struct perf_top { | |||
24 | u64 exact_samples; | 24 | u64 exact_samples; |
25 | u64 guest_us_samples, guest_kernel_samples; | 25 | u64 guest_us_samples, guest_kernel_samples; |
26 | int print_entries, count_filter, delay_secs; | 26 | int print_entries, count_filter, delay_secs; |
27 | int freq; | ||
28 | bool hide_kernel_symbols, hide_user_symbols, zero; | 27 | bool hide_kernel_symbols, hide_user_symbols, zero; |
29 | bool use_tui, use_stdio; | 28 | bool use_tui, use_stdio; |
30 | bool sort_has_symbols; | 29 | bool sort_has_symbols; |
31 | bool dont_use_callchains; | ||
32 | bool kptr_restrict_warned; | 30 | bool kptr_restrict_warned; |
33 | bool vmlinux_warned; | 31 | bool vmlinux_warned; |
34 | bool inherit; | ||
35 | bool group; | ||
36 | bool sample_id_all_missing; | 32 | bool sample_id_all_missing; |
37 | bool exclude_guest_missing; | 33 | bool exclude_guest_missing; |
38 | bool dump_symtab; | 34 | bool dump_symtab; |
@@ -40,8 +36,6 @@ struct perf_top { | |||
40 | struct perf_evsel *sym_evsel; | 36 | struct perf_evsel *sym_evsel; |
41 | struct perf_session *session; | 37 | struct perf_session *session; |
42 | struct winsize winsize; | 38 | struct winsize winsize; |
43 | unsigned int mmap_pages; | ||
44 | int default_interval; | ||
45 | int realtime_prio; | 39 | int realtime_prio; |
46 | int sym_pcnt_filter; | 40 | int sym_pcnt_filter; |
47 | const char *sym_filter; | 41 | const char *sym_filter; |