1 /**
2 * Copyright (C) ARM Limited 2012-2014. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 */
10 #define NEWLINE_CANARY \
11 /* Unix */ \
12 "1\n" \
13 /* Windows */ \
14 "2\r\n" \
15 /* Mac OS */ \
16 "3\r" \
17 /* RISC OS */ \
18 "4\n\r" \
19 /* Add another character so the length isn't 0x0a bytes */ \
20 "5"
22 #ifdef MALI_SUPPORT
23 #include "gator_events_mali_common.h"
24 #endif
26 static void marshal_summary(long long timestamp, long long uptime, long long monotonic_delta, const char * uname)
27 {
28 unsigned long flags;
29 int cpu = 0;
31 local_irq_save(flags);
32 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_SUMMARY);
33 gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
34 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
35 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
36 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, monotonic_delta);
37 gator_buffer_write_string(cpu, SUMMARY_BUF, "uname");
38 gator_buffer_write_string(cpu, SUMMARY_BUF, uname);
39 #if GATOR_IKS_SUPPORT
40 gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
41 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
42 #endif
43 // Let Streamline know which GPU is used so that it can label the GPU Activity appropriately. This is a temporary fix, to be improved in a future release.
44 #ifdef MALI_SUPPORT
45 gator_buffer_write_string(cpu, SUMMARY_BUF, "mali_type");
46 #if (MALI_SUPPORT == MALI_4xx)
47 gator_buffer_write_string(cpu, SUMMARY_BUF, "4xx");
48 #elif (MALI_SUPPORT == MALI_T6xx)
49 gator_buffer_write_string(cpu, SUMMARY_BUF, "6xx");
50 #else
51 gator_buffer_write_string(cpu, SUMMARY_BUF, "unknown");
52 #endif
53 #endif
54 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
55 // Commit the buffer now so it can be one of the first frames read by Streamline
56 local_irq_restore(flags);
57 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
58 }
60 static bool marshal_cookie_header(const char *text)
61 {
62 int cpu = get_physical_cpu();
63 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
64 }
66 static void marshal_cookie(int cookie, const char *text)
67 {
68 int cpu = get_physical_cpu();
69 // buffer_check_space already called by marshal_cookie_header
70 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
71 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
72 gator_buffer_write_string(cpu, NAME_BUF, text);
73 buffer_check(cpu, NAME_BUF, gator_get_time());
74 }
76 static void marshal_thread_name(int pid, char *name)
77 {
78 unsigned long flags, cpu;
79 u64 time;
80 local_irq_save(flags);
81 cpu = get_physical_cpu();
82 time = gator_get_time();
83 if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
84 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
85 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
86 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
87 gator_buffer_write_string(cpu, NAME_BUF, name);
88 }
89 local_irq_restore(flags);
90 buffer_check(cpu, NAME_BUF, time);
91 }
93 static void marshal_link(int cookie, int tgid, int pid)
94 {
95 unsigned long cpu = get_physical_cpu(), flags;
96 u64 time;
98 local_irq_save(flags);
99 time = gator_get_time();
100 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
101 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_LINK);
102 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
103 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
104 gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
105 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
106 }
107 local_irq_restore(flags);
108 // Check and commit; commit is set to occur once buffer is 3/4 full
109 buffer_check(cpu, NAME_BUF, time);
110 }
112 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, u64 time)
113 {
114 int cpu = get_physical_cpu();
115 if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
116 // Check and commit; commit is set to occur once buffer is 3/4 full
117 buffer_check(cpu, BACKTRACE_BUF, time);
119 return false;
120 }
122 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
123 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
124 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
125 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
127 return true;
128 }
130 static void marshal_backtrace(unsigned long address, int cookie, int in_kernel)
131 {
132 int cpu = get_physical_cpu();
133 if (cookie == 0 && !in_kernel) {
134 cookie = UNRESOLVED_COOKIE;
135 }
136 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
137 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
138 }
140 static void marshal_backtrace_footer(u64 time)
141 {
142 int cpu = get_physical_cpu();
143 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
145 // Check and commit; commit is set to occur once buffer is 3/4 full
146 buffer_check(cpu, BACKTRACE_BUF, time);
147 }
149 static bool marshal_event_header(u64 time)
150 {
151 unsigned long flags, cpu = get_physical_cpu();
152 bool retval = false;
154 local_irq_save(flags);
155 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
156 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
157 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
158 retval = true;
159 }
160 local_irq_restore(flags);
162 return retval;
163 }
165 static void marshal_event(int len, int *buffer)
166 {
167 unsigned long i, flags, cpu = get_physical_cpu();
169 if (len <= 0)
170 return;
172 // length must be even since all data is a (key, value) pair
173 if (len & 0x1) {
174 pr_err("gator: invalid counter data detected and discarded");
175 return;
176 }
178 // events must be written in key,value pairs
179 local_irq_save(flags);
180 for (i = 0; i < len; i += 2) {
181 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
182 break;
183 }
184 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
185 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
186 }
187 local_irq_restore(flags);
188 }
190 static void marshal_event64(int len, long long *buffer64)
191 {
192 unsigned long i, flags, cpu = get_physical_cpu();
194 if (len <= 0)
195 return;
197 // length must be even since all data is a (key, value) pair
198 if (len & 0x1) {
199 pr_err("gator: invalid counter data detected and discarded");
200 return;
201 }
203 // events must be written in key,value pairs
204 local_irq_save(flags);
205 for (i = 0; i < len; i += 2) {
206 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
207 break;
208 }
209 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
210 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
211 }
212 local_irq_restore(flags);
213 }
215 #if GATOR_CPU_FREQ_SUPPORT
216 static void marshal_event_single(int core, int key, int value)
217 {
218 unsigned long flags, cpu;
219 u64 time;
221 local_irq_save(flags);
222 cpu = get_physical_cpu();
223 time = gator_get_time();
224 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
225 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
226 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
227 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
228 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
229 }
230 local_irq_restore(flags);
231 // Check and commit; commit is set to occur once buffer is 3/4 full
232 buffer_check(cpu, COUNTER_BUF, time);
233 }
234 #endif
236 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
237 {
238 unsigned long cpu = get_physical_cpu(), flags;
239 u64 time;
241 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
242 return;
244 local_irq_save(flags);
245 time = gator_get_time();
246 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
247 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
248 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
249 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
250 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
251 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
252 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
253 }
254 local_irq_restore(flags);
255 // Check and commit; commit is set to occur once buffer is 3/4 full
256 buffer_check(cpu, GPU_TRACE_BUF, time);
257 }
259 static void marshal_sched_gpu_stop(int unit, int core)
260 {
261 unsigned long cpu = get_physical_cpu(), flags;
262 u64 time;
264 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
265 return;
267 local_irq_save(flags);
268 time = gator_get_time();
269 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
270 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
271 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
272 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
273 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
274 }
275 local_irq_restore(flags);
276 // Check and commit; commit is set to occur once buffer is 3/4 full
277 buffer_check(cpu, GPU_TRACE_BUF, time);
278 }
280 static void marshal_sched_trace_start(int tgid, int pid, int cookie)
281 {
282 unsigned long cpu = get_physical_cpu(), flags;
283 u64 time;
285 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
286 return;
288 local_irq_save(flags);
289 time = gator_get_time();
290 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
291 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_START);
292 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
293 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
294 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
295 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
296 }
297 local_irq_restore(flags);
298 // Check and commit; commit is set to occur once buffer is 3/4 full
299 buffer_check(cpu, SCHED_TRACE_BUF, time);
300 }
302 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
303 {
304 unsigned long cpu = get_physical_cpu(), flags;
305 u64 time;
307 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
308 return;
310 local_irq_save(flags);
311 time = gator_get_time();
312 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
313 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
314 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
315 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
316 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
317 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
318 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
319 }
320 local_irq_restore(flags);
321 // Check and commit; commit is set to occur once buffer is 3/4 full
322 buffer_check(cpu, SCHED_TRACE_BUF, time);
323 }
325 static void marshal_sched_trace_exit(int tgid, int pid)
326 {
327 unsigned long cpu = get_physical_cpu(), flags;
328 u64 time;
330 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
331 return;
333 local_irq_save(flags);
334 time = gator_get_time();
335 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
336 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
337 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
338 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
339 }
340 local_irq_restore(flags);
341 // Check and commit; commit is set to occur once buffer is 3/4 full
342 buffer_check(cpu, SCHED_TRACE_BUF, time);
343 }
345 #if GATOR_CPU_FREQ_SUPPORT
346 static void marshal_idle(int core, int state)
347 {
348 unsigned long flags, cpu;
349 u64 time;
351 local_irq_save(flags);
352 cpu = get_physical_cpu();
353 time = gator_get_time();
354 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
355 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
356 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
357 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
358 }
359 local_irq_restore(flags);
360 // Check and commit; commit is set to occur once buffer is 3/4 full
361 buffer_check(cpu, IDLE_BUF, time);
362 }
363 #endif
365 #if defined(__arm__) || defined(__aarch64__)
366 static void marshal_core_name(const int core, const int cpuid, const char *name)
367 {
368 int cpu = get_physical_cpu();
369 unsigned long flags;
370 local_irq_save(flags);
371 if (buffer_check_space(cpu, SUMMARY_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
372 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_CORE_NAME);
373 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, core);
374 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, cpuid);
375 gator_buffer_write_string(cpu, SUMMARY_BUF, name);
376 }
377 // Commit core names now so that they can show up in live
378 local_irq_restore(flags);
379 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
380 }
381 #endif