aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/auxtrace.h2
-rw-r--r--tools/perf/util/intel-bts.c22
-rw-r--r--tools/perf/util/intel-pt.c5
3 files changed, 23 insertions, 6 deletions
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 767989e0e312..ac5f0d7167e6 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -63,6 +63,7 @@ enum itrace_period_type {
63 * @calls: limit branch samples to calls (can be combined with @returns) 63 * @calls: limit branch samples to calls (can be combined with @returns)
64 * @returns: limit branch samples to returns (can be combined with @calls) 64 * @returns: limit branch samples to returns (can be combined with @calls)
65 * @callchain: add callchain to 'instructions' events 65 * @callchain: add callchain to 'instructions' events
66 * @thread_stack: feed branches to the thread_stack
66 * @last_branch: add branch context to 'instruction' events 67 * @last_branch: add branch context to 'instruction' events
67 * @callchain_sz: maximum callchain size 68 * @callchain_sz: maximum callchain size
68 * @last_branch_sz: branch context size 69 * @last_branch_sz: branch context size
@@ -82,6 +83,7 @@ struct itrace_synth_opts {
82 bool calls; 83 bool calls;
83 bool returns; 84 bool returns;
84 bool callchain; 85 bool callchain;
86 bool thread_stack;
85 bool last_branch; 87 bool last_branch;
86 unsigned int callchain_sz; 88 unsigned int callchain_sz;
87 unsigned int last_branch_sz; 89 unsigned int last_branch_sz;
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index ecec73f6fe5a..749e6f2e37ca 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -422,7 +422,8 @@ static int intel_bts_get_branch_type(struct intel_bts_queue *btsq,
422} 422}
423 423
424static int intel_bts_process_buffer(struct intel_bts_queue *btsq, 424static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
425 struct auxtrace_buffer *buffer) 425 struct auxtrace_buffer *buffer,
426 struct thread *thread)
426{ 427{
427 struct branch *branch; 428 struct branch *branch;
428 size_t sz, bsz = sizeof(struct branch); 429 size_t sz, bsz = sizeof(struct branch);
@@ -444,6 +445,12 @@ static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
444 if (!branch->from && !branch->to) 445 if (!branch->from && !branch->to)
445 continue; 446 continue;
446 intel_bts_get_branch_type(btsq, branch); 447 intel_bts_get_branch_type(btsq, branch);
448 if (btsq->bts->synth_opts.thread_stack)
449 thread_stack__event(thread, btsq->sample_flags,
450 le64_to_cpu(branch->from),
451 le64_to_cpu(branch->to),
452 btsq->intel_pt_insn.length,
453 buffer->buffer_nr + 1);
447 if (filter && !(filter & btsq->sample_flags)) 454 if (filter && !(filter & btsq->sample_flags))
448 continue; 455 continue;
449 err = intel_bts_synth_branch_sample(btsq, branch); 456 err = intel_bts_synth_branch_sample(btsq, branch);
@@ -507,12 +514,13 @@ static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp)
507 goto out_put; 514 goto out_put;
508 } 515 }
509 516
510 if (!btsq->bts->synth_opts.callchain && thread && 517 if (!btsq->bts->synth_opts.callchain &&
518 !btsq->bts->synth_opts.thread_stack && thread &&
511 (!old_buffer || btsq->bts->sampling_mode || 519 (!old_buffer || btsq->bts->sampling_mode ||
512 (btsq->bts->snapshot_mode && !buffer->consecutive))) 520 (btsq->bts->snapshot_mode && !buffer->consecutive)))
513 thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1); 521 thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1);
514 522
515 err = intel_bts_process_buffer(btsq, buffer); 523 err = intel_bts_process_buffer(btsq, buffer, thread);
516 524
517 auxtrace_buffer__drop_data(buffer); 525 auxtrace_buffer__drop_data(buffer);
518 526
@@ -905,10 +913,14 @@ int intel_bts_process_auxtrace_info(union perf_event *event,
905 if (dump_trace) 913 if (dump_trace)
906 return 0; 914 return 0;
907 915
908 if (session->itrace_synth_opts && session->itrace_synth_opts->set) 916 if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
909 bts->synth_opts = *session->itrace_synth_opts; 917 bts->synth_opts = *session->itrace_synth_opts;
910 else 918 } else {
911 itrace_synth_opts__set_default(&bts->synth_opts); 919 itrace_synth_opts__set_default(&bts->synth_opts);
920 if (session->itrace_synth_opts)
921 bts->synth_opts.thread_stack =
922 session->itrace_synth_opts->thread_stack;
923 }
912 924
913 if (bts->synth_opts.calls) 925 if (bts->synth_opts.calls)
914 bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | 926 bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index dc243b19197b..551ff6f640be 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -1234,7 +1234,7 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
1234 if (!(state->type & INTEL_PT_BRANCH)) 1234 if (!(state->type & INTEL_PT_BRANCH))
1235 return 0; 1235 return 0;
1236 1236
1237 if (pt->synth_opts.callchain) 1237 if (pt->synth_opts.callchain || pt->synth_opts.thread_stack)
1238 thread_stack__event(ptq->thread, ptq->flags, state->from_ip, 1238 thread_stack__event(ptq->thread, ptq->flags, state->from_ip,
1239 state->to_ip, ptq->insn_len, 1239 state->to_ip, ptq->insn_len,
1240 state->trace_nr); 1240 state->trace_nr);
@@ -2137,6 +2137,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
2137 pt->synth_opts.branches = false; 2137 pt->synth_opts.branches = false;
2138 pt->synth_opts.callchain = true; 2138 pt->synth_opts.callchain = true;
2139 } 2139 }
2140 if (session->itrace_synth_opts)
2141 pt->synth_opts.thread_stack =
2142 session->itrace_synth_opts->thread_stack;
2140 } 2143 }
2141 2144
2142 if (pt->synth_opts.log) 2145 if (pt->synth_opts.log)