Skip to content

Commit

Permalink
Parsing android_fs_read events
Browse files Browse the repository at this point in the history
In this CL we re adding support to parse the android_fs events, one issue here is that a read start and read end events can happen on different thread we keep track of things by using a map with inode, offset and threadId to track the start and end events.

Change-Id: I14fd317083ae3ac4c6bb39323ed88bb97837fab1
  • Loading branch information
rahuludacity committed Oct 9, 2023
1 parent a908c7a commit e096209
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 5 deletions.
80 changes: 75 additions & 5 deletions src/trace_processor/importers/ftrace/ftrace_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/softirq_action.h"
#include "src/trace_processor/types/tcp_state.h"

#include "protos/perfetto/common/gpu_counter_descriptor.pbzero.h"
#include "protos/perfetto/trace/ftrace/android_fs.pbzero.h"
#include "protos/perfetto/trace/ftrace/binder.pbzero.h"
#include "protos/perfetto/trace/ftrace/cma.pbzero.h"
#include "protos/perfetto/trace/ftrace/cpuhp.pbzero.h"
Expand Down Expand Up @@ -217,8 +217,7 @@ std::string GetUfsCmdString(uint32_t ufsopcode, uint32_t gid) {
}
return buffer;
}
} // namespace

} // namespace
FtraceParser::FtraceParser(TraceProcessorContext* context)
: context_(context),
rss_stat_tracker_(context),
Expand Down Expand Up @@ -315,7 +314,15 @@ FtraceParser::FtraceParser(TraceProcessorContext* context)
cma_nr_test_fail_id_(context_->storage->InternString("cma_nr_test_fail")),
syscall_ret_id_(context->storage->InternString("ret")),
syscall_args_id_(context->storage->InternString("args")),
replica_slice_id_(context->storage->InternString("replica_slice")) {
replica_slice_id_(context->storage->InternString("replica_slice")),
file_path_id_(context_->storage->InternString("file_path")),
offset_id_start_(context_->storage->InternString("offset_start")),
offset_id_end_(context_->storage->InternString("offset_end")),
bytes_read_id_start_(context_->storage->InternString("bytes_read_start")),
bytes_read_id_end_(context_->storage->InternString("bytes_read_end")),
android_fs_category_id_(context_->storage->InternString("android_fs")),
android_fs_data_read_id_(
context_->storage->InternString("android_fs_data_read")) {
// Build the lookup table for the strings inside ftrace events (e.g. the
// name of ftrace event fields and the names of their args).
for (size_t i = 0; i < GetDescriptorsSize(); i++) {
Expand Down Expand Up @@ -1047,7 +1054,14 @@ util::Status FtraceParser::ParseFtraceEvent(uint32_t cpu,
ParseMdssTracingMarkWrite(ts, pid, fld_bytes);
break;
}

case FtraceEvent::kAndroidFsDatareadEndFieldNumber: {
ParseAndroidFsDatareadEnd(ts, fld_bytes);
break;
}
case FtraceEvent::kAndroidFsDatareadStartFieldNumber: {
ParseAndroidFsDatareadStart(ts, pid, fld_bytes);
break;
}
default:
break;
}
Expand Down Expand Up @@ -3092,6 +3106,62 @@ void FtraceParser::ParseFuncgraphExit(
context_->slice_tracker->End(timestamp, track, kNullStringId, name_id);
}

/** Parses android_fs_dataread_start event.*/
void FtraceParser::ParseAndroidFsDatareadStart(int64_t ts,
uint32_t pid,
ConstBytes data) {
protos::pbzero::AndroidFsDatareadStartFtraceEvent::Decoder
android_fs_read_begin(data);
base::StringView file_path(android_fs_read_begin.pathbuf());
std::pair<uint64_t, int64_t> key(android_fs_read_begin.ino(),
android_fs_read_begin.offset());
inode_offset_thread_map_.Insert(key, pid);
// Create a new Track object for the event.
auto async_track = context_->async_track_set_tracker->InternGlobalTrackSet(
android_fs_category_id_);
TrackId track_id = context_->async_track_set_tracker->Begin(async_track, pid);
StringId string_id = context_->storage->InternString(file_path);
auto args_inserter = [this, &android_fs_read_begin,
&string_id](ArgsTracker::BoundInserter* inserter) {
inserter->AddArg(file_path_id_, Variadic::String(string_id));
inserter->AddArg(offset_id_start_,
Variadic::Integer(android_fs_read_begin.offset()));
inserter->AddArg(bytes_read_id_start_,
Variadic::Integer(android_fs_read_begin.bytes()));
};
context_->slice_tracker->Begin(ts, track_id, kNullStringId,
android_fs_data_read_id_, args_inserter);
}

/** Parses android_fs_dataread_end event.*/
void FtraceParser::ParseAndroidFsDatareadEnd(int64_t ts, ConstBytes data) {
protos::pbzero::AndroidFsDatareadEndFtraceEvent::Decoder android_fs_read_end(
data);
std::pair<uint64_t, int64_t> key(android_fs_read_end.ino(),
android_fs_read_end.offset());
// Find the corresponding (inode, offset) pair in the map.
auto it = inode_offset_thread_map_.Find(key);
if (!it) {
return;
}
uint32_t start_event_tid = *it;
auto async_track = context_->async_track_set_tracker->InternGlobalTrackSet(
android_fs_category_id_);
TrackId track_id =
context_->async_track_set_tracker->End(async_track, start_event_tid);
auto args_inserter =
[this, &android_fs_read_end](ArgsTracker::BoundInserter* inserter) {
inserter->AddArg(offset_id_end_,
Variadic::Integer(android_fs_read_end.offset()));
inserter->AddArg(bytes_read_id_end_,
Variadic::Integer(android_fs_read_end.bytes()));
};
context_->slice_tracker->End(ts, track_id, kNullStringId, kNullStringId,
args_inserter);
// Erase the entry from the map.
inode_offset_thread_map_.Erase(key);
}

StringId FtraceParser::InternedKernelSymbolOrFallback(
uint64_t key,
PacketSequenceStateGeneration* seq_state) {
Expand Down
25 changes: 25 additions & 0 deletions src/trace_processor/importers/ftrace/ftrace_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_FTRACE_PARSER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_FTRACE_PARSER_H_

#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/ext/base/hash.h"
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/parser_types.h"
Expand Down Expand Up @@ -285,6 +287,10 @@ class FtraceParser {
void ParseMaliKcpuFenceSignal(uint32_t pid, int64_t ts);
void ParseMaliKcpuFenceWaitStart(uint32_t pid, int64_t ts);
void ParseMaliKcpuFenceWaitEnd(uint32_t pid, int64_t ts);
void ParseAndroidFsDatareadEnd(int64_t timestamp, protozero::ConstBytes);
void ParseAndroidFsDatareadStart(int64_t ts,
uint32_t pid,
protozero::ConstBytes);

TraceProcessorContext* context_;
RssStatTracker rss_stat_tracker_;
Expand Down Expand Up @@ -366,6 +372,13 @@ class FtraceParser {
const StringId syscall_ret_id_;
const StringId syscall_args_id_;
const StringId replica_slice_id_;
const StringId file_path_id_;
const StringId offset_id_start_;
const StringId offset_id_end_;
const StringId bytes_read_id_start_;
const StringId bytes_read_id_end_;
const StringId android_fs_category_id_;
const StringId android_fs_data_read_id_;
std::vector<StringId> syscall_arg_name_ids_;

struct FtraceMessageStrings {
Expand Down Expand Up @@ -428,6 +441,18 @@ class FtraceParser {
// putting them in the metadata multiple times (the ftrace data sources
// re-emits begin stats on every flush).
std::unordered_set<uint32_t> seen_errors_for_sequence_id_;

struct PairHash {
std::size_t operator()(const std::pair<uint64_t, int64_t>& p) const {
base::Hasher hasher;
hasher.Update(p.first);
hasher.Update(p.second);
return static_cast<std::size_t>(hasher.digest());
}
};

base::FlatHashMap<std::pair<uint64_t, int64_t>, uint32_t, PairHash>
inode_offset_thread_map_;
};

} // namespace trace_processor
Expand Down
67 changes: 67 additions & 0 deletions test/trace_processor/diff_tests/android_fs/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
# Copyright (C) 2023 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 a
#
# 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.

from python.generators.diff_tests.testing import Path, DataPath, Metric
from python.generators.diff_tests.testing import Csv, Json, TextProto
from python.generators.diff_tests.testing import DiffTestBlueprint
from python.generators.diff_tests.testing import TestSuite


class AndroidFs(TestSuite):

# android_fs_dataread
def test_android_fs_dataread(self):
return DiffTestBlueprint(
trace=TextProto(r"""
packet {
ftrace_events {
cpu: 0
event {
timestamp: 46448185788840
pid: 5892
android_fs_dataread_start {
bytes: 4096
pid: 5892
ino: 836
offset: 0
cmdline: "am"
i_size: 31772
pathbuf: "/system/bin/cmd"
}
}
}
}
packet {
ftrace_events {
cpu: 0
event {
timestamp: 46448185789530
pid: 156
android_fs_dataread_end {
bytes: 4096
ino: 836
offset: 0
}
}
}
}
"""),
query="""
SELECT ts, dur, name FROM slice WHERE name = 'android_fs_data_read';
""",
out=Csv("""
"ts","dur","name"
46448185788840,690,"android_fs_data_read"
"""))
2 changes: 2 additions & 0 deletions test/trace_processor/diff_tests/include_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
from diff_tests.translation.tests import Translation
from diff_tests.ufs.tests import Ufs
from diff_tests.webview.tests import WebView
from diff_tests.android_fs.tests import AndroidFs

sys.path.pop()

Expand All @@ -102,6 +103,7 @@ def fetch_all_diff_tests(index_path: str) -> List['testing.TestCase']:
return [
*Android(index_path, 'android', 'Android').fetch(),
*AndroidBugreport(index_path, 'android', 'AndroidBugreport').fetch(),
*AndroidFs(index_path, 'android_fs', 'AndroidFs').fetch(),
*AndroidGames(index_path, 'android', 'AndroidGames').fetch(),
*Atrace(index_path, 'atrace', 'Atrace').fetch(),
*AtraceErrorHandling(index_path, 'atrace', 'AtraceErrorHandling').fetch(),
Expand Down

0 comments on commit e096209

Please sign in to comment.