Skip to content

Commit

Permalink
Merge "Initial TargetMemory implementation" into main
Browse files Browse the repository at this point in the history
  • Loading branch information
carlscabgro authored and Gerrit Code Review committed Dec 6, 2024
2 parents 45d960e + 7348fe8 commit f84c2d6
Show file tree
Hide file tree
Showing 24 changed files with 830 additions and 107 deletions.
3 changes: 3 additions & 0 deletions src/trace_processor/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ perfetto_unittest_source_set("unittests") {
"sqlite:unittests",
]
}
if (enable_perfetto_etm_importer) {
deps += [ "importers/etm:unittests" ]
}
}

perfetto_cc_proto_descriptor("gen_cc_test_messages_descriptor") {
Expand Down
33 changes: 29 additions & 4 deletions src/trace_processor/importers/etm/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import("../../../../gn/perfetto.gni")
import("../../../../gn/test.gni")

assert(enable_perfetto_etm_importer)

Expand All @@ -26,17 +27,24 @@ source_set("public_hdr") {
":etm",
":etm_impl",
]
sources = [ "etm_v4_stream_demultiplexer.h" ]
sources = [
"etm_tracker.h",
"etm_v4_stream_demultiplexer.h",
]

deps = [
"../../../../gn:default_deps",
"../../../../include/perfetto/ext/base:base",
"../../../../include/perfetto/trace_processor:storage",
"../../tables:tables_python",
"../../types",
]
}

