aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/machine.c21
-rw-r--r--tools/perf/util/machine.h3
-rw-r--r--tools/perf/util/session.c20
-rw-r--r--tools/perf/util/thread-stack.c18
-rw-r--r--tools/perf/util/thread-stack.h1
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
1893int 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
1893int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 1914int __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);
216int machine__for_each_thread(struct machine *machine, 216int 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);
219int machines__for_each_thread(struct machines *machines,
220 int (*fn)(struct thread *thread, void *p),
221 void *priv);
219 222
220int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 223int __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
20static int perf_session__deliver_event(struct perf_session *session, 21static 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
1365static int perf_session__flush_thread_stack(struct thread *thread,
1366 void *p __maybe_unused)
1367{
1368 return thread_stack__flush(thread);
1369}
1370
1371static 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
1364volatile int session_done; 1378volatile int session_done;
1365 1379
1366static int __perf_session__process_pipe_events(struct perf_session *session) 1380static 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);
1453out_err: 1470out_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);
1603out_err: 1623out_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
222static int thread_stack__flush(struct thread *thread, struct thread_stack *ts) 222static 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
245int 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
245int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, 253int 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)
305void thread_stack__free(struct thread *thread) 313void 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,
96void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr); 96void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr);
97void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, 97void thread_stack__sample(struct thread *thread, struct ip_callchain *chain,
98 size_t sz, u64 ip); 98 size_t sz, u64 ip);
99int thread_stack__flush(struct thread *thread);
99void thread_stack__free(struct thread *thread); 100void thread_stack__free(struct thread *thread);
100 101
101struct call_return_processor * 102struct call_return_processor *