diff options
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ecff31257eb..e3c63aef8ef 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -64,7 +64,6 @@ | |||
64 | #include <linux/unistd.h> | 64 | #include <linux/unistd.h> |
65 | #include <linux/types.h> | 65 | #include <linux/types.h> |
66 | 66 | ||
67 | |||
68 | void get_term_dimensions(struct winsize *ws) | 67 | void get_term_dimensions(struct winsize *ws) |
69 | { | 68 | { |
70 | char *s = getenv("LINES"); | 69 | char *s = getenv("LINES"); |
@@ -544,10 +543,20 @@ static void perf_top__sort_new_samples(void *arg) | |||
544 | 543 | ||
545 | static void *display_thread_tui(void *arg) | 544 | static void *display_thread_tui(void *arg) |
546 | { | 545 | { |
546 | struct perf_evsel *pos; | ||
547 | struct perf_top *top = arg; | 547 | struct perf_top *top = arg; |
548 | const char *help = "For a higher level overview, try: perf top --sort comm,dso"; | 548 | const char *help = "For a higher level overview, try: perf top --sort comm,dso"; |
549 | 549 | ||
550 | perf_top__sort_new_samples(top); | 550 | perf_top__sort_new_samples(top); |
551 | |||
552 | /* | ||
553 | * Initialize the uid_filter_str, in the future the TUI will allow | ||
554 | * Zooming in/out UIDs. For now juse use whatever the user passed | ||
555 | * via --uid. | ||
556 | */ | ||
557 | list_for_each_entry(pos, &top->evlist->entries, node) | ||
558 | pos->hists.uid_filter_str = top->uid_str; | ||
559 | |||
551 | perf_evlist__tui_browse_hists(top->evlist, help, | 560 | perf_evlist__tui_browse_hists(top->evlist, help, |
552 | perf_top__sort_new_samples, | 561 | perf_top__sort_new_samples, |
553 | top, top->delay_secs); | 562 | top, top->delay_secs); |
@@ -668,6 +677,12 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
668 | return; | 677 | return; |
669 | } | 678 | } |
670 | 679 | ||
680 | if (!machine) { | ||
681 | pr_err("%u unprocessable samples recorded.", | ||
682 | top->session->hists.stats.nr_unprocessable_samples++); | ||
683 | return; | ||
684 | } | ||
685 | |||
671 | if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) | 686 | if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) |
672 | top->exact_samples++; | 687 | top->exact_samples++; |
673 | 688 | ||
@@ -861,7 +876,7 @@ fallback_missing_features: | |||
861 | if (top->exclude_guest_missing) | 876 | if (top->exclude_guest_missing) |
862 | attr->exclude_guest = attr->exclude_host = 0; | 877 | attr->exclude_guest = attr->exclude_host = 0; |
863 | retry_sample_id: | 878 | retry_sample_id: |
864 | attr->sample_id_all = top->sample_id_all_avail ? 1 : 0; | 879 | attr->sample_id_all = top->sample_id_all_missing ? 0 : 1; |
865 | try_again: | 880 | try_again: |
866 | if (perf_evsel__open(counter, top->evlist->cpus, | 881 | if (perf_evsel__open(counter, top->evlist->cpus, |
867 | top->evlist->threads, top->group, | 882 | top->evlist->threads, top->group, |
@@ -878,11 +893,11 @@ try_again: | |||
878 | "guest or host samples.\n"); | 893 | "guest or host samples.\n"); |
879 | top->exclude_guest_missing = true; | 894 | top->exclude_guest_missing = true; |
880 | goto fallback_missing_features; | 895 | goto fallback_missing_features; |
881 | } else if (top->sample_id_all_avail) { | 896 | } else if (!top->sample_id_all_missing) { |
882 | /* | 897 | /* |
883 | * Old kernel, no attr->sample_id_type_all field | 898 | * Old kernel, no attr->sample_id_type_all field |
884 | */ | 899 | */ |
885 | top->sample_id_all_avail = false; | 900 | top->sample_id_all_missing = true; |
886 | goto retry_sample_id; | 901 | goto retry_sample_id; |
887 | } | 902 | } |
888 | } | 903 | } |
@@ -967,7 +982,7 @@ static int __cmd_top(struct perf_top *top) | |||
967 | if (ret) | 982 | if (ret) |
968 | goto out_delete; | 983 | goto out_delete; |
969 | 984 | ||
970 | if (top->target_tid != -1) | 985 | if (top->target_tid || top->uid != UINT_MAX) |
971 | perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, | 986 | perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, |
972 | perf_event__process, | 987 | perf_event__process, |
973 | &top->session->host_machine); | 988 | &top->session->host_machine); |
@@ -1105,10 +1120,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1105 | struct perf_top top = { | 1120 | struct perf_top top = { |
1106 | .count_filter = 5, | 1121 | .count_filter = 5, |
1107 | .delay_secs = 2, | 1122 | .delay_secs = 2, |
1108 | .target_pid = -1, | 1123 | .uid = UINT_MAX, |
1109 | .target_tid = -1, | ||
1110 | .freq = 1000, /* 1 KHz */ | 1124 | .freq = 1000, /* 1 KHz */ |
1111 | .sample_id_all_avail = true, | ||
1112 | .mmap_pages = 128, | 1125 | .mmap_pages = 128, |
1113 | .sym_pcnt_filter = 5, | 1126 | .sym_pcnt_filter = 5, |
1114 | }; | 1127 | }; |
@@ -1119,9 +1132,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1119 | parse_events_option), | 1132 | parse_events_option), |
1120 | OPT_INTEGER('c', "count", &top.default_interval, | 1133 | OPT_INTEGER('c', "count", &top.default_interval, |
1121 | "event period to sample"), | 1134 | "event period to sample"), |
1122 | OPT_INTEGER('p', "pid", &top.target_pid, | 1135 | OPT_STRING('p', "pid", &top.target_pid, "pid", |
1123 | "profile events on existing process id"), | 1136 | "profile events on existing process id"), |
1124 | OPT_INTEGER('t', "tid", &top.target_tid, | 1137 | OPT_STRING('t', "tid", &top.target_tid, "tid", |
1125 | "profile events on existing thread id"), | 1138 | "profile events on existing thread id"), |
1126 | OPT_BOOLEAN('a', "all-cpus", &top.system_wide, | 1139 | OPT_BOOLEAN('a', "all-cpus", &top.system_wide, |
1127 | "system-wide collection from all CPUs"), | 1140 | "system-wide collection from all CPUs"), |
@@ -1180,6 +1193,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1180 | "Display raw encoding of assembly instructions (default)"), | 1193 | "Display raw encoding of assembly instructions (default)"), |
1181 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", | 1194 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", |
1182 | "Specify disassembler style (e.g. -M intel for intel syntax)"), | 1195 | "Specify disassembler style (e.g. -M intel for intel syntax)"), |
1196 | OPT_STRING('u', "uid", &top.uid_str, "user", "user to profile"), | ||
1183 | OPT_END() | 1197 | OPT_END() |
1184 | }; | 1198 | }; |
1185 | 1199 | ||
@@ -1205,18 +1219,22 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1205 | 1219 | ||
1206 | setup_browser(false); | 1220 | setup_browser(false); |
1207 | 1221 | ||
1222 | top.uid = parse_target_uid(top.uid_str, top.target_tid, top.target_pid); | ||
1223 | if (top.uid_str != NULL && top.uid == UINT_MAX - 1) | ||
1224 | goto out_delete_evlist; | ||
1225 | |||
1208 | /* CPU and PID are mutually exclusive */ | 1226 | /* CPU and PID are mutually exclusive */ |
1209 | if (top.target_tid > 0 && top.cpu_list) { | 1227 | if (top.target_tid && top.cpu_list) { |
1210 | printf("WARNING: PID switch overriding CPU\n"); | 1228 | printf("WARNING: PID switch overriding CPU\n"); |
1211 | sleep(1); | 1229 | sleep(1); |
1212 | top.cpu_list = NULL; | 1230 | top.cpu_list = NULL; |
1213 | } | 1231 | } |
1214 | 1232 | ||
1215 | if (top.target_pid != -1) | 1233 | if (top.target_pid) |
1216 | top.target_tid = top.target_pid; | 1234 | top.target_tid = top.target_pid; |
1217 | 1235 | ||
1218 | if (perf_evlist__create_maps(top.evlist, top.target_pid, | 1236 | if (perf_evlist__create_maps(top.evlist, top.target_pid, |
1219 | top.target_tid, top.cpu_list) < 0) | 1237 | top.target_tid, top.uid, top.cpu_list) < 0) |
1220 | usage_with_options(top_usage, options); | 1238 | usage_with_options(top_usage, options); |
1221 | 1239 | ||
1222 | if (!top.evlist->nr_entries && | 1240 | if (!top.evlist->nr_entries && |
@@ -1280,6 +1298,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1280 | 1298 | ||
1281 | status = __cmd_top(&top); | 1299 | status = __cmd_top(&top); |
1282 | 1300 | ||
1301 | out_delete_evlist: | ||
1283 | perf_evlist__delete(top.evlist); | 1302 | perf_evlist__delete(top.evlist); |
1284 | 1303 | ||
1285 | return status; | 1304 | return status; |