2 * Copyright (C) ARM Limited 2012-2013. All rights reserved.
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.
10 #define NEWLINE_CANARY \
19 /* Add another character so the length isn't 0x0a bytes */ \
23 #include "gator_events_mali_common.h"
26 static void marshal_summary(long long timestamp, long long uptime, long long monotonic_delta, const char * uname)
31 local_irq_save(flags);
32 gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
33 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
34 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
35 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, monotonic_delta);
36 gator_buffer_write_string(cpu, SUMMARY_BUF, "uname");
37 gator_buffer_write_string(cpu, SUMMARY_BUF, uname);
39 gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
40 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
42 // 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 gator_buffer_write_string(cpu, SUMMARY_BUF, "mali_type");
45 #if (MALI_SUPPORT == MALI_4xx)
46 gator_buffer_write_string(cpu, SUMMARY_BUF, "4xx");
47 #elif (MALI_SUPPORT == MALI_T6xx)
48 gator_buffer_write_string(cpu, SUMMARY_BUF, "6xx");
50 gator_buffer_write_string(cpu, SUMMARY_BUF, "unknown");
53 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
54 // Commit the buffer now so it can be one of the first frames read by Streamline
55 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
56 local_irq_restore(flags);
59 static bool marshal_cookie_header(const char *text)
61 int cpu = get_physical_cpu();
62 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
65 static void marshal_cookie(int cookie, const char *text)
67 int cpu = get_physical_cpu();
68 // buffer_check_space already called by marshal_cookie_header
69 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
70 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
71 gator_buffer_write_string(cpu, NAME_BUF, text);
72 buffer_check(cpu, NAME_BUF, gator_get_time());
75 static void marshal_thread_name(int pid, char *name)
77 unsigned long flags, cpu;
79 local_irq_save(flags);
80 cpu = get_physical_cpu();
81 time = gator_get_time();
82 if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
83 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
84 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
85 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
86 gator_buffer_write_string(cpu, NAME_BUF, name);
88 buffer_check(cpu, NAME_BUF, time);
89 local_irq_restore(flags);
92 static void marshal_link(int cookie, int tgid, int pid)
94 unsigned long cpu = get_physical_cpu(), flags;
97 local_irq_save(flags);
98 time = gator_get_time();
99 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
100 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_LINK);
101 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
102 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
103 gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
104 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
106 // Check and commit; commit is set to occur once buffer is 3/4 full
107 buffer_check(cpu, NAME_BUF, time);
108 local_irq_restore(flags);
111 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel, u64 time)
113 int cpu = get_physical_cpu();
114 if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
115 // Check and commit; commit is set to occur once buffer is 3/4 full
116 buffer_check(cpu, BACKTRACE_BUF, time);
121 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
122 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
123 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
124 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
125 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
130 static void marshal_backtrace(unsigned long address, int cookie)
132 int cpu = get_physical_cpu();
133 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
134 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
137 static void marshal_backtrace_footer(u64 time)
139 int cpu = get_physical_cpu();
140 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
142 // Check and commit; commit is set to occur once buffer is 3/4 full
143 buffer_check(cpu, BACKTRACE_BUF, time);
146 static bool marshal_event_header(u64 time)
148 unsigned long flags, cpu = get_physical_cpu();
151 local_irq_save(flags);
152 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
153 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
154 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
157 local_irq_restore(flags);
162 static void marshal_event(int len, int *buffer)
164 unsigned long i, flags, cpu = get_physical_cpu();
169 // length must be even since all data is a (key, value) pair
171 pr_err("gator: invalid counter data detected and discarded");
175 // events must be written in key,value pairs
176 local_irq_save(flags);
177 for (i = 0; i < len; i += 2) {
178 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
181 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
182 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
184 local_irq_restore(flags);
187 static void marshal_event64(int len, long long *buffer64)
189 unsigned long i, flags, cpu = get_physical_cpu();
194 // length must be even since all data is a (key, value) pair
196 pr_err("gator: invalid counter data detected and discarded");
200 // events must be written in key,value pairs
201 local_irq_save(flags);
202 for (i = 0; i < len; i += 2) {
203 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
206 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
207 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
209 local_irq_restore(flags);
212 #if GATOR_CPU_FREQ_SUPPORT
213 static void marshal_event_single(int core, int key, int value)
215 unsigned long flags, cpu;
218 local_irq_save(flags);
219 cpu = get_physical_cpu();
220 time = gator_get_time();
221 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
222 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
223 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
224 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
225 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
227 // Check and commit; commit is set to occur once buffer is 3/4 full
228 buffer_check(cpu, COUNTER_BUF, time);
229 local_irq_restore(flags);
233 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
235 unsigned long cpu = get_physical_cpu(), flags;
238 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
241 local_irq_save(flags);
242 time = gator_get_time();
243 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
244 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
245 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
246 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
247 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
248 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
249 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
251 // Check and commit; commit is set to occur once buffer is 3/4 full
252 buffer_check(cpu, GPU_TRACE_BUF, time);
253 local_irq_restore(flags);
256 static void marshal_sched_gpu_stop(int unit, int core)
258 unsigned long cpu = get_physical_cpu(), flags;
261 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
264 local_irq_save(flags);
265 time = gator_get_time();
266 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
267 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
268 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
269 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
270 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
272 // Check and commit; commit is set to occur once buffer is 3/4 full
273 buffer_check(cpu, GPU_TRACE_BUF, time);
274 local_irq_restore(flags);
277 static void marshal_sched_trace_start(int tgid, int pid, int cookie)
279 unsigned long cpu = get_physical_cpu(), flags;
282 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
285 local_irq_save(flags);
286 time = gator_get_time();
287 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
288 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_START);
289 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
290 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
291 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
292 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
294 // Check and commit; commit is set to occur once buffer is 3/4 full
295 buffer_check(cpu, SCHED_TRACE_BUF, time);
296 local_irq_restore(flags);
299 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
301 unsigned long cpu = get_physical_cpu(), flags;
304 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
307 local_irq_save(flags);
308 time = gator_get_time();
309 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
310 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
311 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
312 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
313 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
314 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
315 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
317 // Check and commit; commit is set to occur once buffer is 3/4 full
318 buffer_check(cpu, SCHED_TRACE_BUF, time);
319 local_irq_restore(flags);
322 static void marshal_sched_trace_exit(int tgid, int pid)
324 unsigned long cpu = get_physical_cpu(), flags;
327 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
330 local_irq_save(flags);
331 time = gator_get_time();
332 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
333 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
334 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
335 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
337 // Check and commit; commit is set to occur once buffer is 3/4 full
338 buffer_check(cpu, SCHED_TRACE_BUF, time);
339 local_irq_restore(flags);
342 #if GATOR_CPU_FREQ_SUPPORT
343 static void marshal_idle(int core, int state)
345 unsigned long flags, cpu;
348 local_irq_save(flags);
349 cpu = get_physical_cpu();
350 time = gator_get_time();
351 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
352 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
353 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
354 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
356 // Check and commit; commit is set to occur once buffer is 3/4 full
357 buffer_check(cpu, IDLE_BUF, time);
358 local_irq_restore(flags);
362 static void marshal_frame(int cpu, int buftype)
366 if (!per_cpu(gator_buffer, cpu)[buftype]) {
372 frame = FRAME_SUMMARY;
375 frame = FRAME_BACKTRACE;
381 frame = FRAME_COUNTER;
383 case BLOCK_COUNTER_BUF:
384 frame = FRAME_BLOCK_COUNTER;
387 frame = FRAME_ANNOTATE;
389 case SCHED_TRACE_BUF:
390 frame = FRAME_SCHED_TRACE;
393 frame = FRAME_GPU_TRACE;
404 if (gator_response_type > 0) {
405 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
408 // leave space for 4-byte unpacked length
409 per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];
411 // add frame type and core number
412 gator_buffer_write_packed_int(cpu, buftype, frame);
413 gator_buffer_write_packed_int(cpu, buftype, cpu);
416 #if defined(__arm__) || defined(__aarch64__)
417 static void marshal_core_name(const int core, const int cpuid, const char *name)
419 int cpu = get_physical_cpu();
421 local_irq_save(flags);
422 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
423 gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
424 gator_buffer_write_packed_int(cpu, NAME_BUF, core);
425 gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid);
426 gator_buffer_write_string(cpu, NAME_BUF, name);
428 // Commit core names now so that they can show up in live
429 gator_commit_buffer(cpu, NAME_BUF, gator_get_time());
430 local_irq_restore(flags);