1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/importers/ftrace/iostat_tracker.h"
18 #include "protos/perfetto/trace/ftrace/f2fs.pbzero.h"
19 #include "src/trace_processor/importers/common/event_tracker.h"
20 #include "src/trace_processor/importers/common/track_tracker.h"
21
22 namespace perfetto {
23 namespace trace_processor {
24
25 static constexpr char kF2fsIostatTag[] = "f2fs_iostat";
26 static constexpr char kF2fsIostatLatencyTag[] = "f2fs_iostat_latency";
27
IostatTracker(TraceProcessorContext * context)28 IostatTracker::IostatTracker(TraceProcessorContext* context)
29 : context_(context) {}
30
GetDeviceName(uint64_t dev_num)31 std::string IostatTracker::GetDeviceName(uint64_t dev_num) {
32 std::string dev_name = std::to_string((dev_num & 0xFF00) >> 8) + ":" +
33 std::to_string(dev_num & 0xFF);
34 return "[" + dev_name + "]";
35 }
36
ParseF2fsIostat(int64_t timestamp,protozero::ConstBytes blob)37 void IostatTracker::ParseF2fsIostat(int64_t timestamp,
38 protozero::ConstBytes blob) {
39 protos::pbzero::F2fsIostatFtraceEvent::Decoder evt(blob.data, blob.size);
40 std::string tagPrefix =
41 std::string(kF2fsIostatTag) + "." + GetDeviceName(evt.dev());
42 auto push_counter = [this, timestamp, tagPrefix](const char* counter_name,
43 uint64_t value) {
44 std::string track_name = tagPrefix + "." + std::string(counter_name);
45 StringId string_id = context_->storage->InternString(track_name.c_str());
46 TrackId track = context_->track_tracker->InternGlobalCounterTrack(
47 TrackTracker::Group::kIo, string_id);
48 context_->event_tracker->PushCounter(timestamp, static_cast<double>(value),
49 track);
50 };
51
52 push_counter("write_app_total", evt.app_wio());
53 push_counter("write_app_direct", evt.app_dio());
54 push_counter("write_app_buffered", evt.app_bio());
55 push_counter("write_app_mapped", evt.app_mio());
56 push_counter("write_fs_data", evt.fs_dio());
57 push_counter("write_fs_node", evt.fs_nio());
58 push_counter("write_fs_meta", evt.fs_mio());
59 push_counter("write_gc_data", evt.fs_gc_dio());
60 push_counter("write_gc_node", evt.fs_gc_nio());
61 push_counter("write_cp_data", evt.fs_cp_dio());
62 push_counter("write_cp_node", evt.fs_cp_nio());
63 push_counter("write_cp_meta", evt.fs_cp_mio());
64 push_counter("read_app_total", evt.app_rio());
65 push_counter("read_app_direct", evt.app_drio());
66 push_counter("read_app_buffered", evt.app_brio());
67 push_counter("read_app_mapped", evt.app_mrio());
68 push_counter("read_fs_data", evt.fs_drio());
69 push_counter("read_fs_gdata", evt.fs_gdrio());
70 push_counter("read_fs_cdata", evt.fs_cdrio());
71 push_counter("read_fs_node", evt.fs_nrio());
72 push_counter("read_fs_meta", evt.fs_mrio());
73 push_counter("other_fs_discard", evt.fs_discard());
74 }
75
ParseF2fsIostatLatency(int64_t timestamp,protozero::ConstBytes blob)76 void IostatTracker::ParseF2fsIostatLatency(int64_t timestamp,
77 protozero::ConstBytes blob) {
78 protos::pbzero::F2fsIostatLatencyFtraceEvent::Decoder evt(blob.data,
79 blob.size);
80 std::string tagPrefix =
81 std::string(kF2fsIostatLatencyTag) + "." + GetDeviceName(evt.dev());
82 auto push_counter = [this, timestamp, tagPrefix](const char* counter_name,
83 uint64_t value) {
84 std::string track_name = tagPrefix + "." + std::string(counter_name);
85 StringId string_id = context_->storage->InternString(track_name.c_str());
86 TrackId track = context_->track_tracker->InternGlobalCounterTrack(
87 TrackTracker::Group::kIo, string_id);
88 context_->event_tracker->PushCounter(timestamp, static_cast<double>(value),
89 track);
90 };
91
92 push_counter("read_data_peak", evt.d_rd_peak());
93 push_counter("read_data_avg", evt.d_rd_avg());
94 push_counter("read_data_cnt", evt.d_rd_cnt());
95 push_counter("read_node_peak", evt.n_rd_peak());
96 push_counter("read_node_avg", evt.n_rd_avg());
97 push_counter("read_node_cnt", evt.n_rd_cnt());
98 push_counter("read_meta_peak", evt.m_rd_peak());
99 push_counter("read_meta_avg", evt.m_rd_avg());
100 push_counter("read_meta_cnt", evt.m_rd_cnt());
101 push_counter("write_sync_data_peak", evt.d_wr_s_peak());
102 push_counter("write_sync_data_avg", evt.d_wr_s_avg());
103 push_counter("write_sync_data_cnt", evt.d_wr_s_cnt());
104 push_counter("write_sync_node_peak", evt.n_wr_s_peak());
105 push_counter("write_sync_node_avg", evt.n_wr_s_avg());
106 push_counter("write_sync_node_cnt", evt.n_wr_s_cnt());
107 push_counter("write_sync_meta_peak", evt.m_wr_s_peak());
108 push_counter("write_sync_meta_avg", evt.m_wr_s_avg());
109 push_counter("write_sync_meta_cnt", evt.m_wr_s_cnt());
110 push_counter("write_async_data_peak", evt.d_wr_as_peak());
111 push_counter("write_async_data_avg", evt.d_wr_as_avg());
112 push_counter("write_async_data_cnt", evt.d_wr_as_cnt());
113 push_counter("write_async_node_peak", evt.n_wr_as_peak());
114 push_counter("write_async_node_avg", evt.n_wr_as_avg());
115 push_counter("write_async_node_cnt", evt.n_wr_as_cnt());
116 push_counter("write_async_meta_peak", evt.m_wr_as_peak());
117 push_counter("write_async_meta_avg", evt.m_wr_as_avg());
118 push_counter("write_async_meta_cnt", evt.m_wr_as_cnt());
119 }
120
121 } // namespace trace_processor
122 } // namespace perfetto
123