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 bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel, u64 time)
94 int cpu = get_physical_cpu();
95 if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
96 // Check and commit; commit is set to occur once buffer is 3/4 full
97 buffer_check(cpu, BACKTRACE_BUF, time);
102 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
103 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
104 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
105 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
106 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
111 static void marshal_backtrace(unsigned long address, int cookie)
113 int cpu = get_physical_cpu();
114 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
115 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
118 static void marshal_backtrace_footer(u64 time)
120 int cpu = get_physical_cpu();
121 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
123 // Check and commit; commit is set to occur once buffer is 3/4 full
124 buffer_check(cpu, BACKTRACE_BUF, time);
127 static bool marshal_event_header(u64 time)
129 unsigned long flags, cpu = get_physical_cpu();
132 local_irq_save(flags);
133 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
134 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
135 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
138 local_irq_restore(flags);
143 static void marshal_event(int len, int *buffer)
145 unsigned long i, flags, cpu = get_physical_cpu();
150 // length must be even since all data is a (key, value) pair
152 pr_err("gator: invalid counter data detected and discarded");
156 // events must be written in key,value pairs
157 local_irq_save(flags);
158 for (i = 0; i < len; i += 2) {
159 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
162 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
163 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
165 local_irq_restore(flags);
168 static void marshal_event64(int len, long long *buffer64)
170 unsigned long i, flags, cpu = get_physical_cpu();
175 // length must be even since all data is a (key, value) pair
177 pr_err("gator: invalid counter data detected and discarded");
181 // events must be written in key,value pairs
182 local_irq_save(flags);
183 for (i = 0; i < len; i += 2) {
184 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
187 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
188 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
190 local_irq_restore(flags);
193 #if GATOR_CPU_FREQ_SUPPORT
194 static void marshal_event_single(int core, int key, int value)
196 unsigned long flags, cpu;
199 local_irq_save(flags);
200 cpu = get_physical_cpu();
201 time = gator_get_time();
202 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
203 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
204 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
205 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
206 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
208 // Check and commit; commit is set to occur once buffer is 3/4 full
209 buffer_check(cpu, COUNTER_BUF, time);
210 local_irq_restore(flags);
214 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
216 unsigned long cpu = get_physical_cpu(), flags;
219 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
222 local_irq_save(flags);
223 time = gator_get_time();
224 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
225 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
226 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
227 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
228 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
229 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
230 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
232 // Check and commit; commit is set to occur once buffer is 3/4 full
233 buffer_check(cpu, GPU_TRACE_BUF, time);
234 local_irq_restore(flags);
237 static void marshal_sched_gpu_stop(int unit, int core)
239 unsigned long cpu = get_physical_cpu(), flags;
242 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
245 local_irq_save(flags);
246 time = gator_get_time();
247 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
248 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
249 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
250 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
251 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
253 // Check and commit; commit is set to occur once buffer is 3/4 full
254 buffer_check(cpu, GPU_TRACE_BUF, time);
255 local_irq_restore(flags);
258 static void marshal_sched_trace_start(int tgid, int pid, int cookie)
260 unsigned long cpu = get_physical_cpu(), flags;
263 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
266 local_irq_save(flags);
267 time = gator_get_time();
268 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
269 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_START);
270 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
271 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
272 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
273 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
275 // Check and commit; commit is set to occur once buffer is 3/4 full
276 buffer_check(cpu, SCHED_TRACE_BUF, time);
277 local_irq_restore(flags);
280 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
282 unsigned long cpu = get_physical_cpu(), flags;
285 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
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_SWITCH);
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 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
298 // Check and commit; commit is set to occur once buffer is 3/4 full
299 buffer_check(cpu, SCHED_TRACE_BUF, time);
300 local_irq_restore(flags);
303 static void marshal_sched_trace_exit(int tgid, int pid)
305 unsigned long cpu = get_physical_cpu(), flags;
308 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
311 local_irq_save(flags);
312 time = gator_get_time();
313 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
314 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
315 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
316 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
318 // Check and commit; commit is set to occur once buffer is 3/4 full
319 buffer_check(cpu, SCHED_TRACE_BUF, time);
320 local_irq_restore(flags);
323 #if GATOR_CPU_FREQ_SUPPORT
324 static void marshal_idle(int core, int state)
326 unsigned long flags, cpu;
329 local_irq_save(flags);
330 cpu = get_physical_cpu();
331 time = gator_get_time();
332 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
333 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
334 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
335 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
337 // Check and commit; commit is set to occur once buffer is 3/4 full
338 buffer_check(cpu, IDLE_BUF, time);
339 local_irq_restore(flags);
343 static void marshal_frame(int cpu, int buftype)
347 if (!per_cpu(gator_buffer, cpu)[buftype]) {
353 frame = FRAME_SUMMARY;
356 frame = FRAME_BACKTRACE;
362 frame = FRAME_COUNTER;
364 case BLOCK_COUNTER_BUF:
365 frame = FRAME_BLOCK_COUNTER;
368 frame = FRAME_ANNOTATE;
370 case SCHED_TRACE_BUF:
371 frame = FRAME_SCHED_TRACE;
374 frame = FRAME_GPU_TRACE;
385 if (gator_response_type > 0) {
386 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
389 // leave space for 4-byte unpacked length
390 per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];
392 // add frame type and core number
393 gator_buffer_write_packed_int(cpu, buftype, frame);
394 gator_buffer_write_packed_int(cpu, buftype, cpu);
397 #if defined(__arm__) || defined(__aarch64__)
398 static void marshal_core_name(const int core, const int cpuid, const char *name)
400 int cpu = get_physical_cpu();
402 local_irq_save(flags);
403 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
404 gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
405 gator_buffer_write_packed_int(cpu, NAME_BUF, core);
406 gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid);
407 gator_buffer_write_string(cpu, NAME_BUF, name);
409 // Commit core names now so that they can show up in live
410 gator_commit_buffer(cpu, NAME_BUF, gator_get_time());
411 local_irq_restore(flags);