xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/ftrace/iostat_tracker.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 
19 #include <cstdint>
20 #include <string>
21 
22 #include "perfetto/ext/base/string_utils.h"
23 #include "perfetto/ext/base/string_view.h"
24 #include "perfetto/protozero/field.h"
25 #include "protos/perfetto/trace/ftrace/f2fs.pbzero.h"
26 #include "src/trace_processor/importers/common/event_tracker.h"
27 #include "src/trace_processor/importers/common/track_tracker.h"
28 #include "src/trace_processor/importers/common/tracks.h"
29 #include "src/trace_processor/importers/common/tracks_common.h"
30 #include "src/trace_processor/storage/trace_storage.h"
31 
32 namespace perfetto::trace_processor {
33 
34 namespace {
35 
GetRawDeviceName(uint64_t dev_num)36 std::string GetRawDeviceName(uint64_t dev_num) {
37   return std::to_string((dev_num & 0xFF00) >> 8) + ":" +
38          std::to_string(dev_num & 0xFF);
39 }
40 
41 }  // namespace
42 
IostatTracker(TraceProcessorContext * context)43 IostatTracker::IostatTracker(TraceProcessorContext* context)
44     : context_(context) {}
45 
ParseF2fsIostat(int64_t timestamp,protozero::ConstBytes blob)46 void IostatTracker::ParseF2fsIostat(int64_t timestamp,
47                                     protozero::ConstBytes blob) {
48   protos::pbzero::F2fsIostatFtraceEvent::Decoder evt(blob);
49 
50   static constexpr auto kBlueprint = tracks::CounterBlueprint(
51       "f2fs_iostat", tracks::UnknownUnitBlueprint(),
52       tracks::DimensionBlueprints(
53           tracks::kLinuxDeviceDimensionBlueprint,
54           tracks::StringDimensionBlueprint("counter_key")),
55       tracks::FnNameBlueprint(
56           [](base::StringView device, base::StringView name) {
57             return base::StackString<1024>("f2fs_iostat.[%.*s].%.*s",
58                                            int(device.size()), device.data(),
59                                            int(name.size()), name.data());
60           }));
61 
62   auto push_counter = [&, this](const char* counter_name, uint64_t value) {
63     TrackId track = context_->track_tracker->InternTrack(
64         kBlueprint,
65         tracks::DimensionBlueprints(
66             base::StringView(GetRawDeviceName(evt.dev())), counter_name));
67     context_->event_tracker->PushCounter(timestamp, static_cast<double>(value),
68                                          track);
69   };
70   push_counter("write_app_total", evt.app_wio());
71   push_counter("write_app_direct", evt.app_dio());
72   push_counter("write_app_buffered", evt.app_bio());
73   push_counter("write_app_mapped", evt.app_mio());
74   push_counter("write_fs_data", evt.fs_dio());
75   push_counter("write_fs_node", evt.fs_nio());
76   push_counter("write_fs_meta", evt.fs_mio());
77   push_counter("write_gc_data", evt.fs_gc_dio());
78   push_counter("write_gc_node", evt.fs_gc_nio());
79   push_counter("write_cp_data", evt.fs_cp_dio());
80   push_counter("write_cp_node", evt.fs_cp_nio());
81   push_counter("write_cp_meta", evt.fs_cp_mio());
82   push_counter("read_app_total", evt.app_rio());
83   push_counter("read_app_direct", evt.app_drio());
84   push_counter("read_app_buffered", evt.app_brio());
85   push_counter("read_app_mapped", evt.app_mrio());
86   push_counter("read_fs_data", evt.fs_drio());
87   push_counter("read_fs_gdata", evt.fs_gdrio());
88   push_counter("read_fs_cdata", evt.fs_cdrio());
89   push_counter("read_fs_node", evt.fs_nrio());
90   push_counter("read_fs_meta", evt.fs_mrio());
91   push_counter("other_fs_discard", evt.fs_discard());
92 }
93 
ParseF2fsIostatLatency(int64_t timestamp,protozero::ConstBytes blob)94 void IostatTracker::ParseF2fsIostatLatency(int64_t timestamp,
95                                            protozero::ConstBytes blob) {
96   protos::pbzero::F2fsIostatLatencyFtraceEvent::Decoder evt(blob.data,
97                                                             blob.size);
98 
99   static constexpr auto kBlueprint = tracks::CounterBlueprint(
100       "f2fs_iostat_latency", tracks::UnknownUnitBlueprint(),
101       tracks::DimensionBlueprints(
102           tracks::kLinuxDeviceDimensionBlueprint,
103           tracks::StringDimensionBlueprint("counter_key")),
104       tracks::FnNameBlueprint(
105           [](base::StringView device, base::StringView name) {
106             return base::StackString<1024>("f2fs_iostat_latency.[%.*s].%.*s",
107                                            int(device.size()), device.data(),
108                                            int(name.size()), name.data());
109           }));
110 
111   auto push_counter = [&, this](const char* counter_name, uint64_t value) {
112     TrackId track = context_->track_tracker->InternTrack(
113         kBlueprint,
114         tracks::DimensionBlueprints(
115             base::StringView(GetRawDeviceName(evt.dev())), counter_name));
116     context_->event_tracker->PushCounter(timestamp, static_cast<double>(value),
117                                          track);
118   };
119   push_counter("read_data_peak", evt.d_rd_peak());
120   push_counter("read_data_avg", evt.d_rd_avg());
121   push_counter("read_data_cnt", evt.d_rd_cnt());
122   push_counter("read_node_peak", evt.n_rd_peak());
123   push_counter("read_node_avg", evt.n_rd_avg());
124   push_counter("read_node_cnt", evt.n_rd_cnt());
125   push_counter("read_meta_peak", evt.m_rd_peak());
126   push_counter("read_meta_avg", evt.m_rd_avg());
127   push_counter("read_meta_cnt", evt.m_rd_cnt());
128   push_counter("write_sync_data_peak", evt.d_wr_s_peak());
129   push_counter("write_sync_data_avg", evt.d_wr_s_avg());
130   push_counter("write_sync_data_cnt", evt.d_wr_s_cnt());
131   push_counter("write_sync_node_peak", evt.n_wr_s_peak());
132   push_counter("write_sync_node_avg", evt.n_wr_s_avg());
133   push_counter("write_sync_node_cnt", evt.n_wr_s_cnt());
134   push_counter("write_sync_meta_peak", evt.m_wr_s_peak());
135   push_counter("write_sync_meta_avg", evt.m_wr_s_avg());
136   push_counter("write_sync_meta_cnt", evt.m_wr_s_cnt());
137   push_counter("write_async_data_peak", evt.d_wr_as_peak());
138   push_counter("write_async_data_avg", evt.d_wr_as_avg());
139   push_counter("write_async_data_cnt", evt.d_wr_as_cnt());
140   push_counter("write_async_node_peak", evt.n_wr_as_peak());
141   push_counter("write_async_node_avg", evt.n_wr_as_avg());
142   push_counter("write_async_node_cnt", evt.n_wr_as_cnt());
143   push_counter("write_async_meta_peak", evt.m_wr_as_peak());
144   push_counter("write_async_meta_avg", evt.m_wr_as_avg());
145   push_counter("write_async_meta_cnt", evt.m_wr_as_cnt());
146 }
147 
148 }  // namespace perfetto::trace_processor
149