diff options
Diffstat (limited to 'tools/perf/util')
-rwxr-xr-x | tools/perf/util/PERF-VERSION-GEN | 21 | ||||
-rw-r--r-- | tools/perf/util/dso.c | 10 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 3 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 12 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 6 | ||||
-rw-r--r-- | tools/perf/util/header.c | 17 | ||||
-rw-r--r-- | tools/perf/util/header.h | 1 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 96 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 16 | ||||
-rw-r--r-- | tools/perf/util/map.c | 1 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 4 | ||||
-rw-r--r-- | tools/perf/util/session.h | 1 | ||||
-rw-r--r-- | tools/perf/util/setup.py | 5 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 128 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 36 | ||||
-rw-r--r-- | tools/perf/util/stat.c | 2 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 1 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 4 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 1 | ||||
-rw-r--r-- | tools/perf/util/top.c | 23 | ||||
-rw-r--r-- | tools/perf/util/top.h | 2 | ||||
-rw-r--r-- | tools/perf/util/util.h | 6 | ||||
-rw-r--r-- | tools/perf/util/vdso.c | 2 |
23 files changed, 240 insertions, 158 deletions
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 055fef34b6f6..15a77b7c0e36 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN | |||
@@ -13,13 +13,22 @@ LF=' | |||
13 | # First check if there is a .git to get the version from git describe | 13 | # First check if there is a .git to get the version from git describe |
14 | # otherwise try to get the version from the kernel Makefile | 14 | # otherwise try to get the version from the kernel Makefile |
15 | # | 15 | # |
16 | if test -d ../../.git -o -f ../../.git && | 16 | CID= |
17 | VN=$(git tag 2>/dev/null | tail -1 | grep -E "v[0-9].[0-9]*") | 17 | TAG= |
18 | if test -d ../../.git -o -f ../../.git | ||
18 | then | 19 | then |
19 | VN=$(echo $VN"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD)) | 20 | TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null ) |
20 | VN=$(echo "$VN" | sed -e 's/-/./g'); | 21 | CID=$(git log -1 --abbrev=4 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID" |
21 | else | 22 | fi |
22 | VN=$(MAKEFLAGS= make -sC ../.. kernelversion) | 23 | if test -z "$TAG" |
24 | then | ||
25 | TAG=$(MAKEFLAGS= make -sC ../.. kernelversion) | ||
26 | fi | ||
27 | VN="$TAG$CID" | ||
28 | if test -n "$CID" | ||
29 | then | ||
30 | # format version string, strip trailing zero of sublevel: | ||
31 | VN=$(echo "$VN" | sed -e 's/-/./g;s/\([0-9]*[.][0-9]*\)[.]0/\1/') | ||
23 | fi | 32 | fi |
24 | 33 | ||
25 | VN=$(expr "$VN" : v*'\(.*\)') | 34 | VN=$(expr "$VN" : v*'\(.*\)') |
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 6f7d5a9d6b05..c4374f07603c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -513,10 +513,16 @@ void dsos__add(struct list_head *head, struct dso *dso) | |||
513 | list_add_tail(&dso->node, head); | 513 | list_add_tail(&dso->node, head); |
514 | } | 514 | } |
515 | 515 | ||
516 | struct dso *dsos__find(struct list_head *head, const char *name) | 516 | struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short) |
517 | { | 517 | { |
518 | struct dso *pos; | 518 | struct dso *pos; |
519 | 519 | ||
520 | if (cmp_short) { | ||
521 | list_for_each_entry(pos, head, node) | ||
522 | if (strcmp(pos->short_name, name) == 0) | ||
523 | return pos; | ||
524 | return NULL; | ||
525 | } | ||
520 | list_for_each_entry(pos, head, node) | 526 | list_for_each_entry(pos, head, node) |
521 | if (strcmp(pos->long_name, name) == 0) | 527 | if (strcmp(pos->long_name, name) == 0) |
522 | return pos; | 528 | return pos; |
@@ -525,7 +531,7 @@ struct dso *dsos__find(struct list_head *head, const char *name) | |||
525 | 531 | ||
526 | struct dso *__dsos__findnew(struct list_head *head, const char *name) | 532 | struct dso *__dsos__findnew(struct list_head *head, const char *name) |
527 | { | 533 | { |
528 | struct dso *dso = dsos__find(head, name); | 534 | struct dso *dso = dsos__find(head, name, false); |
529 | 535 | ||
530 | if (!dso) { | 536 | if (!dso) { |
531 | dso = dso__new(name); | 537 | dso = dso__new(name); |
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 450199ab51b5..d51aaf272c68 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
@@ -133,7 +133,8 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name, | |||
133 | const char *short_name, int dso_type); | 133 | const char *short_name, int dso_type); |
134 | 134 | ||
135 | void dsos__add(struct list_head *head, struct dso *dso); | 135 | void dsos__add(struct list_head *head, struct dso *dso); |
136 | struct dso *dsos__find(struct list_head *head, const char *name); | 136 | struct dso *dsos__find(struct list_head *head, const char *name, |
137 | bool cmp_short); | ||
137 | struct dso *__dsos__findnew(struct list_head *head, const char *name); | 138 | struct dso *__dsos__findnew(struct list_head *head, const char *name); |
138 | bool __dsos__read_build_ids(struct list_head *head, bool with_hits); | 139 | bool __dsos__read_build_ids(struct list_head *head, bool with_hits); |
139 | 140 | ||
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f7c727801aab..8065ce8fa9a5 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, | |||
776 | if (pipe_output) | 776 | if (pipe_output) |
777 | dup2(2, 1); | 777 | dup2(2, 1); |
778 | 778 | ||
779 | signal(SIGTERM, SIG_DFL); | ||
780 | |||
779 | close(child_ready_pipe[0]); | 781 | close(child_ready_pipe[0]); |
780 | close(go_pipe[1]); | 782 | close(go_pipe[1]); |
781 | fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); | 783 | fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); |
@@ -819,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, | |||
819 | goto out_close_pipes; | 821 | goto out_close_pipes; |
820 | } | 822 | } |
821 | 823 | ||
824 | fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); | ||
822 | evlist->workload.cork_fd = go_pipe[1]; | 825 | evlist->workload.cork_fd = go_pipe[1]; |
823 | close(child_ready_pipe[0]); | 826 | close(child_ready_pipe[0]); |
824 | return 0; | 827 | return 0; |
@@ -835,10 +838,17 @@ out_close_ready_pipe: | |||
835 | int perf_evlist__start_workload(struct perf_evlist *evlist) | 838 | int perf_evlist__start_workload(struct perf_evlist *evlist) |
836 | { | 839 | { |
837 | if (evlist->workload.cork_fd > 0) { | 840 | if (evlist->workload.cork_fd > 0) { |
841 | char bf; | ||
842 | int ret; | ||
838 | /* | 843 | /* |
839 | * Remove the cork, let it rip! | 844 | * Remove the cork, let it rip! |
840 | */ | 845 | */ |
841 | return close(evlist->workload.cork_fd); | 846 | ret = write(evlist->workload.cork_fd, &bf, 1); |
847 | if (ret < 0) | ||
848 | perror("enable to write to pipe"); | ||
849 | |||
850 | close(evlist->workload.cork_fd); | ||
851 | return ret; | ||
842 | } | 852 | } |
843 | 853 | ||
844 | return 0; | 854 | return 0; |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 07b1a3ad3e24..c9c7494506a1 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -124,7 +124,7 @@ struct event_format *event_format__new(const char *sys, const char *name) | |||
124 | bf = nbf; | 124 | bf = nbf; |
125 | } | 125 | } |
126 | 126 | ||
127 | n = read(fd, bf + size, BUFSIZ); | 127 | n = read(fd, bf + size, alloc_size - size); |
128 | if (n < 0) | 128 | if (n < 0) |
129 | goto out_free_bf; | 129 | goto out_free_bf; |
130 | size += n; | 130 | size += n; |
@@ -1170,7 +1170,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | |||
1170 | } else { | 1170 | } else { |
1171 | data->user_stack.data = (char *)array; | 1171 | data->user_stack.data = (char *)array; |
1172 | array += size / sizeof(*array); | 1172 | array += size / sizeof(*array); |
1173 | data->user_stack.size = *array; | 1173 | data->user_stack.size = *array++; |
1174 | } | 1174 | } |
1175 | } | 1175 | } |
1176 | 1176 | ||
@@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, | |||
1514 | switch (err) { | 1514 | switch (err) { |
1515 | case EPERM: | 1515 | case EPERM: |
1516 | case EACCES: | 1516 | case EACCES: |
1517 | return scnprintf(msg, size, "%s", | 1517 | return scnprintf(msg, size, |
1518 | "You may not have permission to collect %sstats.\n" | 1518 | "You may not have permission to collect %sstats.\n" |
1519 | "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" | 1519 | "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" |
1520 | " -1 - Not paranoid at all\n" | 1520 | " -1 - Not paranoid at all\n" |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 326068a593a5..a4dafbee2511 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -2303,29 +2303,18 @@ int perf_session__write_header(struct perf_session *session, | |||
2303 | struct perf_file_header f_header; | 2303 | struct perf_file_header f_header; |
2304 | struct perf_file_attr f_attr; | 2304 | struct perf_file_attr f_attr; |
2305 | struct perf_header *header = &session->header; | 2305 | struct perf_header *header = &session->header; |
2306 | struct perf_evsel *evsel, *pair = NULL; | 2306 | struct perf_evsel *evsel; |
2307 | int err; | 2307 | int err; |
2308 | 2308 | ||
2309 | lseek(fd, sizeof(f_header), SEEK_SET); | 2309 | lseek(fd, sizeof(f_header), SEEK_SET); |
2310 | 2310 | ||
2311 | if (session->evlist != evlist) | ||
2312 | pair = perf_evlist__first(session->evlist); | ||
2313 | |||
2314 | list_for_each_entry(evsel, &evlist->entries, node) { | 2311 | list_for_each_entry(evsel, &evlist->entries, node) { |
2315 | evsel->id_offset = lseek(fd, 0, SEEK_CUR); | 2312 | evsel->id_offset = lseek(fd, 0, SEEK_CUR); |
2316 | err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); | 2313 | err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); |
2317 | if (err < 0) { | 2314 | if (err < 0) { |
2318 | out_err_write: | ||
2319 | pr_debug("failed to write perf header\n"); | 2315 | pr_debug("failed to write perf header\n"); |
2320 | return err; | 2316 | return err; |
2321 | } | 2317 | } |
2322 | if (session->evlist != evlist) { | ||
2323 | err = do_write(fd, pair->id, pair->ids * sizeof(u64)); | ||
2324 | if (err < 0) | ||
2325 | goto out_err_write; | ||
2326 | evsel->ids += pair->ids; | ||
2327 | pair = perf_evsel__next(pair); | ||
2328 | } | ||
2329 | } | 2318 | } |
2330 | 2319 | ||
2331 | header->attr_offset = lseek(fd, 0, SEEK_CUR); | 2320 | header->attr_offset = lseek(fd, 0, SEEK_CUR); |
@@ -2391,7 +2380,6 @@ out_err_write: | |||
2391 | } | 2380 | } |
2392 | lseek(fd, header->data_offset + header->data_size, SEEK_SET); | 2381 | lseek(fd, header->data_offset + header->data_size, SEEK_SET); |
2393 | 2382 | ||
2394 | header->frozen = 1; | ||
2395 | return 0; | 2383 | return 0; |
2396 | } | 2384 | } |
2397 | 2385 | ||
@@ -2871,7 +2859,6 @@ int perf_session__read_header(struct perf_session *session, int fd) | |||
2871 | session->pevent)) | 2859 | session->pevent)) |
2872 | goto out_delete_evlist; | 2860 | goto out_delete_evlist; |
2873 | 2861 | ||
2874 | header->frozen = 1; | ||
2875 | return 0; | 2862 | return 0; |
2876 | out_errno: | 2863 | out_errno: |
2877 | return -errno; | 2864 | return -errno; |
@@ -2969,6 +2956,8 @@ int perf_event__process_attr(union perf_event *event, | |||
2969 | perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]); | 2956 | perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]); |
2970 | } | 2957 | } |
2971 | 2958 | ||
2959 | symbol_conf.nr_events = evlist->nr_entries; | ||
2960 | |||
2972 | return 0; | 2961 | return 0; |
2973 | } | 2962 | } |
2974 | 2963 | ||
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index c9fc55cada6d..16a3e83c584e 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h | |||
@@ -84,7 +84,6 @@ struct perf_session_env { | |||
84 | }; | 84 | }; |
85 | 85 | ||
86 | struct perf_header { | 86 | struct perf_header { |
87 | int frozen; | ||
88 | bool needs_swap; | 87 | bool needs_swap; |
89 | s64 attr_offset; | 88 | s64 attr_offset; |
90 | u64 data_offset; | 89 | u64 data_offset; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6b32721f829a..b11a6cfdb414 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
70 | int symlen; | 70 | int symlen; |
71 | u16 len; | 71 | u16 len; |
72 | 72 | ||
73 | if (h->ms.sym) | 73 | /* |
74 | hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4); | 74 | * +4 accounts for '[x] ' priv level info |
75 | else { | 75 | * +2 accounts for 0x prefix on raw addresses |
76 | * +3 accounts for ' y ' symtab origin info | ||
77 | */ | ||
78 | if (h->ms.sym) { | ||
79 | symlen = h->ms.sym->namelen + 4; | ||
80 | if (verbose) | ||
81 | symlen += BITS_PER_LONG / 4 + 2 + 3; | ||
82 | hists__new_col_len(hists, HISTC_SYMBOL, symlen); | ||
83 | } else { | ||
76 | symlen = unresolved_col_width + 4 + 2; | 84 | symlen = unresolved_col_width + 4 + 2; |
77 | hists__new_col_len(hists, HISTC_SYMBOL, symlen); | 85 | hists__new_col_len(hists, HISTC_SYMBOL, symlen); |
78 | hists__set_unres_dso_col_len(hists, HISTC_DSO); | 86 | hists__set_unres_dso_col_len(hists, HISTC_DSO); |
@@ -91,12 +99,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
91 | hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen); | 99 | hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen); |
92 | 100 | ||
93 | if (h->branch_info) { | 101 | if (h->branch_info) { |
94 | /* | ||
95 | * +4 accounts for '[x] ' priv level info | ||
96 | * +2 account of 0x prefix on raw addresses | ||
97 | */ | ||
98 | if (h->branch_info->from.sym) { | 102 | if (h->branch_info->from.sym) { |
99 | symlen = (int)h->branch_info->from.sym->namelen + 4; | 103 | symlen = (int)h->branch_info->from.sym->namelen + 4; |
104 | if (verbose) | ||
105 | symlen += BITS_PER_LONG / 4 + 2 + 3; | ||
100 | hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); | 106 | hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); |
101 | 107 | ||
102 | symlen = dso__name_len(h->branch_info->from.map->dso); | 108 | symlen = dso__name_len(h->branch_info->from.map->dso); |
@@ -109,6 +115,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
109 | 115 | ||
110 | if (h->branch_info->to.sym) { | 116 | if (h->branch_info->to.sym) { |
111 | symlen = (int)h->branch_info->to.sym->namelen + 4; | 117 | symlen = (int)h->branch_info->to.sym->namelen + 4; |
118 | if (verbose) | ||
119 | symlen += BITS_PER_LONG / 4 + 2 + 3; | ||
112 | hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); | 120 | hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); |
113 | 121 | ||
114 | symlen = dso__name_len(h->branch_info->to.map->dso); | 122 | symlen = dso__name_len(h->branch_info->to.map->dso); |
@@ -121,10 +129,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
121 | } | 129 | } |
122 | 130 | ||
123 | if (h->mem_info) { | 131 | if (h->mem_info) { |
124 | /* | ||
125 | * +4 accounts for '[x] ' priv level info | ||
126 | * +2 account of 0x prefix on raw addresses | ||
127 | */ | ||
128 | if (h->mem_info->daddr.sym) { | 132 | if (h->mem_info->daddr.sym) { |
129 | symlen = (int)h->mem_info->daddr.sym->namelen + 4 | 133 | symlen = (int)h->mem_info->daddr.sym->namelen + 4 |
130 | + unresolved_col_width + 2; | 134 | + unresolved_col_width + 2; |
@@ -236,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) | |||
236 | return he->stat.period == 0; | 240 | return he->stat.period == 0; |
237 | } | 241 | } |
238 | 242 | ||
239 | static void __hists__decay_entries(struct hists *hists, bool zap_user, | 243 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel) |
240 | bool zap_kernel, bool threaded) | ||
241 | { | 244 | { |
242 | struct rb_node *next = rb_first(&hists->entries); | 245 | struct rb_node *next = rb_first(&hists->entries); |
243 | struct hist_entry *n; | 246 | struct hist_entry *n; |
@@ -256,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user, | |||
256 | !n->used) { | 259 | !n->used) { |
257 | rb_erase(&n->rb_node, &hists->entries); | 260 | rb_erase(&n->rb_node, &hists->entries); |
258 | 261 | ||
259 | if (sort__need_collapse || threaded) | 262 | if (sort__need_collapse) |
260 | rb_erase(&n->rb_node_in, &hists->entries_collapsed); | 263 | rb_erase(&n->rb_node_in, &hists->entries_collapsed); |
261 | 264 | ||
262 | hist_entry__free(n); | 265 | hist_entry__free(n); |
@@ -265,17 +268,6 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user, | |||
265 | } | 268 | } |
266 | } | 269 | } |
267 | 270 | ||
268 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel) | ||
269 | { | ||
270 | return __hists__decay_entries(hists, zap_user, zap_kernel, false); | ||
271 | } | ||
272 | |||
273 | void hists__decay_entries_threaded(struct hists *hists, | ||
274 | bool zap_user, bool zap_kernel) | ||
275 | { | ||
276 | return __hists__decay_entries(hists, zap_user, zap_kernel, true); | ||
277 | } | ||
278 | |||
279 | /* | 271 | /* |
280 | * histogram, sorted on item, collects periods | 272 | * histogram, sorted on item, collects periods |
281 | */ | 273 | */ |
@@ -292,6 +284,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
292 | he->ms.map->referenced = true; | 284 | he->ms.map->referenced = true; |
293 | 285 | ||
294 | if (he->branch_info) { | 286 | if (he->branch_info) { |
287 | /* | ||
288 | * This branch info is (a part of) allocated from | ||
289 | * machine__resolve_bstack() and will be freed after | ||
290 | * adding new entries. So we need to save a copy. | ||
291 | */ | ||
292 | he->branch_info = malloc(sizeof(*he->branch_info)); | ||
293 | if (he->branch_info == NULL) { | ||
294 | free(he); | ||
295 | return NULL; | ||
296 | } | ||
297 | |||
298 | memcpy(he->branch_info, template->branch_info, | ||
299 | sizeof(*he->branch_info)); | ||
300 | |||
295 | if (he->branch_info->from.map) | 301 | if (he->branch_info->from.map) |
296 | he->branch_info->from.map->referenced = true; | 302 | he->branch_info->from.map->referenced = true; |
297 | if (he->branch_info->to.map) | 303 | if (he->branch_info->to.map) |
@@ -341,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
341 | struct hist_entry *he; | 347 | struct hist_entry *he; |
342 | int cmp; | 348 | int cmp; |
343 | 349 | ||
344 | pthread_mutex_lock(&hists->lock); | ||
345 | |||
346 | p = &hists->entries_in->rb_node; | 350 | p = &hists->entries_in->rb_node; |
347 | 351 | ||
348 | while (*p != NULL) { | 352 | while (*p != NULL) { |
@@ -360,6 +364,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
360 | if (!cmp) { | 364 | if (!cmp) { |
361 | he_stat__add_period(&he->stat, period, weight); | 365 | he_stat__add_period(&he->stat, period, weight); |
362 | 366 | ||
367 | /* | ||
368 | * This mem info was allocated from machine__resolve_mem | ||
369 | * and will not be used anymore. | ||
370 | */ | ||
371 | free(entry->mem_info); | ||
372 | |||
363 | /* If the map of an existing hist_entry has | 373 | /* If the map of an existing hist_entry has |
364 | * become out-of-date due to an exec() or | 374 | * become out-of-date due to an exec() or |
365 | * similar, update it. Otherwise we will | 375 | * similar, update it. Otherwise we will |
@@ -382,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
382 | 392 | ||
383 | he = hist_entry__new(entry); | 393 | he = hist_entry__new(entry); |
384 | if (!he) | 394 | if (!he) |
385 | goto out_unlock; | 395 | return NULL; |
386 | 396 | ||
387 | rb_link_node(&he->rb_node_in, parent, p); | 397 | rb_link_node(&he->rb_node_in, parent, p); |
388 | rb_insert_color(&he->rb_node_in, hists->entries_in); | 398 | rb_insert_color(&he->rb_node_in, hists->entries_in); |
389 | out: | 399 | out: |
390 | hist_entry__add_cpumode_period(he, al->cpumode, period); | 400 | hist_entry__add_cpumode_period(he, al->cpumode, period); |
391 | out_unlock: | ||
392 | pthread_mutex_unlock(&hists->lock); | ||
393 | return he; | 401 | return he; |
394 | } | 402 | } |
395 | 403 | ||
@@ -589,13 +597,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he) | |||
589 | hists__filter_entry_by_symbol(hists, he); | 597 | hists__filter_entry_by_symbol(hists, he); |
590 | } | 598 | } |
591 | 599 | ||
592 | static void __hists__collapse_resort(struct hists *hists, bool threaded) | 600 | void hists__collapse_resort(struct hists *hists) |
593 | { | 601 | { |
594 | struct rb_root *root; | 602 | struct rb_root *root; |
595 | struct rb_node *next; | 603 | struct rb_node *next; |
596 | struct hist_entry *n; | 604 | struct hist_entry *n; |
597 | 605 | ||
598 | if (!sort__need_collapse && !threaded) | 606 | if (!sort__need_collapse) |
599 | return; | 607 | return; |
600 | 608 | ||
601 | root = hists__get_rotate_entries_in(hists); | 609 | root = hists__get_rotate_entries_in(hists); |
@@ -617,16 +625,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded) | |||
617 | } | 625 | } |
618 | } | 626 | } |
619 | 627 | ||
620 | void hists__collapse_resort(struct hists *hists) | ||
621 | { | ||
622 | return __hists__collapse_resort(hists, false); | ||
623 | } | ||
624 | |||
625 | void hists__collapse_resort_threaded(struct hists *hists) | ||
626 | { | ||
627 | return __hists__collapse_resort(hists, true); | ||
628 | } | ||
629 | |||
630 | /* | 628 | /* |
631 | * reverse the map, sort on period. | 629 | * reverse the map, sort on period. |
632 | */ | 630 | */ |
@@ -713,7 +711,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, | |||
713 | rb_insert_color(&he->rb_node, entries); | 711 | rb_insert_color(&he->rb_node, entries); |
714 | } | 712 | } |
715 | 713 | ||
716 | static void __hists__output_resort(struct hists *hists, bool threaded) | 714 | void hists__output_resort(struct hists *hists) |
717 | { | 715 | { |
718 | struct rb_root *root; | 716 | struct rb_root *root; |
719 | struct rb_node *next; | 717 | struct rb_node *next; |
@@ -722,7 +720,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded) | |||
722 | 720 | ||
723 | min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); | 721 | min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); |
724 | 722 | ||
725 | if (sort__need_collapse || threaded) | 723 | if (sort__need_collapse) |
726 | root = &hists->entries_collapsed; | 724 | root = &hists->entries_collapsed; |
727 | else | 725 | else |
728 | root = hists->entries_in; | 726 | root = hists->entries_in; |
@@ -743,16 +741,6 @@ static void __hists__output_resort(struct hists *hists, bool threaded) | |||
743 | } | 741 | } |
744 | } | 742 | } |
745 | 743 | ||
746 | void hists__output_resort(struct hists *hists) | ||
747 | { | ||
748 | return __hists__output_resort(hists, false); | ||
749 | } | ||
750 | |||
751 | void hists__output_resort_threaded(struct hists *hists) | ||
752 | { | ||
753 | return __hists__output_resort(hists, true); | ||
754 | } | ||
755 | |||
756 | static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h, | 744 | static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h, |
757 | enum hist_filter filter) | 745 | enum hist_filter filter) |
758 | { | 746 | { |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 14c2fe20aa62..2d3790fd99bb 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -43,12 +43,12 @@ enum hist_column { | |||
43 | HISTC_COMM, | 43 | HISTC_COMM, |
44 | HISTC_PARENT, | 44 | HISTC_PARENT, |
45 | HISTC_CPU, | 45 | HISTC_CPU, |
46 | HISTC_SRCLINE, | ||
46 | HISTC_MISPREDICT, | 47 | HISTC_MISPREDICT, |
47 | HISTC_SYMBOL_FROM, | 48 | HISTC_SYMBOL_FROM, |
48 | HISTC_SYMBOL_TO, | 49 | HISTC_SYMBOL_TO, |
49 | HISTC_DSO_FROM, | 50 | HISTC_DSO_FROM, |
50 | HISTC_DSO_TO, | 51 | HISTC_DSO_TO, |
51 | HISTC_SRCLINE, | ||
52 | HISTC_LOCAL_WEIGHT, | 52 | HISTC_LOCAL_WEIGHT, |
53 | HISTC_GLOBAL_WEIGHT, | 53 | HISTC_GLOBAL_WEIGHT, |
54 | HISTC_MEM_DADDR_SYMBOL, | 54 | HISTC_MEM_DADDR_SYMBOL, |
@@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self, | |||
104 | u64 weight); | 104 | u64 weight); |
105 | 105 | ||
106 | void hists__output_resort(struct hists *self); | 106 | void hists__output_resort(struct hists *self); |
107 | void hists__output_resort_threaded(struct hists *hists); | ||
108 | void hists__collapse_resort(struct hists *self); | 107 | void hists__collapse_resort(struct hists *self); |
109 | void hists__collapse_resort_threaded(struct hists *hists); | ||
110 | 108 | ||
111 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); | 109 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); |
112 | void hists__decay_entries_threaded(struct hists *hists, bool zap_user, | ||
113 | bool zap_kernel); | ||
114 | void hists__output_recalc_col_len(struct hists *hists, int max_rows); | 110 | void hists__output_recalc_col_len(struct hists *hists, int max_rows); |
115 | 111 | ||
116 | void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h); | 112 | void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h); |
@@ -119,7 +115,7 @@ void events_stats__inc(struct events_stats *stats, u32 type); | |||
119 | size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); | 115 | size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); |
120 | 116 | ||
121 | size_t hists__fprintf(struct hists *self, bool show_header, int max_rows, | 117 | size_t hists__fprintf(struct hists *self, bool show_header, int max_rows, |
122 | int max_cols, FILE *fp); | 118 | int max_cols, float min_pcnt, FILE *fp); |
123 | 119 | ||
124 | int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr); | 120 | int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr); |
125 | int hist_entry__annotate(struct hist_entry *self, size_t privsize); | 121 | int hist_entry__annotate(struct hist_entry *self, size_t privsize); |
@@ -199,6 +195,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, | |||
199 | 195 | ||
200 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, | 196 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, |
201 | struct hist_browser_timer *hbt, | 197 | struct hist_browser_timer *hbt, |
198 | float min_pcnt, | ||
202 | struct perf_session_env *env); | 199 | struct perf_session_env *env); |
203 | int script_browse(const char *script_opt); | 200 | int script_browse(const char *script_opt); |
204 | #else | 201 | #else |
@@ -206,6 +203,7 @@ static inline | |||
206 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, | 203 | int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, |
207 | const char *help __maybe_unused, | 204 | const char *help __maybe_unused, |
208 | struct hist_browser_timer *hbt __maybe_unused, | 205 | struct hist_browser_timer *hbt __maybe_unused, |
206 | float min_pcnt __maybe_unused, | ||
209 | struct perf_session_env *env __maybe_unused) | 207 | struct perf_session_env *env __maybe_unused) |
210 | { | 208 | { |
211 | return 0; | 209 | return 0; |
@@ -233,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused) | |||
233 | 231 | ||
234 | #ifdef GTK2_SUPPORT | 232 | #ifdef GTK2_SUPPORT |
235 | int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, | 233 | int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, |
236 | struct hist_browser_timer *hbt __maybe_unused); | 234 | struct hist_browser_timer *hbt __maybe_unused, |
235 | float min_pcnt); | ||
237 | #else | 236 | #else |
238 | static inline | 237 | static inline |
239 | int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, | 238 | int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, |
240 | const char *help __maybe_unused, | 239 | const char *help __maybe_unused, |
241 | struct hist_browser_timer *hbt __maybe_unused) | 240 | struct hist_browser_timer *hbt __maybe_unused, |
241 | float min_pcnt __maybe_unused) | ||
242 | { | 242 | { |
243 | return 0; | 243 | return 0; |
244 | } | 244 | } |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 6fcb9de62340..8bcdf9e54089 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -21,6 +21,7 @@ const char *map_type__name[MAP__NR_TYPES] = { | |||
21 | static inline int is_anon_memory(const char *filename) | 21 | static inline int is_anon_memory(const char *filename) |
22 | { | 22 | { |
23 | return !strcmp(filename, "//anon") || | 23 | return !strcmp(filename, "//anon") || |
24 | !strcmp(filename, "/dev/zero (deleted)") || | ||
24 | !strcmp(filename, "/anon_hugepage (deleted)"); | 25 | !strcmp(filename, "/anon_hugepage (deleted)"); |
25 | } | 26 | } |
26 | 27 | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6c8bb0fb189b..995fc25db8c6 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -860,7 +860,8 @@ int parse_events_terms(struct list_head *terms, const char *str) | |||
860 | return 0; | 860 | return 0; |
861 | } | 861 | } |
862 | 862 | ||
863 | parse_events__free_terms(data.terms); | 863 | if (data.terms) |
864 | parse_events__free_terms(data.terms); | ||
864 | return ret; | 865 | return ret; |
865 | } | 866 | } |
866 | 867 | ||
@@ -1183,6 +1184,7 @@ static int new_term(struct parse_events_term **_term, int type_val, | |||
1183 | term->val.str = str; | 1184 | term->val.str = str; |
1184 | break; | 1185 | break; |
1185 | default: | 1186 | default: |
1187 | free(term); | ||
1186 | return -EINVAL; | 1188 | return -EINVAL; |
1187 | } | 1189 | } |
1188 | 1190 | ||
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 6b51d47acdba..f3b235ec7bf4 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -37,7 +37,6 @@ struct perf_session { | |||
37 | int fd; | 37 | int fd; |
38 | bool fd_pipe; | 38 | bool fd_pipe; |
39 | bool repipe; | 39 | bool repipe; |
40 | int cwdlen; | ||
41 | char *cwd; | 40 | char *cwd; |
42 | struct ordered_samples ordered_samples; | 41 | struct ordered_samples ordered_samples; |
43 | char filename[1]; | 42 | char filename[1]; |
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index 6b0ed322907e..58ea5ca6c255 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py | |||
@@ -18,8 +18,9 @@ class install_lib(_install_lib): | |||
18 | self.build_dir = build_lib | 18 | self.build_dir = build_lib |
19 | 19 | ||
20 | 20 | ||
21 | cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] | 21 | cflags = getenv('CFLAGS', '').split() |
22 | cflags += getenv('CFLAGS', '').split() | 22 | # switch off several checks (need to be at the end of cflags list) |
23 | cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] | ||
23 | 24 | ||
24 | build_lib = getenv('PYTHON_EXTBUILD_LIB') | 25 | build_lib = getenv('PYTHON_EXTBUILD_LIB') |
25 | build_tmp = getenv('PYTHON_EXTBUILD_TMP') | 26 | build_tmp = getenv('PYTHON_EXTBUILD_TMP') |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 5f52d492590c..313a5a730112 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include "sort.h" | 1 | #include "sort.h" |
2 | #include "hist.h" | 2 | #include "hist.h" |
3 | #include "symbol.h" | ||
3 | 4 | ||
4 | regex_t parent_regex; | 5 | regex_t parent_regex; |
5 | const char default_parent_pattern[] = "^sys_|^do_page_fault"; | 6 | const char default_parent_pattern[] = "^sys_|^do_page_fault"; |
@@ -9,7 +10,7 @@ const char *sort_order = default_sort_order; | |||
9 | int sort__need_collapse = 0; | 10 | int sort__need_collapse = 0; |
10 | int sort__has_parent = 0; | 11 | int sort__has_parent = 0; |
11 | int sort__has_sym = 0; | 12 | int sort__has_sym = 0; |
12 | int sort__branch_mode = -1; /* -1 = means not set */ | 13 | enum sort_mode sort__mode = SORT_MODE__NORMAL; |
13 | 14 | ||
14 | enum sort_type sort__first_dimension; | 15 | enum sort_type sort__first_dimension; |
15 | 16 | ||
@@ -194,7 +195,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, | |||
194 | if (verbose) { | 195 | if (verbose) { |
195 | char o = map ? dso__symtab_origin(map->dso) : '!'; | 196 | char o = map ? dso__symtab_origin(map->dso) : '!'; |
196 | ret += repsep_snprintf(bf, size, "%-#*llx %c ", | 197 | ret += repsep_snprintf(bf, size, "%-#*llx %c ", |
197 | BITS_PER_LONG / 4, ip, o); | 198 | BITS_PER_LONG / 4 + 2, ip, o); |
198 | } | 199 | } |
199 | 200 | ||
200 | ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); | 201 | ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); |
@@ -871,14 +872,6 @@ static struct sort_dimension common_sort_dimensions[] = { | |||
871 | DIM(SORT_PARENT, "parent", sort_parent), | 872 | DIM(SORT_PARENT, "parent", sort_parent), |
872 | DIM(SORT_CPU, "cpu", sort_cpu), | 873 | DIM(SORT_CPU, "cpu", sort_cpu), |
873 | DIM(SORT_SRCLINE, "srcline", sort_srcline), | 874 | DIM(SORT_SRCLINE, "srcline", sort_srcline), |
874 | DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), | ||
875 | DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight), | ||
876 | DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym), | ||
877 | DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso), | ||
878 | DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked), | ||
879 | DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb), | ||
880 | DIM(SORT_MEM_LVL, "mem", sort_mem_lvl), | ||
881 | DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop), | ||
882 | }; | 875 | }; |
883 | 876 | ||
884 | #undef DIM | 877 | #undef DIM |
@@ -895,6 +888,36 @@ static struct sort_dimension bstack_sort_dimensions[] = { | |||
895 | 888 | ||
896 | #undef DIM | 889 | #undef DIM |
897 | 890 | ||
891 | #define DIM(d, n, func) [d - __SORT_MEMORY_MODE] = { .name = n, .entry = &(func) } | ||
892 | |||
893 | static struct sort_dimension memory_sort_dimensions[] = { | ||
894 | DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), | ||
895 | DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight), | ||
896 | DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym), | ||
897 | DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso), | ||
898 | DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked), | ||
899 | DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb), | ||
900 | DIM(SORT_MEM_LVL, "mem", sort_mem_lvl), | ||
901 | DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop), | ||
902 | }; | ||
903 | |||
904 | #undef DIM | ||
905 | |||
906 | static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx) | ||
907 | { | ||
908 | if (sd->taken) | ||
909 | return; | ||
910 | |||
911 | if (sd->entry->se_collapse) | ||
912 | sort__need_collapse = 1; | ||
913 | |||
914 | if (list_empty(&hist_entry__sort_list)) | ||
915 | sort__first_dimension = idx; | ||
916 | |||
917 | list_add_tail(&sd->entry->list, &hist_entry__sort_list); | ||
918 | sd->taken = 1; | ||
919 | } | ||
920 | |||
898 | int sort_dimension__add(const char *tok) | 921 | int sort_dimension__add(const char *tok) |
899 | { | 922 | { |
900 | unsigned int i; | 923 | unsigned int i; |
@@ -915,25 +938,11 @@ int sort_dimension__add(const char *tok) | |||
915 | return -EINVAL; | 938 | return -EINVAL; |
916 | } | 939 | } |
917 | sort__has_parent = 1; | 940 | sort__has_parent = 1; |
918 | } else if (sd->entry == &sort_sym || | 941 | } else if (sd->entry == &sort_sym) { |
919 | sd->entry == &sort_sym_from || | ||
920 | sd->entry == &sort_sym_to || | ||
921 | sd->entry == &sort_mem_daddr_sym) { | ||
922 | sort__has_sym = 1; | 942 | sort__has_sym = 1; |
923 | } | 943 | } |
924 | 944 | ||
925 | if (sd->taken) | 945 | __sort_dimension__add(sd, i); |
926 | return 0; | ||
927 | |||
928 | if (sd->entry->se_collapse) | ||
929 | sort__need_collapse = 1; | ||
930 | |||
931 | if (list_empty(&hist_entry__sort_list)) | ||
932 | sort__first_dimension = i; | ||
933 | |||
934 | list_add_tail(&sd->entry->list, &hist_entry__sort_list); | ||
935 | sd->taken = 1; | ||
936 | |||
937 | return 0; | 946 | return 0; |
938 | } | 947 | } |
939 | 948 | ||
@@ -943,24 +952,29 @@ int sort_dimension__add(const char *tok) | |||
943 | if (strncasecmp(tok, sd->name, strlen(tok))) | 952 | if (strncasecmp(tok, sd->name, strlen(tok))) |
944 | continue; | 953 | continue; |
945 | 954 | ||
946 | if (sort__branch_mode != 1) | 955 | if (sort__mode != SORT_MODE__BRANCH) |
947 | return -EINVAL; | 956 | return -EINVAL; |
948 | 957 | ||
949 | if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) | 958 | if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) |
950 | sort__has_sym = 1; | 959 | sort__has_sym = 1; |
951 | 960 | ||
952 | if (sd->taken) | 961 | __sort_dimension__add(sd, i + __SORT_BRANCH_STACK); |
953 | return 0; | 962 | return 0; |
963 | } | ||
954 | 964 | ||
955 | if (sd->entry->se_collapse) | 965 | for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) { |
956 | sort__need_collapse = 1; | 966 | struct sort_dimension *sd = &memory_sort_dimensions[i]; |
957 | 967 | ||
958 | if (list_empty(&hist_entry__sort_list)) | 968 | if (strncasecmp(tok, sd->name, strlen(tok))) |
959 | sort__first_dimension = i + __SORT_BRANCH_STACK; | 969 | continue; |
960 | 970 | ||
961 | list_add_tail(&sd->entry->list, &hist_entry__sort_list); | 971 | if (sort__mode != SORT_MODE__MEMORY) |
962 | sd->taken = 1; | 972 | return -EINVAL; |
973 | |||
974 | if (sd->entry == &sort_mem_daddr_sym) | ||
975 | sort__has_sym = 1; | ||
963 | 976 | ||
977 | __sort_dimension__add(sd, i + __SORT_MEMORY_MODE); | ||
964 | return 0; | 978 | return 0; |
965 | } | 979 | } |
966 | 980 | ||
@@ -993,8 +1007,9 @@ int setup_sorting(void) | |||
993 | return ret; | 1007 | return ret; |
994 | } | 1008 | } |
995 | 1009 | ||
996 | void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, | 1010 | static void sort_entry__setup_elide(struct sort_entry *self, |
997 | const char *list_name, FILE *fp) | 1011 | struct strlist *list, |
1012 | const char *list_name, FILE *fp) | ||
998 | { | 1013 | { |
999 | if (list && strlist__nr_entries(list) == 1) { | 1014 | if (list && strlist__nr_entries(list) == 1) { |
1000 | if (fp != NULL) | 1015 | if (fp != NULL) |
@@ -1003,3 +1018,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, | |||
1003 | self->elide = true; | 1018 | self->elide = true; |
1004 | } | 1019 | } |
1005 | } | 1020 | } |
1021 | |||
1022 | void sort__setup_elide(FILE *output) | ||
1023 | { | ||
1024 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1025 | "dso", output); | ||
1026 | sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, | ||
1027 | "comm", output); | ||
1028 | sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, | ||
1029 | "symbol", output); | ||
1030 | |||
1031 | if (sort__mode == SORT_MODE__BRANCH) { | ||
1032 | sort_entry__setup_elide(&sort_dso_from, | ||
1033 | symbol_conf.dso_from_list, | ||
1034 | "dso_from", output); | ||
1035 | sort_entry__setup_elide(&sort_dso_to, | ||
1036 | symbol_conf.dso_to_list, | ||
1037 | "dso_to", output); | ||
1038 | sort_entry__setup_elide(&sort_sym_from, | ||
1039 | symbol_conf.sym_from_list, | ||
1040 | "sym_from", output); | ||
1041 | sort_entry__setup_elide(&sort_sym_to, | ||
1042 | symbol_conf.sym_to_list, | ||
1043 | "sym_to", output); | ||
1044 | } else if (sort__mode == SORT_MODE__MEMORY) { | ||
1045 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1046 | "symbol_daddr", output); | ||
1047 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1048 | "dso_daddr", output); | ||
1049 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1050 | "mem", output); | ||
1051 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1052 | "local_weight", output); | ||
1053 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1054 | "tlb", output); | ||
1055 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, | ||
1056 | "snoop", output); | ||
1057 | } | ||
1058 | |||
1059 | } | ||
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index f24bdf64238c..45ac84c1e037 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -32,7 +32,7 @@ extern const char default_sort_order[]; | |||
32 | extern int sort__need_collapse; | 32 | extern int sort__need_collapse; |
33 | extern int sort__has_parent; | 33 | extern int sort__has_parent; |
34 | extern int sort__has_sym; | 34 | extern int sort__has_sym; |
35 | extern int sort__branch_mode; | 35 | extern enum sort_mode sort__mode; |
36 | extern struct sort_entry sort_comm; | 36 | extern struct sort_entry sort_comm; |
37 | extern struct sort_entry sort_dso; | 37 | extern struct sort_entry sort_dso; |
38 | extern struct sort_entry sort_sym; | 38 | extern struct sort_entry sort_sym; |
@@ -117,12 +117,18 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he) | |||
117 | return NULL; | 117 | return NULL; |
118 | } | 118 | } |
119 | 119 | ||
120 | static inline void hist_entry__add_pair(struct hist_entry *he, | 120 | static inline void hist_entry__add_pair(struct hist_entry *pair, |
121 | struct hist_entry *pair) | 121 | struct hist_entry *he) |
122 | { | 122 | { |
123 | list_add_tail(&he->pairs.head, &pair->pairs.node); | 123 | list_add_tail(&pair->pairs.node, &he->pairs.head); |
124 | } | 124 | } |
125 | 125 | ||
126 | enum sort_mode { | ||
127 | SORT_MODE__NORMAL, | ||
128 | SORT_MODE__BRANCH, | ||
129 | SORT_MODE__MEMORY, | ||
130 | }; | ||
131 | |||
126 | enum sort_type { | 132 | enum sort_type { |
127 | /* common sort keys */ | 133 | /* common sort keys */ |
128 | SORT_PID, | 134 | SORT_PID, |
@@ -132,14 +138,6 @@ enum sort_type { | |||
132 | SORT_PARENT, | 138 | SORT_PARENT, |
133 | SORT_CPU, | 139 | SORT_CPU, |
134 | SORT_SRCLINE, | 140 | SORT_SRCLINE, |
135 | SORT_LOCAL_WEIGHT, | ||
136 | SORT_GLOBAL_WEIGHT, | ||
137 | SORT_MEM_DADDR_SYMBOL, | ||
138 | SORT_MEM_DADDR_DSO, | ||
139 | SORT_MEM_LOCKED, | ||
140 | SORT_MEM_TLB, | ||
141 | SORT_MEM_LVL, | ||
142 | SORT_MEM_SNOOP, | ||
143 | 141 | ||
144 | /* branch stack specific sort keys */ | 142 | /* branch stack specific sort keys */ |
145 | __SORT_BRANCH_STACK, | 143 | __SORT_BRANCH_STACK, |
@@ -148,6 +146,17 @@ enum sort_type { | |||
148 | SORT_SYM_FROM, | 146 | SORT_SYM_FROM, |
149 | SORT_SYM_TO, | 147 | SORT_SYM_TO, |
150 | SORT_MISPREDICT, | 148 | SORT_MISPREDICT, |
149 | |||
150 | /* memory mode specific sort keys */ | ||
151 | __SORT_MEMORY_MODE, | ||
152 | SORT_LOCAL_WEIGHT = __SORT_MEMORY_MODE, | ||
153 | SORT_GLOBAL_WEIGHT, | ||
154 | SORT_MEM_DADDR_SYMBOL, | ||
155 | SORT_MEM_DADDR_DSO, | ||
156 | SORT_MEM_LOCKED, | ||
157 | SORT_MEM_TLB, | ||
158 | SORT_MEM_LVL, | ||
159 | SORT_MEM_SNOOP, | ||
151 | }; | 160 | }; |
152 | 161 | ||
153 | /* | 162 | /* |
@@ -172,7 +181,6 @@ extern struct list_head hist_entry__sort_list; | |||
172 | 181 | ||
173 | int setup_sorting(void); | 182 | int setup_sorting(void); |
174 | extern int sort_dimension__add(const char *); | 183 | extern int sort_dimension__add(const char *); |
175 | void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, | 184 | void sort__setup_elide(FILE *fp); |
176 | const char *list_name, FILE *fp); | ||
177 | 185 | ||
178 | #endif /* __PERF_SORT_H */ | 186 | #endif /* __PERF_SORT_H */ |
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 23742126f47c..7c59c28afcc5 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c | |||
@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats) | |||
37 | { | 37 | { |
38 | double variance, variance_mean; | 38 | double variance, variance_mean; |
39 | 39 | ||
40 | if (!stats->n) | 40 | if (stats->n < 2) |
41 | return 0.0; | 41 | return 0.0; |
42 | 42 | ||
43 | variance = stats->M2 / (stats->n - 1); | 43 | variance = stats->M2 / (stats->n - 1); |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 8cf3b5426a9a..d5528e1cc03a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -32,7 +32,6 @@ int vmlinux_path__nr_entries; | |||
32 | char **vmlinux_path; | 32 | char **vmlinux_path; |
33 | 33 | ||
34 | struct symbol_conf symbol_conf = { | 34 | struct symbol_conf symbol_conf = { |
35 | .exclude_other = true, | ||
36 | .use_modules = true, | 35 | .use_modules = true, |
37 | .try_vmlinux_path = true, | 36 | .try_vmlinux_path = true, |
38 | .annotate_src = true, | 37 | .annotate_src = true, |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 632e40e5ceca..40399cbcca77 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid) | |||
14 | if (self != NULL) { | 14 | if (self != NULL) { |
15 | map_groups__init(&self->mg); | 15 | map_groups__init(&self->mg); |
16 | self->pid = pid; | 16 | self->pid = pid; |
17 | self->ppid = -1; | ||
17 | self->comm = malloc(32); | 18 | self->comm = malloc(32); |
18 | if (self->comm) | 19 | if (self->comm) |
19 | snprintf(self->comm, 32, ":%d", self->pid); | 20 | snprintf(self->comm, 32, ":%d", self->pid); |
@@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent) | |||
82 | for (i = 0; i < MAP__NR_TYPES; ++i) | 83 | for (i = 0; i < MAP__NR_TYPES; ++i) |
83 | if (map_groups__clone(&self->mg, &parent->mg, i) < 0) | 84 | if (map_groups__clone(&self->mg, &parent->mg, i) < 0) |
84 | return -ENOMEM; | 85 | return -ENOMEM; |
86 | |||
87 | self->ppid = parent->pid; | ||
88 | |||
85 | return 0; | 89 | return 0; |
86 | } | 90 | } |
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 5ad266403098..eeb7ac62b9e3 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
@@ -13,6 +13,7 @@ struct thread { | |||
13 | }; | 13 | }; |
14 | struct map_groups mg; | 14 | struct map_groups mg; |
15 | pid_t pid; | 15 | pid_t pid; |
16 | pid_t ppid; | ||
16 | char shortname[3]; | 17 | char shortname[3]; |
17 | bool comm_set; | 18 | bool comm_set; |
18 | char *comm; | 19 | char *comm; |
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 54d37a4753c5..f857b51b6bde 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c | |||
@@ -23,20 +23,31 @@ | |||
23 | 23 | ||
24 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | 24 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) |
25 | { | 25 | { |
26 | float samples_per_sec = top->samples / top->delay_secs; | 26 | float samples_per_sec; |
27 | float ksamples_per_sec = top->kernel_samples / top->delay_secs; | 27 | float ksamples_per_sec; |
28 | float esamples_percent = (100.0 * top->exact_samples) / top->samples; | 28 | float esamples_percent; |
29 | struct perf_record_opts *opts = &top->record_opts; | 29 | struct perf_record_opts *opts = &top->record_opts; |
30 | struct perf_target *target = &opts->target; | 30 | struct perf_target *target = &opts->target; |
31 | size_t ret = 0; | 31 | size_t ret = 0; |
32 | 32 | ||
33 | if (top->samples) { | ||
34 | samples_per_sec = top->samples / top->delay_secs; | ||
35 | ksamples_per_sec = top->kernel_samples / top->delay_secs; | ||
36 | esamples_percent = (100.0 * top->exact_samples) / top->samples; | ||
37 | } else { | ||
38 | samples_per_sec = ksamples_per_sec = esamples_percent = 0.0; | ||
39 | } | ||
40 | |||
33 | if (!perf_guest) { | 41 | if (!perf_guest) { |
42 | float ksamples_percent = 0.0; | ||
43 | |||
44 | if (samples_per_sec) | ||
45 | ksamples_percent = (100.0 * ksamples_per_sec) / | ||
46 | samples_per_sec; | ||
34 | ret = SNPRINTF(bf, size, | 47 | ret = SNPRINTF(bf, size, |
35 | " PerfTop:%8.0f irqs/sec kernel:%4.1f%%" | 48 | " PerfTop:%8.0f irqs/sec kernel:%4.1f%%" |
36 | " exact: %4.1f%% [", samples_per_sec, | 49 | " exact: %4.1f%% [", samples_per_sec, |
37 | 100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) / | 50 | ksamples_percent, esamples_percent); |
38 | samples_per_sec)), | ||
39 | esamples_percent); | ||
40 | } else { | 51 | } else { |
41 | float us_samples_per_sec = top->us_samples / top->delay_secs; | 52 | float us_samples_per_sec = top->us_samples / top->delay_secs; |
42 | float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs; | 53 | float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs; |
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 7ebf357dc9e1..df46be93d902 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
@@ -26,7 +26,6 @@ struct perf_top { | |||
26 | int print_entries, count_filter, delay_secs; | 26 | int print_entries, count_filter, delay_secs; |
27 | bool hide_kernel_symbols, hide_user_symbols, zero; | 27 | bool hide_kernel_symbols, hide_user_symbols, zero; |
28 | bool use_tui, use_stdio; | 28 | bool use_tui, use_stdio; |
29 | bool sort_has_symbols; | ||
30 | bool kptr_restrict_warned; | 29 | bool kptr_restrict_warned; |
31 | bool vmlinux_warned; | 30 | bool vmlinux_warned; |
32 | bool dump_symtab; | 31 | bool dump_symtab; |
@@ -37,6 +36,7 @@ struct perf_top { | |||
37 | int realtime_prio; | 36 | int realtime_prio; |
38 | int sym_pcnt_filter; | 37 | int sym_pcnt_filter; |
39 | const char *sym_filter; | 38 | const char *sym_filter; |
39 | float min_percent; | ||
40 | }; | 40 | }; |
41 | 41 | ||
42 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); | 42 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index a45710b70a55..2732fad03908 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -72,6 +72,7 @@ | |||
72 | #include "types.h" | 72 | #include "types.h" |
73 | #include <sys/ttydefaults.h> | 73 | #include <sys/ttydefaults.h> |
74 | #include <lk/debugfs.h> | 74 | #include <lk/debugfs.h> |
75 | #include <termios.h> | ||
75 | 76 | ||
76 | extern const char *graph_line; | 77 | extern const char *graph_line; |
77 | extern const char *graph_dotted_line; | 78 | extern const char *graph_dotted_line; |
@@ -221,8 +222,8 @@ extern unsigned char sane_ctype[256]; | |||
221 | #define isalpha(x) sane_istest(x,GIT_ALPHA) | 222 | #define isalpha(x) sane_istest(x,GIT_ALPHA) |
222 | #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) | 223 | #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) |
223 | #define isprint(x) sane_istest(x,GIT_PRINT) | 224 | #define isprint(x) sane_istest(x,GIT_PRINT) |
224 | #define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20)) | 225 | #define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20)) |
225 | #define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20)) | 226 | #define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20)) |
226 | #define tolower(x) sane_case((unsigned char)(x), 0x20) | 227 | #define tolower(x) sane_case((unsigned char)(x), 0x20) |
227 | #define toupper(x) sane_case((unsigned char)(x), 0) | 228 | #define toupper(x) sane_case((unsigned char)(x), 0) |
228 | 229 | ||
@@ -274,6 +275,5 @@ void dump_stack(void); | |||
274 | 275 | ||
275 | extern unsigned int page_size; | 276 | extern unsigned int page_size; |
276 | 277 | ||
277 | struct winsize; | ||
278 | void get_term_dimensions(struct winsize *ws); | 278 | void get_term_dimensions(struct winsize *ws); |
279 | #endif /* GIT_COMPAT_UTIL_H */ | 279 | #endif /* GIT_COMPAT_UTIL_H */ |
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index e60951fcdb12..39159822d58f 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c | |||
@@ -91,7 +91,7 @@ void vdso__exit(void) | |||
91 | 91 | ||
92 | struct dso *vdso__dso_findnew(struct list_head *head) | 92 | struct dso *vdso__dso_findnew(struct list_head *head) |
93 | { | 93 | { |
94 | struct dso *dso = dsos__find(head, VDSO__MAP_NAME); | 94 | struct dso *dso = dsos__find(head, VDSO__MAP_NAME, true); |
95 | 95 | ||
96 | if (!dso) { | 96 | if (!dso) { |
97 | char *file; | 97 | char *file; |