source_set("etm_impl") {
visibility = [
":etm",
":unittests",
"../../perfetto_sql/intrinsics/operators:etm_impl",
]
sources = [
Expand All @@ -45,25 +53,28 @@ source_set("etm_impl") {
"error_logger.cc",
"error_logger.h",
"etm_tracker.cc",
"etm_tracker.h",
"etm_v4_decoder.cc",
"etm_v4_decoder.h",
"etm_v4_stream.cc",
"etm_v4_stream.h",
"etm_v4_stream_demultiplexer.cc",
"frame_decoder.cc",
"frame_decoder.h",
"mapping.cc",
"mapping.h",
"mapping_version.cc",
"mapping_version.h",
"opencsd.h",
"storage_handle.cc",
"storage_handle.h",
"target_memory.cc",
"target_memory.h",
"target_memory_reader.cc",
"target_memory_reader.h",
"types.cc",
"types.h",
"util.cc",
"util.h",
"virtual_address_space.cc",
"virtual_address_space.h",
]

public_deps = [ "../../../../gn:open_csd" ]
Expand All @@ -80,3 +91,17 @@ source_set("etm_impl") {
"../perf:record",
]
}

perfetto_unittest_source_set("unittests") {
testonly = true
sources = [ "virtual_address_space_unittest.cc" ]
deps = [
":etm_impl",
"../../../../gn:default_deps",
"../../../../gn:gtest_and_gmock",
"../../../base",
"../../storage",
"../../tables:tables_python",
"../../types",
]
}
10 changes: 6 additions & 4 deletions src/trace_processor/importers/etm/element_cursor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
#include <cstddef>
#include <cstdint>
#include <limits>
#include <memory>

#include "perfetto/base/logging.h"
#include "perfetto/base/status.h"
#include "src/trace_processor/importers/etm/etm_v4_decoder.h"
#include "src/trace_processor/importers/etm/storage_handle.h"
#include "src/trace_processor/importers/etm/target_memory.h"
#include "src/trace_processor/importers/etm/target_memory_reader.h"
#include "src/trace_processor/importers/etm/types.h"
#include "src/trace_processor/storage/trace_storage.h"
Expand All @@ -33,7 +33,9 @@
namespace perfetto::trace_processor::etm {

ElementCursor::ElementCursor(TraceStorage* storage)
: storage_(storage), reader_(std::make_unique<TargetMemoryReader>()) {}
: storage_(storage),
reader_(
std::make_unique<TargetMemoryReader>(TargetMemory::Get(storage))) {}

ElementCursor::~ElementCursor() = default;

Expand All @@ -50,7 +52,7 @@ base::Status ElementCursor::Filter(
storage_->etm_v4_trace_table().FindById(*trace_id)->session_id());
RETURN_IF_ERROR(ResetDecoder(session.configuration_id()));

reader_->SetTs(session.start_ts());
reader_->SetTs(session.start_ts().value_or(0));
// We expect this to overflow to 0 in the Next() below
element_index_ = std::numeric_limits<uint32_t>::max();
const auto& data = StorageHandle(storage_).GetTrace(*trace_id);
Expand Down Expand Up @@ -119,7 +121,7 @@ base::Status ElementCursor::Next() {
ocsd_datapath_resp_t ElementCursor::TraceElemIn(const ocsd_trc_index_t,
const uint8_t,
const OcsdTraceElement& elem,
const Mapping* mapping) {
const MappingVersion* mapping) {
++element_index_;
if (!(type_mask_.matches(elem.getType()))) {
return OCSD_RESP_CONT;
Expand Down
10 changes: 7 additions & 3 deletions src/trace_processor/importers/etm/element_cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
#include "src/trace_processor/tables/etm_tables_py.h"

namespace perfetto::trace_processor::etm {
class Mapping;

class MappingVersion;
class TargetMemory;
class TargetMemoryReader;

class ElementTypeMask {
Expand Down Expand Up @@ -92,13 +94,15 @@ class ElementCursor : public EtmV4Decoder::Delegate {

const TraceStorage* storage() const { return storage_; }

const MappingVersion* mapping() const { return mapping_; }

private:
void SetAtEof();
base::Status ResetDecoder(tables::EtmV4ConfigurationTable::Id config_id);
ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement& elem,
const Mapping* mapping) override;
const MappingVersion* mapping) override;

TraceStorage* storage_;
ElementTypeMask type_mask_;
Expand All @@ -114,7 +118,7 @@ class ElementCursor : public EtmV4Decoder::Delegate {
bool needs_flush_ = false;
uint32_t element_index_;
const OcsdTraceElement* element_;
const Mapping* mapping_;
const MappingVersion* mapping_;
};

} // namespace perfetto::trace_processor::etm
Expand Down
7 changes: 7 additions & 0 deletions src/trace_processor/importers/etm/etm_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
#include <cstdint>
#include <memory>

#include "perfetto/base/status.h"
#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/etm/storage_handle.h"
#include "src/trace_processor/importers/etm/target_memory.h"
#include "src/trace_processor/importers/etm/types.h"
#include "src/trace_processor/importers/etm/util.h"
#include "src/trace_processor/storage/trace_storage.h"
Expand Down Expand Up @@ -88,4 +90,9 @@ EtmTracker::InsertEtmV4Config(PerCpuConfiguration per_cpu_configs) {
return res;
}

base::Status EtmTracker::Finalize() {
TargetMemory::InitStorage(context_);
return base::OkStatus();
}

} // namespace perfetto::trace_processor::etm
9 changes: 8 additions & 1 deletion src/trace_processor/importers/etm/etm_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_ETM_ETM_TRACKER_H_

#include "perfetto/base/flat_set.h"
#include "perfetto/base/status.h"
#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/etm/types.h"
#include "src/trace_processor/tables/etm_tables_py.h"
#include "src/trace_processor/types/destructible.h"
#include "src/trace_processor/types/trace_processor_context.h"

namespace perfetto::trace_processor {
namespace etm {

class Configuration;

using PerCpuConfiguration =
base::FlatHashMap<uint32_t, std::unique_ptr<Configuration>>;

class EtmTracker : public Destructible {
public:
static EtmTracker* GetOrCreate(TraceProcessorContext* context) {
Expand All @@ -38,6 +43,8 @@ class EtmTracker : public Destructible {

~EtmTracker() override;

base::Status Finalize();

void AddSessionData(tables::EtmV4SessionTable::Id session_id,
std::vector<TraceBlobView> traces);

Expand Down
17 changes: 8 additions & 9 deletions src/trace_processor/importers/etm/etm_v4_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/base/status.h"
#include "perfetto/ext/base/status_or.h"
#include "src/trace_processor/importers/common/address_range.h"
#include "src/trace_processor/importers/etm/mapping.h"
#include "src/trace_processor/importers/etm/mapping_version.h"
#include "src/trace_processor/importers/etm/opencsd.h"
#include "src/trace_processor/importers/etm/target_memory_reader.h"
#include "src/trace_processor/util/status_macros.h"
Expand Down Expand Up @@ -78,14 +77,13 @@ base::Status EtmV4Decoder::Init(const EtmV4Config& config) {
ocsd_datapath_resp_t EtmV4Decoder::TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement& elem) {
const MappingVersion* content = nullptr;
if (elem.getType() == OCSD_GEN_TRC_ELEM_PE_CONTEXT) {
memory_reader_->SetPeContext(elem.getContext());
}
const Mapping* content = nullptr;
if (elem.getType() == OCSD_GEN_TRC_ELEM_INSTR_RANGE) {
AddressRange range(elem.st_addr, elem.en_addr);
content = memory_reader_->FindMapping(range);
if (!content) {
} else if (elem.getType() == OCSD_GEN_TRC_ELEM_INSTR_RANGE) {
content = memory_reader_->FindMapping(elem.st_addr);
PERFETTO_CHECK(content);
if (!content->Contains(elem.en_addr)) {
// Sometimes (very very rarely) we get huge instruction ranges that can
// span multiple adjacent mappings caused by runaway decoding.
// Some libraries get their code modified at load time (e.g. linux kernel
Expand All @@ -96,8 +94,9 @@ ocsd_datapath_resp_t EtmV4Decoder::TraceElemIn(const ocsd_trc_index_t index_sop,
"Mapping does not contain full instruction range. st_addr=%" PRIu64
"en_addr=%" PRIu64,
elem.st_addr, elem.en_addr);
content = nullptr;
}
} else if (elem.getType() == OCSD_GEN_TRC_ELEM_ADDR_NACC) {
content = memory_reader_->FindMapping(elem.st_addr);
}
return delegate_->TraceElemIn(index_sop, trc_chan_id, elem, content);
}
Expand Down
4 changes: 2 additions & 2 deletions src/trace_processor/importers/etm/etm_v4_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

namespace perfetto::trace_processor::etm {

class Mapping;
class MappingVersion;
class TargetMemoryReader;

// Wrapper around the open_csd packet processor. This class will take ETM traces
Expand All @@ -41,7 +41,7 @@ class EtmV4Decoder : private ITrcGenElemIn {
virtual ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop,
const uint8_t trc_chan_id,
const OcsdTraceElement& elem,
const Mapping* mapping) = 0;
const MappingVersion* mapping) = 0;
};

static base::StatusOr<std::unique_ptr<EtmV4Decoder>> Create(
Expand Down
20 changes: 0 additions & 20 deletions src/trace_processor/importers/etm/mapping.cc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,16 @@
* limitations under the License.
*/

#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_ETM_MAPPING_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_ETM_MAPPING_H_

#include "src/trace_processor/importers/common/address_range.h"
#include "src/trace_processor/importers/etm/mapping_version.h"
#include "perfetto/base/logging.h"

namespace perfetto::trace_processor::etm {

class Mapping {
public:
Mapping() {}
const AddressRange& range() const { return range_; }

private:
AddressRange range_;
};

MappingVersion MappingVersion::SplitFront(uint64_t mid) {
PERFETTO_CHECK(range_.start() < mid && mid < range_.end());
AddressRange head(range_.start(), mid);
AddressRange tail(mid, range_.end());
range_ = tail;
return MappingVersion(id_, create_ts_, head);
}
} // namespace perfetto::trace_processor::etm

#endif // SRC_TRACE_PROCESSOR_IMPORTERS_ETM_MAPPING_H_
56 changes: 56 additions & 0 deletions src/trace_processor/importers/etm/mapping_version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_ETM_MAPPING_VERSION_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_ETM_MAPPING_VERSION_H_

#include <cstdint>

#include "src/trace_processor/importers/common/address_range.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/tables/profiler_tables_py.h"

namespace perfetto::trace_processor::etm {
class MappingVersion {
public:
MappingVersion(int64_t create_ts,
tables::StackProfileMappingTable::ConstRowReference mapping)
: id_(mapping.id()),
create_ts_(create_ts),
range_(static_cast<uint64_t>(mapping.start()),
static_cast<uint64_t>(mapping.end())) {}
bool Contains(uint64_t address) const { return range_.Contains(address); }
bool Contains(const AddressRange& range) const {
return range_.Contains(range);
}
uint64_t start() const { return range_.start(); }
uint64_t end() const { return range_.end(); }
int64_t create_ts() const { return create_ts_; }
MappingId id() const { return id_; }

MappingVersion SplitFront(uint64_t mid);

private:
MappingVersion(MappingId id, int64_t create_ts, AddressRange alive_range)
: id_(id), create_ts_(create_ts), range_(alive_range) {}
MappingId id_;
int64_t create_ts_;
AddressRange range_;
};

} // namespace perfetto::trace_processor::etm

#endif // SRC_TRACE_PROCESSOR_IMPORTERS_ETM_MAPPING_VERSION_H_
Loading

0 comments on commit f84c2d6

Please sign in to comment.