Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf auxtrace: Add option to feed branches to the thread stack

In preparation for using the thread stack to print an indent
representing the stack depth in perf script, add an option to tell
decoders to feed branches to the thread stack. Add support for that
option to Intel PT and Intel BTS.

The advantage of using the decoder to feed the thread stack is that it
happens before branch filtering and so can be used with different itrace
options (e.g. it still works when only showing calls, even though the
thread stack needs to see calls and returns). Also it does not conflict
with using the thread stack to get callchains.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1466689258-28493-3-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
50f73637 055cd33d

+23 -6
+2
tools/perf/util/auxtrace.h
··· 63 63 * @calls: limit branch samples to calls (can be combined with @returns) 64 64 * @returns: limit branch samples to returns (can be combined with @calls) 65 65 * @callchain: add callchain to 'instructions' events 66 + * @thread_stack: feed branches to the thread_stack 66 67 * @last_branch: add branch context to 'instruction' events 67 68 * @callchain_sz: maximum callchain size 68 69 * @last_branch_sz: branch context size ··· 83 82 bool calls; 84 83 bool returns; 85 84 bool callchain; 85 + bool thread_stack; 86 86 bool last_branch; 87 87 unsigned int callchain_sz; 88 88 unsigned int last_branch_sz;
+17 -5
tools/perf/util/intel-bts.c
··· 422 422 } 423 423 424 424 static 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 428 struct branch *branch; 428 429 size_t sz, bsz = sizeof(struct branch); ··· 445 444 if (!branch->from && !branch->to) 446 445 continue; 447 446 intel_bts_get_branch_type(btsq, branch); 447 + if (btsq->bts->synth_opts.thread_stack) 448 + thread_stack__event(thread, btsq->sample_flags, 449 + le64_to_cpu(branch->from), 450 + le64_to_cpu(branch->to), 451 + btsq->intel_pt_insn.length, 452 + buffer->buffer_nr + 1); 448 453 if (filter && !(filter & btsq->sample_flags)) 449 454 continue; 450 455 err = intel_bts_synth_branch_sample(btsq, branch); ··· 514 507 goto out_put; 515 508 } 516 509 517 - if (!btsq->bts->synth_opts.callchain && thread && 510 + if (!btsq->bts->synth_opts.callchain && 511 + !btsq->bts->synth_opts.thread_stack && thread && 518 512 (!old_buffer || btsq->bts->sampling_mode || 519 513 (btsq->bts->snapshot_mode && !buffer->consecutive))) 520 514 thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1); 521 515 522 - err = intel_bts_process_buffer(btsq, buffer); 516 + err = intel_bts_process_buffer(btsq, buffer, thread); 523 517 524 518 auxtrace_buffer__drop_data(buffer); 525 519 ··· 913 905 if (dump_trace) 914 906 return 0; 915 907 916 - if (session->itrace_synth_opts && session->itrace_synth_opts->set) 908 + if (session->itrace_synth_opts && session->itrace_synth_opts->set) { 917 909 bts->synth_opts = *session->itrace_synth_opts; 918 - else 910 + } else { 919 911 itrace_synth_opts__set_default(&bts->synth_opts); 912 + if (session->itrace_synth_opts) 913 + bts->synth_opts.thread_stack = 914 + session->itrace_synth_opts->thread_stack; 915 + } 920 916 921 917 if (bts->synth_opts.calls) 922 918 bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
+4 -1
tools/perf/util/intel-pt.c
··· 1234 1234 if (!(state->type & INTEL_PT_BRANCH)) 1235 1235 return 0; 1236 1236 1237 - if (pt->synth_opts.callchain) 1237 + if (pt->synth_opts.callchain || pt->synth_opts.thread_stack) 1238 1238 thread_stack__event(ptq->thread, ptq->flags, state->from_ip, 1239 1239 state->to_ip, ptq->insn_len, 1240 1240 state->trace_nr); ··· 2137 2137 pt->synth_opts.branches = false; 2138 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 2145 if (pt->synth_opts.log)