aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c45
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
68void get_term_dimensions(struct winsize *ws) 67void 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
545static void *display_thread_tui(void *arg) 544static 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;
863retry_sample_id: 878retry_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;
865try_again: 880try_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
1301out_delete_evlist:
1283 perf_evlist__delete(top.evlist); 1302 perf_evlist__delete(top.evlist);
1284 1303
1285 return status; 1304 return status;