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 "perfetto/ext/base/string_utils.h"
20 #include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
21 #include "protos/perfetto/trace/ftrace/mali.pbzero.h"
22 #include "src/trace_processor/importers/common/async_track_set_tracker.h"
23 #include "src/trace_processor/importers/common/process_tracker.h"
24 #include "src/trace_processor/importers/common/slice_tracker.h"
25 #include "src/trace_processor/importers/common/track_tracker.h"
26
27 namespace perfetto {
28 namespace trace_processor {
29
MaliGpuEventTracker(TraceProcessorContext * context)30 MaliGpuEventTracker::MaliGpuEventTracker(TraceProcessorContext* context)
31 : context_(context),
32 mali_KCPU_CQS_SET_id_(
33 context->storage->InternString("mali_KCPU_CQS_SET")),
34 mali_KCPU_CQS_WAIT_id_(
35 context->storage->InternString("mali_KCPU_CQS_WAIT")),
36 mali_KCPU_FENCE_SIGNAL_id_(
37 context->storage->InternString("mali_KCPU_FENCE_SIGNAL")),
38 mali_KCPU_FENCE_WAIT_id_(
39 context->storage->InternString("mali_KCPU_FENCE_WAIT")),
40 mali_CSF_INTERRUPT_id_(
41 context->storage->InternString("mali_CSF_INTERRUPT")),
42 mali_CSF_INTERRUPT_info_val_id_(
43 context->storage->InternString("info_val")) {}
44
ParseMaliGpuEvent(int64_t ts,int32_t field_id,uint32_t pid)45 void MaliGpuEventTracker::ParseMaliGpuEvent(int64_t ts,
46 int32_t field_id,
47 uint32_t pid) {
48 using protos::pbzero::FtraceEvent;
49
50 UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
51 TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
52
53 switch (field_id) {
54 case FtraceEvent::kMaliMaliKCPUCQSSETFieldNumber: {
55 ParseMaliKcpuCqsSet(ts, track_id);
56 break;
57 }
58 case FtraceEvent::kMaliMaliKCPUCQSWAITSTARTFieldNumber: {
59 ParseMaliKcpuCqsWaitStart(ts, track_id);
60 break;
61 }
62 case FtraceEvent::kMaliMaliKCPUCQSWAITENDFieldNumber: {
63 ParseMaliKcpuCqsWaitEnd(ts, track_id);
64 break;
65 }
66 case FtraceEvent::kMaliMaliKCPUFENCESIGNALFieldNumber: {
67 ParseMaliKcpuFenceSignal(ts, track_id);
68 break;
69 }
70 case FtraceEvent::kMaliMaliKCPUFENCEWAITSTARTFieldNumber: {
71 ParseMaliKcpuFenceWaitStart(ts, track_id);
72 break;
73 }
74 case FtraceEvent::kMaliMaliKCPUFENCEWAITENDFieldNumber: {
75 ParseMaliKcpuFenceWaitEnd(ts, track_id);
76 break;
77 }
78 default:
79 PERFETTO_DFATAL("Unexpected field id");
80 break;
81 }
82 }
83
ParseMaliGpuIrqEvent(int64_t ts,int32_t field_id,uint32_t cpu,protozero::ConstBytes blob)84 void MaliGpuEventTracker::ParseMaliGpuIrqEvent(int64_t ts,
85 int32_t field_id,
86 uint32_t cpu,
87 protozero::ConstBytes blob) {
88 using protos::pbzero::FtraceEvent;
89
90 // Since these events are called from an interrupt context they cannot be
91 // associated to a single process or thread. Add to a custom Mali Irq track
92 // instead.
93 base::StackString<255> track_name("Mali Irq Cpu %d", cpu);
94 StringId track_name_id =
95 context_->storage->InternString(track_name.string_view());
96 TrackId track_id =
97 context_->track_tracker->InternCpuTrack(track_name_id, cpu);
98
99 switch (field_id) {
100 case FtraceEvent::kMaliMaliCSFINTERRUPTSTARTFieldNumber: {
101 ParseMaliCSFInterruptStart(ts, track_id, blob);
102 break;
103 }
104 case FtraceEvent::kMaliMaliCSFINTERRUPTENDFieldNumber: {
105 ParseMaliCSFInterruptEnd(ts, track_id, blob);
106 break;
107 }
108 default:
109 PERFETTO_DFATAL("Unexpected field id");
110 break;
111 }
112 }
113
ParseMaliKcpuCqsSet(int64_t timestamp,TrackId track_id)114 void MaliGpuEventTracker::ParseMaliKcpuCqsSet(int64_t timestamp,
115 TrackId track_id) {
116 context_->slice_tracker->Scoped(timestamp, track_id, kNullStringId,
117 mali_KCPU_CQS_SET_id_, 0);
118 }
119
ParseMaliKcpuCqsWaitStart(int64_t timestamp,TrackId track_id)120 void MaliGpuEventTracker::ParseMaliKcpuCqsWaitStart(int64_t timestamp,
121 TrackId track_id) {
122 context_->slice_tracker->Begin(timestamp, track_id, kNullStringId,
123 mali_KCPU_CQS_WAIT_id_);
124 }
125
ParseMaliKcpuCqsWaitEnd(int64_t timestamp,TrackId track_id)126 void MaliGpuEventTracker::ParseMaliKcpuCqsWaitEnd(int64_t timestamp,
127 TrackId track_id) {
128 context_->slice_tracker->End(timestamp, track_id, kNullStringId,
129 mali_KCPU_CQS_WAIT_id_);
130 }
131
ParseMaliKcpuFenceSignal(int64_t timestamp,TrackId track_id)132 void MaliGpuEventTracker::ParseMaliKcpuFenceSignal(int64_t timestamp,
133 TrackId track_id) {
134 context_->slice_tracker->Scoped(timestamp, track_id, kNullStringId,
135 mali_KCPU_FENCE_SIGNAL_id_, 0);
136 }
137
ParseMaliKcpuFenceWaitStart(int64_t timestamp,TrackId track_id)138 void MaliGpuEventTracker::ParseMaliKcpuFenceWaitStart(int64_t timestamp,
139 TrackId track_id) {
140 context_->slice_tracker->Begin(timestamp, track_id, kNullStringId,
141 mali_KCPU_FENCE_WAIT_id_);
142 }
143
ParseMaliKcpuFenceWaitEnd(int64_t timestamp,TrackId track_id)144 void MaliGpuEventTracker::ParseMaliKcpuFenceWaitEnd(int64_t timestamp,
145 TrackId track_id) {
146 context_->slice_tracker->End(timestamp, track_id, kNullStringId,
147 mali_KCPU_FENCE_WAIT_id_);
148 }
149
ParseMaliCSFInterruptStart(int64_t timestamp,TrackId track_id,protozero::ConstBytes blob)150 void MaliGpuEventTracker::ParseMaliCSFInterruptStart(
151 int64_t timestamp,
152 TrackId track_id,
153 protozero::ConstBytes blob) {
154 protos::pbzero::MaliMaliCSFINTERRUPTSTARTFtraceEvent::Decoder evt(blob.data,
155 blob.size);
156 auto args_inserter = [this, &evt](ArgsTracker::BoundInserter* inserter) {
157 inserter->AddArg(mali_CSF_INTERRUPT_info_val_id_,
158 Variadic::UnsignedInteger(evt.info_val()));
159 };
160
161 context_->slice_tracker->Begin(timestamp, track_id, kNullStringId,
162 mali_CSF_INTERRUPT_id_, args_inserter);
163 }
164
ParseMaliCSFInterruptEnd(int64_t timestamp,TrackId track_id,protozero::ConstBytes blob)165 void MaliGpuEventTracker::ParseMaliCSFInterruptEnd(int64_t timestamp,
166 TrackId track_id,
167 protozero::ConstBytes blob) {
168 protos::pbzero::MaliMaliCSFINTERRUPTSTARTFtraceEvent::Decoder evt(blob.data,
169 blob.size);
170 auto args_inserter = [this, &evt](ArgsTracker::BoundInserter* inserter) {
171 inserter->AddArg(mali_CSF_INTERRUPT_info_val_id_,
172 Variadic::UnsignedInteger(evt.info_val()));
173 };
174
175 context_->slice_tracker->End(timestamp, track_id, kNullStringId,
176 mali_CSF_INTERRUPT_id_, args_inserter);
177 }
178 } // namespace trace_processor
179 } // namespace perfetto
180