blob: 72dd5efb6625a70cb9a60ebd6bf9bfabbea7356a [file] [log] [blame]
Jon Medhurstaaf37a32013-06-11 12:10:56 +01001/**
2 * Copyright (C) ARM Limited 2012-2013. 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 */
9
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"
21
22static void marshal_summary(long long timestamp, long long uptime, const char * uname)
23{
24 unsigned long flags;
25 int cpu = 0;
26
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);
33#if GATOR_IKS_SUPPORT
34 gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
35 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
36#endif
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);
41}
42
43static bool marshal_cookie_header(const char *text)
44{
45 int cpu = get_physical_cpu();
46 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
47}
48
49static void marshal_cookie(int cookie, const char *text)
50{
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());
57}
58
59static void marshal_thread_name(int pid, char *name)
60{
61 unsigned long flags, cpu;
62 u64 time;
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);
71 }
72 buffer_check(cpu, NAME_BUF, time);
73 local_irq_restore(flags);
74}
75
76static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel)
77{
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);
86 return true;
87 }
88
89 // Check and commit; commit is set to occur once buffer is 3/4 full
90 buffer_check(cpu, BACKTRACE_BUF, time);
91
92 return false;
93}
94
95static void marshal_backtrace(unsigned long address, int cookie)
96{
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);
100}
101
102static void marshal_backtrace_footer(void)
103{
104 int cpu = get_physical_cpu();
105 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
106
107 // Check and commit; commit is set to occur once buffer is 3/4 full
108 buffer_check(cpu, BACKTRACE_BUF, gator_get_time());
109}
110
111static bool marshal_event_header(u64 time)
112{
113 unsigned long flags, cpu = get_physical_cpu();
114 bool retval = false;
115
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);
120 retval = true;
121 }
122 local_irq_restore(flags);
123
124 return retval;
125}
126
127static void marshal_event(int len, int *buffer)
128{
129 unsigned long i, flags, cpu = get_physical_cpu();
130
131 if (len <= 0)
132 return;
133
134 // length must be even since all data is a (key, value) pair
135 if (len & 0x1) {
136 pr_err("gator: invalid counter data detected and discarded");
137 return;
138 }
139
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)) {
144 break;
145 }
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]);
148 }
149 local_irq_restore(flags);
150}
151
152static void marshal_event64(int len, long long *buffer64)
153{
154 unsigned long i, flags, cpu = get_physical_cpu();
155
156 if (len <= 0)
157 return;
158
159 // length must be even since all data is a (key, value) pair
160 if (len & 0x1) {
161 pr_err("gator: invalid counter data detected and discarded");
162 return;
163 }
164
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)) {
169 break;
170 }
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]);
173 }
174 local_irq_restore(flags);
175}
176
177#if GATOR_CPU_FREQ_SUPPORT
178static void marshal_event_single(int core, int key, int value)
179{
180 unsigned long flags, cpu;
181 u64 time;
182
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);
191 }
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);
195}
196#endif
197
198static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
199{
200 unsigned long cpu = get_physical_cpu(), flags;
201 u64 time;
202
203 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
204 return;
205
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);
215 }
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);
219}
220
221static void marshal_sched_gpu_stop(int unit, int core)
222{
223 unsigned long cpu = get_physical_cpu(), flags;
224 u64 time;
225
226 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
227 return;
228
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);
236 }
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);
240}
241
242static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
243{
244 unsigned long cpu = get_physical_cpu(), flags;
245 u64 time;
246
247 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
248 return;
249
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);
259 }
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);
263}
264
265static void marshal_sched_trace_exit(int tgid, int pid)
266{
267 unsigned long cpu = get_physical_cpu(), flags;
268 u64 time;
269
270 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
271 return;
272
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);
279 }
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);
283}
284
285#if GATOR_CPU_FREQ_SUPPORT
286static void marshal_idle(int core, int state)
287{
288 unsigned long flags, cpu;
289 u64 time;
290
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);
298 }
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);
302}
303#endif
304
305static void marshal_frame(int cpu, int buftype)
306{
307 int frame;
308
309 if (!per_cpu(gator_buffer, cpu)[buftype]) {
310 return;
311 }
312
313 switch (buftype) {
314 case SUMMARY_BUF:
315 frame = FRAME_SUMMARY;
316 break;
317 case BACKTRACE_BUF:
318 frame = FRAME_BACKTRACE;
319 break;
320 case NAME_BUF:
321 frame = FRAME_NAME;
322 break;
323 case COUNTER_BUF:
324 frame = FRAME_COUNTER;
325 break;
326 case BLOCK_COUNTER_BUF:
327 frame = FRAME_BLOCK_COUNTER;
328 break;
329 case ANNOTATE_BUF:
330 frame = FRAME_ANNOTATE;
331 break;
332 case SCHED_TRACE_BUF:
333 frame = FRAME_SCHED_TRACE;
334 break;
335 case GPU_TRACE_BUF:
336 frame = FRAME_GPU_TRACE;
337 break;
338 case IDLE_BUF:
339 frame = FRAME_IDLE;
340 break;
341 default:
342 frame = -1;
343 break;
344 }
345
346 // add response type
347 if (gator_response_type > 0) {
348 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
349 }
350
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];
353
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);
357}
358
359#if defined(__arm__) || defined(__aarch64__)
360static void marshal_core_name(const int cpuid, const char *name)
361{
362 int cpu = get_physical_cpu();
363 unsigned long flags;
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);
369 }
370 buffer_check(cpu, NAME_BUF, gator_get_time());
371 local_irq_restore(flags);
372}
373#endif