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 */ \
22 static void marshal_summary(long long timestamp, long long uptime, const char * uname)
27 local_irq_save(flags);
28 gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
29 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
30 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
31 gator_buffer_write_string(cpu, SUMMARY_BUF, "uname");
32 gator_buffer_write_string(cpu, SUMMARY_BUF, uname);
34 gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
35 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
37 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
38 // Commit the buffer now so it can be one of the first frames read by Streamline
39 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
40 local_irq_restore(flags);
43 static bool marshal_cookie_header(const char *text)
45 int cpu = get_physical_cpu();
46 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
49 static void marshal_cookie(int cookie, const char *text)
51 int cpu = get_physical_cpu();
52 // buffer_check_space already called by marshal_cookie_header
53 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
54 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
55 gator_buffer_write_string(cpu, NAME_BUF, text);
56 buffer_check(cpu, NAME_BUF, gator_get_time());
59 static void marshal_thread_name(int pid, char *name)
61 unsigned long flags, cpu;
63 local_irq_save(flags);
64 cpu = get_physical_cpu();
65 time = gator_get_time();
66 if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
67 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
68 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
69 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
70 gator_buffer_write_string(cpu, NAME_BUF, name);
72 buffer_check(cpu, NAME_BUF, time);
73 local_irq_restore(flags);
76 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel)
78 int cpu = get_physical_cpu();
79 u64 time = gator_get_time();
80 if (buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
81 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
82 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
83 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
84 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
85 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
89 // Check and commit; commit is set to occur once buffer is 3/4 full
90 buffer_check(cpu, BACKTRACE_BUF, time);
95 static void marshal_backtrace(unsigned long address, int cookie)
97 int cpu = get_physical_cpu();
98 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
99 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
102 static void marshal_backtrace_footer(void)
104 int cpu = get_physical_cpu();
105 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
107 // Check and commit; commit is set to occur once buffer is 3/4 full
108 buffer_check(cpu, BACKTRACE_BUF, gator_get_time());
111 static bool marshal_event_header(u64 time)
113 unsigned long flags, cpu = get_physical_cpu();
116 local_irq_save(flags);
117 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
118 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
119 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
122 local_irq_restore(flags);
127 static void marshal_event(int len, int *buffer)
129 unsigned long i, flags, cpu = get_physical_cpu();
134 // length must be even since all data is a (key, value) pair
136 pr_err("gator: invalid counter data detected and discarded");
140 // events must be written in key,value pairs
141 local_irq_save(flags);
142 for (i = 0; i < len; i += 2) {
143 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
146 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
147 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
149 local_irq_restore(flags);
152 static void marshal_event64(int len, long long *buffer64)
154 unsigned long i, flags, cpu = get_physical_cpu();
159 // length must be even since all data is a (key, value) pair
161 pr_err("gator: invalid counter data detected and discarded");
165 // events must be written in key,value pairs
166 local_irq_save(flags);
167 for (i = 0; i < len; i += 2) {
168 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
171 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
172 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
174 local_irq_restore(flags);
177 #if GATOR_CPU_FREQ_SUPPORT
178 static void marshal_event_single(int core, int key, int value)
180 unsigned long flags, cpu;
183 local_irq_save(flags);
184 cpu = get_physical_cpu();
185 time = gator_get_time();
186 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
187 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
188 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
189 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
190 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
192 // Check and commit; commit is set to occur once buffer is 3/4 full
193 buffer_check(cpu, COUNTER_BUF, time);
194 local_irq_restore(flags);
198 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
200 unsigned long cpu = get_physical_cpu(), flags;
203 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
206 local_irq_save(flags);
207 time = gator_get_time();
208 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
209 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
210 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
211 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
212 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
213 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
214 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
216 // Check and commit; commit is set to occur once buffer is 3/4 full
217 buffer_check(cpu, GPU_TRACE_BUF, time);
218 local_irq_restore(flags);
221 static void marshal_sched_gpu_stop(int unit, int core)
223 unsigned long cpu = get_physical_cpu(), flags;
226 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
229 local_irq_save(flags);
230 time = gator_get_time();
231 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
232 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
233 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
234 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
235 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
237 // Check and commit; commit is set to occur once buffer is 3/4 full
238 buffer_check(cpu, GPU_TRACE_BUF, time);
239 local_irq_restore(flags);
242 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
244 unsigned long cpu = get_physical_cpu(), flags;
247 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
250 local_irq_save(flags);
251 time = gator_get_time();
252 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
253 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
254 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
255 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
256 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
257 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
258 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
260 // Check and commit; commit is set to occur once buffer is 3/4 full
261 buffer_check(cpu, SCHED_TRACE_BUF, time);
262 local_irq_restore(flags);
265 static void marshal_sched_trace_exit(int tgid, int pid)
267 unsigned long cpu = get_physical_cpu(), flags;
270 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
273 local_irq_save(flags);
274 time = gator_get_time();
275 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
276 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
277 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
278 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
280 // Check and commit; commit is set to occur once buffer is 3/4 full
281 buffer_check(cpu, SCHED_TRACE_BUF, time);
282 local_irq_restore(flags);
285 #if GATOR_CPU_FREQ_SUPPORT
286 static void marshal_idle(int core, int state)
288 unsigned long flags, cpu;
291 local_irq_save(flags);
292 cpu = get_physical_cpu();
293 time = gator_get_time();
294 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
295 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
296 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
297 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
299 // Check and commit; commit is set to occur once buffer is 3/4 full
300 buffer_check(cpu, IDLE_BUF, time);
301 local_irq_restore(flags);
305 static void marshal_frame(int cpu, int buftype)
309 if (!per_cpu(gator_buffer, cpu)[buftype]) {
315 frame = FRAME_SUMMARY;
318 frame = FRAME_BACKTRACE;
324 frame = FRAME_COUNTER;
326 case BLOCK_COUNTER_BUF:
327 frame = FRAME_BLOCK_COUNTER;
330 frame = FRAME_ANNOTATE;
332 case SCHED_TRACE_BUF:
333 frame = FRAME_SCHED_TRACE;
336 frame = FRAME_GPU_TRACE;
347 if (gator_response_type > 0) {
348 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
351 // leave space for 4-byte unpacked length
352 per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];
354 // add frame type and core number
355 gator_buffer_write_packed_int(cpu, buftype, frame);
356 gator_buffer_write_packed_int(cpu, buftype, cpu);
359 #if defined(__arm__) || defined(__aarch64__)
360 static void marshal_core_name(const int cpuid, const char *name)
362 int cpu = get_physical_cpu();
364 local_irq_save(flags);
365 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
366 gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
367 gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid);
368 gator_buffer_write_string(cpu, NAME_BUF, name);
370 buffer_check(cpu, NAME_BUF, gator_get_time());
371 local_irq_restore(flags);