• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/mali_gpu_event_tracker.h"
18 
19 #include <cstdint>
20 
21 #include "perfetto/base/logging.h"
22 #include "perfetto/ext/base/string_utils.h"
23 #include "perfetto/protozero/field.h"
24 #include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
25 #include "src/trace_processor/importers/common/slice_tracker.h"
26 #include "src/trace_processor/importers/common/track_compressor.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/importers/common/tracks_internal.h"
31 #include "src/trace_processor/storage/stats.h"
32 #include "src/trace_processor/storage/trace_storage.h"
33 #include "src/trace_processor/types/variadic.h"
34 
35 #include "protos/perfetto/trace/ftrace/mali.pbzero.h"
36 
37 namespace perfetto::trace_processor {
38 namespace {
39 
40 constexpr auto kMaliIrqBlueprint = tracks::SliceBlueprint(
41     "cpu_mali_irq",
42     tracks::DimensionBlueprints(tracks::kCpuDimensionBlueprint),
__anon3d2bbbd90202(uint32_t cpu) 43     tracks::FnNameBlueprint([](uint32_t cpu) {
44       return base::StackString<255>("Mali Irq Cpu %u", cpu);
45     }));
46 
47 }  // namespace
48 
49 namespace {
50 
51 constexpr auto kMcuStateBlueprint = tracks::SliceBlueprint("mali_mcu_state");
52 
53 }
54 
MaliGpuEventTracker(TraceProcessorContext * context)55 MaliGpuEventTracker::MaliGpuEventTracker(TraceProcessorContext* context)
56     : context_(context),
57       mali_KCPU_CQS_SET_id_(
58           context->storage->InternString("mali_KCPU_CQS_SET")),
59       mali_KCPU_CQS_WAIT_id_(
60           context->storage->InternString("mali_KCPU_CQS_WAIT")),
61       mali_KCPU_FENCE_SIGNAL_id_(
62           context->storage->InternString("mali_KCPU_FENCE_SIGNAL")),
63       mali_KCPU_FENCE_WAIT_id_(
64           context->storage->InternString("mali_KCPU_FENCE_WAIT")),
65       mali_CSF_INTERRUPT_id_(
66           context->storage->InternString("mali_CSF_INTERRUPT")),
67       mali_CSF_INTERRUPT_info_val_id_(
68           context->storage->InternString("info_val")),
69       current_mcu_state_name_(kNullStringId) {
70   using protos::pbzero::FtraceEvent;
71 
72   mcu_state_names_.fill(kNullStringId);
73   RegisterMcuState<
74       FtraceEvent::kMaliMaliPMMCUHCTLCORESDOWNSCALENOTIFYPENDFieldNumber>(
75       "HCTL_CORES_DOWN_SCALE_NOTIFY_PEND");
76   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUHCTLCORESNOTIFYPENDFieldNumber>(
77       "HCTL_CORES_NOTIFY_PEND");
78   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUHCTLCOREINACTIVEPENDFieldNumber>(
79       "HCTL_CORE_INACTIVE_PEND");
80   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUHCTLMCUONRECHECKFieldNumber>(
81       "HCTL_MCU_ON_RECHECK");
82   RegisterMcuState<
83       FtraceEvent::kMaliMaliPMMCUHCTLSHADERSCOREOFFPENDFieldNumber>(
84       "HCTL_SHADERS_CORE_OFF_PEND");
85   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUHCTLSHADERSPENDOFFFieldNumber>(
86       "HCTL_SHADERS_PEND_OFF");
87   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUHCTLSHADERSPENDONFieldNumber>(
88       "HCTL_SHADERS_PEND_ON");
89   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUHCTLSHADERSREADYOFFFieldNumber>(
90       "HCTL_SHADERS_READY_OFF");
91   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUINSLEEPFieldNumber>("IN_SLEEP");
92   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUOFFFieldNumber>("OFF");
93   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONFieldNumber>("ON");
94   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONCOREATTRUPDATEPENDFieldNumber>(
95       "ON_CORE_ATTR_UPDATE_PEND");
96   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONGLBREINITPENDFieldNumber>(
97       "ON_GLB_REINIT_PEND");
98   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONHALTFieldNumber>("ON_HALT");
99   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONHWCNTDISABLEFieldNumber>(
100       "ON_HWCNT_DISABLE");
101   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONHWCNTENABLEFieldNumber>(
102       "ON_HWCNT_ENABLE");
103   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONPENDHALTFieldNumber>(
104       "ON_PEND_HALT");
105   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONPENDSLEEPFieldNumber>(
106       "ON_PEND_SLEEP");
107   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUONSLEEPINITIATEFieldNumber>(
108       "ON_SLEEP_INITIATE");
109   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUPENDOFFFieldNumber>("PEND_OFF");
110   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUPENDONRELOADFieldNumber>(
111       "PEND_ON_RELOAD");
112   RegisterMcuState<FtraceEvent::kMaliMaliPMMCUPOWERDOWNFieldNumber>(
113       "POWER_DOWN");
114   RegisterMcuState<FtraceEvent::kMaliMaliPMMCURESETWAITFieldNumber>(
115       "RESET_WAIT");
116 }
117 
118 template <uint32_t FieldId>
RegisterMcuState(const char * state_name)119 void MaliGpuEventTracker::RegisterMcuState(const char* state_name) {
120   static_assert(FieldId >= kFirstMcuStateId && FieldId <= kLastMcuStateId);
121   mcu_state_names_[FieldId - kFirstMcuStateId] =
122       context_->storage->InternString(state_name);
123 }
124 
ParseMaliGpuIrqEvent(int64_t ts,uint32_t field_id,uint32_t cpu,protozero::ConstBytes blob)125 void MaliGpuEventTracker::ParseMaliGpuIrqEvent(int64_t ts,
126                                                uint32_t field_id,
127                                                uint32_t cpu,
128                                                protozero::ConstBytes blob) {
129   // Since these events are called from an interrupt context they cannot be
130   // associated to a single process or thread. Add to a custom Mali Irq track
131   // instead.
132   TrackId track_id = context_->track_tracker->InternTrack(
133       kMaliIrqBlueprint, tracks::Dimensions(cpu));
134 
135   switch (field_id) {
136     case protos::pbzero::FtraceEvent::kMaliMaliCSFINTERRUPTSTARTFieldNumber: {
137       ParseMaliCSFInterruptStart(ts, track_id, blob);
138       break;
139     }
140     case protos::pbzero::FtraceEvent::kMaliMaliCSFINTERRUPTENDFieldNumber: {
141       ParseMaliCSFInterruptEnd(ts, track_id, blob);
142       break;
143     }
144     default:
145       PERFETTO_DFATAL("Unexpected field id");
146       break;
147   }
148 }
149 
ParseMaliGpuMcuStateEvent(int64_t timestamp,uint32_t field_id)150 void MaliGpuEventTracker::ParseMaliGpuMcuStateEvent(int64_t timestamp,
151                                                     uint32_t field_id) {
152   if (field_id < kFirstMcuStateId || field_id > kLastMcuStateId) {
153     PERFETTO_FATAL("Mali MCU state ID out of range");
154   }
155 
156   StringId state_name = mcu_state_names_[field_id - kFirstMcuStateId];
157   if (state_name == kNullStringId) {
158     context_->storage->IncrementStats(stats::mali_unknown_mcu_state_id);
159     return;
160   }
161 
162   TrackId track_id = context_->track_tracker->InternTrack(kMcuStateBlueprint);
163   if (current_mcu_state_name_ != kNullStringId) {
164     context_->slice_tracker->End(timestamp, track_id, kNullStringId,
165                                  current_mcu_state_name_);
166   }
167 
168   context_->slice_tracker->Begin(timestamp, track_id, kNullStringId,
169                                  state_name);
170   current_mcu_state_name_ = state_name;
171 }
172 
ParseMaliCSFInterruptStart(int64_t timestamp,TrackId track_id,protozero::ConstBytes blob)173 void MaliGpuEventTracker::ParseMaliCSFInterruptStart(
174     int64_t timestamp,
175     TrackId track_id,
176     protozero::ConstBytes blob) {
177   protos::pbzero::MaliMaliCSFINTERRUPTSTARTFtraceEvent::Decoder evt(blob);
178   context_->slice_tracker->Begin(
179       timestamp, track_id, kNullStringId, mali_CSF_INTERRUPT_id_,
180       [&, this](ArgsTracker::BoundInserter* inserter) {
181         inserter->AddArg(mali_CSF_INTERRUPT_info_val_id_,
182                          Variadic::UnsignedInteger(evt.info_val()));
183       });
184 }
185 
ParseMaliCSFInterruptEnd(int64_t timestamp,TrackId track_id,protozero::ConstBytes blob)186 void MaliGpuEventTracker::ParseMaliCSFInterruptEnd(int64_t timestamp,
187                                                    TrackId track_id,
188                                                    protozero::ConstBytes blob) {
189   protos::pbzero::MaliMaliCSFINTERRUPTSTARTFtraceEvent::Decoder evt(blob);
190 
191   context_->slice_tracker->End(
192       timestamp, track_id, kNullStringId, mali_CSF_INTERRUPT_id_,
193       [&, this](ArgsTracker::BoundInserter* inserter) {
194         inserter->AddArg(mali_CSF_INTERRUPT_info_val_id_,
195                          Variadic::UnsignedInteger(evt.info_val()));
196       });
197 }
198 }  // namespace perfetto::trace_processor
199