diff options
author | Yabin Cui <yabinc@google.com> | 2017-07-24 14:59:46 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2017-07-24 14:59:46 -0700 |
commit | d3cb3b0c50211ad68459d526fcc32eb11b8f26a5 (patch) | |
tree | 027116325b25ecb2552e34122529adf07524801d /simpleperf/record.cpp | |
parent | 239663cf9757485fb723e17b10be5c6b12706bd7 (diff) | |
download | extras-d3cb3b0c50211ad68459d526fcc32eb11b8f26a5.tar.gz |
simpleperf: exclude kernel callchains when needed.
Exclude kernel callchains when users only monitor events in user space.
After this change, when users use `record -e cpu-cycles:u --trace-offcpu`,
the samples of the implicitly added sched:sched_switch event won't contain
any kernel callchain.
Bug: http://b/37572306
Test: run simpleperf_unit_test.
Change-Id: Iffcb61bac796e734825e68f847f24b4006b44360
Diffstat (limited to 'simpleperf/record.cpp')
-rw-r--r-- | simpleperf/record.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp index 65e98ea6..f3548150 100644 --- a/simpleperf/record.cpp +++ b/simpleperf/record.cpp @@ -594,6 +594,31 @@ void SampleRecord::ReplaceRegAndStackWithCallChain( *reinterpret_cast<uint64_t*>(p) = callchain_data.ip_nr; } +size_t SampleRecord::ExcludeKernelCallChain() { + size_t user_callchain_length = 0u; + if (sample_type & PERF_SAMPLE_CALLCHAIN) { + size_t i; + for (i = 0; i < callchain_data.ip_nr; ++i) { + if (callchain_data.ips[i] == PERF_CONTEXT_USER) { + i++; + if (i < callchain_data.ip_nr) { + ip_data.ip = callchain_data.ips[i]; + if (sample_type & PERF_SAMPLE_IP) { + *reinterpret_cast<uint64_t*>(const_cast<char*>(binary_ + header_size())) = ip_data.ip; + } + header.misc = (header.misc & ~PERF_RECORD_MISC_KERNEL) | PERF_RECORD_MISC_USER; + reinterpret_cast<perf_event_header*>(const_cast<char*>(binary_))->misc = header.misc; + } + break; + } else { + const_cast<uint64_t*>(callchain_data.ips)[i] = PERF_CONTEXT_USER; + } + } + user_callchain_length = callchain_data.ip_nr - i; + } + return user_callchain_length; +} + void SampleRecord::DumpData(size_t indent) const { PrintIndented(indent, "sample_type: 0x%" PRIx64 "\n", sample_type); if (sample_type & PERF_SAMPLE_IP) { |