From 18b0775d68a04d78a4a4bcd6d23d717245aba184 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Tue, 28 Jun 2016 11:50:11 -0400 Subject: [PATCH] Switch to new encoding scheme for large records. Move to the new SPLIT/SPLIT_END encoding scheme used by simpleperf for records with oversized (more than 2^16 bytes) payloads. Bug: 29818021 Change-Id: I40126748dbe9b07b107c85b891f7aafbc556ae1f --- perfprofd/quipper/perf_internals.h | 4 ++++ perfprofd/quipper/perf_parser.cc | 4 ++++ perfprofd/quipper/perf_reader.cc | 26 +++++++++++++++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/perfprofd/quipper/perf_internals.h b/perfprofd/quipper/perf_internals.h index 6b2113e4..a779d3c8 100644 --- a/perfprofd/quipper/perf_internals.h +++ b/perfprofd/quipper/perf_internals.h @@ -68,6 +68,10 @@ typedef perf_event event_t; enum simpleperf_record_type { SIMPLE_PERF_RECORD_TYPE_START = 32768, SIMPLE_PERF_RECORD_KERNEL_SYMBOL, + SIMPLE_PERF_RECORD_DSO, + SIMPLE_PERF_RECORD_SYMBOL, + SIMPLE_PERF_RECORD_SPLIT, + SIMPLE_PERF_RECORD_SPLIT_END, }; #endif diff --git a/perfprofd/quipper/perf_parser.cc b/perfprofd/quipper/perf_parser.cc index 0821612c..c9ec1891 100644 --- a/perfprofd/quipper/perf_parser.cc +++ b/perfprofd/quipper/perf_parser.cc @@ -216,6 +216,10 @@ bool PerfParser::ProcessEvents() { << ". Doing nothing."; break; case SIMPLE_PERF_RECORD_KERNEL_SYMBOL: + case SIMPLE_PERF_RECORD_DSO: + case SIMPLE_PERF_RECORD_SYMBOL: + case SIMPLE_PERF_RECORD_SPLIT: + case SIMPLE_PERF_RECORD_SPLIT_END: break; default: LOG(ERROR) << "Unknown event type: " << event.header.type; diff --git a/perfprofd/quipper/perf_reader.cc b/perfprofd/quipper/perf_reader.cc index 1b397ac1..48497d07 100644 --- a/perfprofd/quipper/perf_reader.cc +++ b/perfprofd/quipper/perf_reader.cc @@ -802,6 +802,10 @@ bool PerfReader::IsSupportedEventType(uint32_t type) { case PERF_RECORD_THROTTLE: case PERF_RECORD_UNTHROTTLE: case SIMPLE_PERF_RECORD_KERNEL_SYMBOL: + case SIMPLE_PERF_RECORD_DSO: + case SIMPLE_PERF_RECORD_SYMBOL: + case SIMPLE_PERF_RECORD_SPLIT: + case SIMPLE_PERF_RECORD_SPLIT_END: return true; case PERF_RECORD_READ: case PERF_RECORD_MAX: @@ -822,7 +826,11 @@ bool PerfReader::ReadPerfSampleInfo(const event_t& event, } // We want to completely ignore these records - if (event.header.type == SIMPLE_PERF_RECORD_KERNEL_SYMBOL) + if (event.header.type == SIMPLE_PERF_RECORD_KERNEL_SYMBOL || + event.header.type == SIMPLE_PERF_RECORD_DSO || + event.header.type == SIMPLE_PERF_RECORD_SYMBOL || + event.header.type == SIMPLE_PERF_RECORD_SPLIT || + event.header.type == SIMPLE_PERF_RECORD_SPLIT_END) return true; uint64_t sample_format = GetSampleFieldsForEventType(event.header.type, @@ -1431,11 +1439,19 @@ bool PerfReader::ReadPerfEventBlock(const event_t& event) { ByteSwap(&size); // - // Special case for kernel symbol record, which may be very - // large -- this is safe to do since we will be skipping over - // the kernel symbols entirely later on. + // Upstream linux perf limits the size of an event record to 2^16 bytes, + // however simpleperf includes extensions to support larger (2^32) record + // sizes via a split record scheme (the larger records are split up + // into chunks and then embedded into a series of SIMPLE_PERF_RECORD_SPLIT + // records followed by a terminating SIMPLE_PERF_RECORD_SPLIT_END record. + // At the moment none of the larger records are of interest to perfprofd, so + // the main thing we're doing here is ignoring/bypassing them. // - if (event.header.type == SIMPLE_PERF_RECORD_KERNEL_SYMBOL) + if (event.header.type == SIMPLE_PERF_RECORD_KERNEL_SYMBOL || + event.header.type == SIMPLE_PERF_RECORD_DSO || + event.header.type == SIMPLE_PERF_RECORD_SYMBOL || + event.header.type == SIMPLE_PERF_RECORD_SPLIT || + event.header.type == SIMPLE_PERF_RECORD_SPLIT_END) size = sizeof(event_t); else if (size > sizeof(event_t)) { LOG(INFO) << "Data size: " << size << " sizeof(event_t): " -- 2.11.0