diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/machine.c | 21 | ||||
-rw-r--r-- | tools/perf/util/machine.h | 3 | ||||
-rw-r--r-- | tools/perf/util/session.c | 20 | ||||
-rw-r--r-- | tools/perf/util/thread-stack.c | 18 | ||||
-rw-r--r-- | tools/perf/util/thread-stack.h | 1 |
5 files changed, 58 insertions, 5 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 132e35765101..8b3b1937cb9e 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1890,6 +1890,27 @@ int machine__for_each_thread(struct machine *machine, | |||
1890 | return rc; | 1890 | return rc; |
1891 | } | 1891 | } |
1892 | 1892 | ||
1893 | int machines__for_each_thread(struct machines *machines, | ||
1894 | int (*fn)(struct thread *thread, void *p), | ||
1895 | void *priv) | ||
1896 | { | ||
1897 | struct rb_node *nd; | ||
1898 | int rc = 0; | ||
1899 | |||
1900 | rc = machine__for_each_thread(&machines->host, fn, priv); | ||
1901 | if (rc != 0) | ||
1902 | return rc; | ||
1903 | |||
1904 | for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { | ||
1905 | struct machine *machine = rb_entry(nd, struct machine, rb_node); | ||
1906 | |||
1907 | rc = machine__for_each_thread(machine, fn, priv); | ||
1908 | if (rc != 0) | ||
1909 | return rc; | ||
1910 | } | ||
1911 | return rc; | ||
1912 | } | ||
1913 | |||
1893 | int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, | 1914 | int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, |
1894 | struct target *target, struct thread_map *threads, | 1915 | struct target *target, struct thread_map *threads, |
1895 | perf_event__handler_t process, bool data_mmap) | 1916 | perf_event__handler_t process, bool data_mmap) |
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index ca267c41f28d..cea62f6fb144 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
@@ -216,6 +216,9 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); | |||
216 | int machine__for_each_thread(struct machine *machine, | 216 | int machine__for_each_thread(struct machine *machine, |
217 | int (*fn)(struct thread *thread, void *p), | 217 | int (*fn)(struct thread *thread, void *p), |
218 | void *priv); | 218 | void *priv); |
219 | int machines__for_each_thread(struct machines *machines, | ||
220 | int (*fn)(struct thread *thread, void *p), | ||
221 | void *priv); | ||
219 | 222 | ||
220 | int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, | 223 | int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, |
221 | struct target *target, struct thread_map *threads, | 224 | struct target *target, struct thread_map *threads, |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e1cd17c2afab..c371336d1eb2 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "perf_regs.h" | 16 | #include "perf_regs.h" |
17 | #include "asm/bug.h" | 17 | #include "asm/bug.h" |
18 | #include "auxtrace.h" | 18 | #include "auxtrace.h" |
19 | #include "thread-stack.h" | ||
19 | 20 | ||
20 | static int perf_session__deliver_event(struct perf_session *session, | 21 | static int perf_session__deliver_event(struct perf_session *session, |
21 | union perf_event *event, | 22 | union perf_event *event, |
@@ -1361,6 +1362,19 @@ static void perf_session__warn_about_errors(const struct perf_session *session) | |||
1361 | events_stats__auxtrace_error_warn(stats); | 1362 | events_stats__auxtrace_error_warn(stats); |
1362 | } | 1363 | } |
1363 | 1364 | ||
1365 | static int perf_session__flush_thread_stack(struct thread *thread, | ||
1366 | void *p __maybe_unused) | ||
1367 | { | ||
1368 | return thread_stack__flush(thread); | ||
1369 | } | ||
1370 | |||
1371 | static int perf_session__flush_thread_stacks(struct perf_session *session) | ||
1372 | { | ||
1373 | return machines__for_each_thread(&session->machines, | ||
1374 | perf_session__flush_thread_stack, | ||
1375 | NULL); | ||
1376 | } | ||
1377 | |||
1364 | volatile int session_done; | 1378 | volatile int session_done; |
1365 | 1379 | ||
1366 | static int __perf_session__process_pipe_events(struct perf_session *session) | 1380 | static int __perf_session__process_pipe_events(struct perf_session *session) |
@@ -1450,6 +1464,9 @@ done: | |||
1450 | if (err) | 1464 | if (err) |
1451 | goto out_err; | 1465 | goto out_err; |
1452 | err = auxtrace__flush_events(session, tool); | 1466 | err = auxtrace__flush_events(session, tool); |
1467 | if (err) | ||
1468 | goto out_err; | ||
1469 | err = perf_session__flush_thread_stacks(session); | ||
1453 | out_err: | 1470 | out_err: |
1454 | free(buf); | 1471 | free(buf); |
1455 | perf_session__warn_about_errors(session); | 1472 | perf_session__warn_about_errors(session); |
@@ -1600,6 +1617,9 @@ out: | |||
1600 | if (err) | 1617 | if (err) |
1601 | goto out_err; | 1618 | goto out_err; |
1602 | err = auxtrace__flush_events(session, tool); | 1619 | err = auxtrace__flush_events(session, tool); |
1620 | if (err) | ||
1621 | goto out_err; | ||
1622 | err = perf_session__flush_thread_stacks(session); | ||
1603 | out_err: | 1623 | out_err: |
1604 | ui_progress__finish(); | 1624 | ui_progress__finish(); |
1605 | perf_session__warn_about_errors(session); | 1625 | perf_session__warn_about_errors(session); |
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 9ed59a452d1f..679688e70ae7 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c | |||
@@ -219,7 +219,7 @@ static int thread_stack__call_return(struct thread *thread, | |||
219 | return crp->process(&cr, crp->data); | 219 | return crp->process(&cr, crp->data); |
220 | } | 220 | } |
221 | 221 | ||
222 | static int thread_stack__flush(struct thread *thread, struct thread_stack *ts) | 222 | static int __thread_stack__flush(struct thread *thread, struct thread_stack *ts) |
223 | { | 223 | { |
224 | struct call_return_processor *crp = ts->crp; | 224 | struct call_return_processor *crp = ts->crp; |
225 | int err; | 225 | int err; |
@@ -242,6 +242,14 @@ static int thread_stack__flush(struct thread *thread, struct thread_stack *ts) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | int thread_stack__flush(struct thread *thread) | ||
246 | { | ||
247 | if (thread->ts) | ||
248 | return __thread_stack__flush(thread, thread->ts); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
245 | int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | 253 | int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, |
246 | u64 to_ip, u16 insn_len, u64 trace_nr) | 254 | u64 to_ip, u16 insn_len, u64 trace_nr) |
247 | { | 255 | { |
@@ -264,7 +272,7 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | |||
264 | */ | 272 | */ |
265 | if (trace_nr != thread->ts->trace_nr) { | 273 | if (trace_nr != thread->ts->trace_nr) { |
266 | if (thread->ts->trace_nr) | 274 | if (thread->ts->trace_nr) |
267 | thread_stack__flush(thread, thread->ts); | 275 | __thread_stack__flush(thread, thread->ts); |
268 | thread->ts->trace_nr = trace_nr; | 276 | thread->ts->trace_nr = trace_nr; |
269 | } | 277 | } |
270 | 278 | ||
@@ -297,7 +305,7 @@ void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr) | |||
297 | 305 | ||
298 | if (trace_nr != thread->ts->trace_nr) { | 306 | if (trace_nr != thread->ts->trace_nr) { |
299 | if (thread->ts->trace_nr) | 307 | if (thread->ts->trace_nr) |
300 | thread_stack__flush(thread, thread->ts); | 308 | __thread_stack__flush(thread, thread->ts); |
301 | thread->ts->trace_nr = trace_nr; | 309 | thread->ts->trace_nr = trace_nr; |
302 | } | 310 | } |
303 | } | 311 | } |
@@ -305,7 +313,7 @@ void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr) | |||
305 | void thread_stack__free(struct thread *thread) | 313 | void thread_stack__free(struct thread *thread) |
306 | { | 314 | { |
307 | if (thread->ts) { | 315 | if (thread->ts) { |
308 | thread_stack__flush(thread, thread->ts); | 316 | __thread_stack__flush(thread, thread->ts); |
309 | zfree(&thread->ts->stack); | 317 | zfree(&thread->ts->stack); |
310 | zfree(&thread->ts); | 318 | zfree(&thread->ts); |
311 | } | 319 | } |
@@ -689,7 +697,7 @@ int thread_stack__process(struct thread *thread, struct comm *comm, | |||
689 | 697 | ||
690 | /* Flush stack on exec */ | 698 | /* Flush stack on exec */ |
691 | if (ts->comm != comm && thread->pid_ == thread->tid) { | 699 | if (ts->comm != comm && thread->pid_ == thread->tid) { |
692 | err = thread_stack__flush(thread, ts); | 700 | err = __thread_stack__flush(thread, ts); |
693 | if (err) | 701 | if (err) |
694 | return err; | 702 | return err; |
695 | ts->comm = comm; | 703 | ts->comm = comm; |
diff --git a/tools/perf/util/thread-stack.h b/tools/perf/util/thread-stack.h index b843bbef8ba2..e1528f1374c3 100644 --- a/tools/perf/util/thread-stack.h +++ b/tools/perf/util/thread-stack.h | |||
@@ -96,6 +96,7 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | |||
96 | void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr); | 96 | void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr); |
97 | void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, | 97 | void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, |
98 | size_t sz, u64 ip); | 98 | size_t sz, u64 ip); |
99 | int thread_stack__flush(struct thread *thread); | ||
99 | void thread_stack__free(struct thread *thread); | 100 | void thread_stack__free(struct thread *thread); |
100 | 101 | ||
101 | struct call_return_processor * | 102 | struct call_return_processor * |