627b441eb44ec2088308cde4f2eafc9eeceaa15b
1 /**
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 */
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 static void marshal_summary(long long timestamp, long long uptime, const char * uname)
23 {
24 unsigned long flags;
25 int cpu = 0;
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 // Commit the buffer now so it can be one of the first frames read by Streamline
33 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
34 local_irq_restore(flags);
35 }
37 static bool marshal_cookie_header(const char *text)
38 {
39 int cpu = get_physical_cpu();
40 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
41 }
43 static void marshal_cookie(int cookie, const char *text)
44 {
45 int cpu = get_physical_cpu();
46 // buffer_check_space already called by marshal_cookie_header
47 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
48 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
49 gator_buffer_write_string(cpu, NAME_BUF, text);
50 buffer_check(cpu, NAME_BUF, gator_get_time());
51 }
53 static void marshal_thread_name(int pid, char *name)
54 {
55 unsigned long flags, cpu;
56 u64 time;
57 local_irq_save(flags);
58 cpu = get_physical_cpu();
59 time = gator_get_time();
60 if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
61 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
62 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
63 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
64 gator_buffer_write_string(cpu, NAME_BUF, name);
65 }
66 buffer_check(cpu, NAME_BUF, time);
67 local_irq_restore(flags);
68 }
70 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel)
71 {
72 int cpu = get_physical_cpu();
73 u64 time = gator_get_time();
74 if (buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
75 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
76 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
77 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
78 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
79 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
80 return true;
81 }
83 // Check and commit; commit is set to occur once buffer is 3/4 full
84 buffer_check(cpu, BACKTRACE_BUF, time);
86 return false;
87 }
89 static void marshal_backtrace(unsigned long address, int cookie)
90 {
91 int cpu = get_physical_cpu();
92 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
93 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
94 }
96 static void marshal_backtrace_footer(void)
97 {
98 int cpu = get_physical_cpu();
99 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
101 // Check and commit; commit is set to occur once buffer is 3/4 full
102 buffer_check(cpu, BACKTRACE_BUF, gator_get_time());
103 }
105 static bool marshal_event_header(void)
106 {
107 unsigned long flags, cpu = get_physical_cpu();
108 bool retval = false;
110 local_irq_save(flags);
111 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
112 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
113 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, gator_get_time());
114 retval = true;
115 }
116 local_irq_restore(flags);
118 return retval;
119 }
121 static void marshal_event(int len, int *buffer)
122 {
123 unsigned long i, flags, cpu = get_physical_cpu();
125 if (len <= 0)
126 return;
128 // length must be even since all data is a (key, value) pair
129 if (len & 0x1) {
130 pr_err("gator: invalid counter data detected and discarded");
131 return;
132 }
134 // events must be written in key,value pairs
135 local_irq_save(flags);
136 for (i = 0; i < len; i += 2) {
137 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
138 break;
139 }
140 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
141 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
142 }
143 local_irq_restore(flags);
144 }
146 static void marshal_event64(int len, long long *buffer64)
147 {
148 unsigned long i, flags, cpu = get_physical_cpu();
150 if (len <= 0)
151 return;
153 // length must be even since all data is a (key, value) pair
154 if (len & 0x1) {
155 pr_err("gator: invalid counter data detected and discarded");
156 return;
157 }
159 // events must be written in key,value pairs
160 local_irq_save(flags);
161 for (i = 0; i < len; i += 2) {
162 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
163 break;
164 }
165 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
166 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
167 }
168 local_irq_restore(flags);
169 }
171 #if GATOR_CPU_FREQ_SUPPORT
172 static void marshal_event_single(int core, int key, int value)
173 {
174 unsigned long flags, cpu;
175 u64 time;
177 local_irq_save(flags);
178 cpu = get_physical_cpu();
179 time = gator_get_time();
180 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
181 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
182 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
183 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
184 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
185 }
186 // Check and commit; commit is set to occur once buffer is 3/4 full
187 buffer_check(cpu, COUNTER_BUF, time);
188 local_irq_restore(flags);
189 }
190 #endif
192 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
193 {
194 unsigned long cpu = get_physical_cpu(), flags;
195 u64 time;
197 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
198 return;
200 local_irq_save(flags);
201 time = gator_get_time();
202 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
203 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
204 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
205 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
206 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
207 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
208 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
209 }
210 // Check and commit; commit is set to occur once buffer is 3/4 full
211 buffer_check(cpu, GPU_TRACE_BUF, time);
212 local_irq_restore(flags);
213 }
215 static void marshal_sched_gpu_stop(int unit, int core)
216 {
217 unsigned long cpu = get_physical_cpu(), flags;
218 u64 time;
220 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
221 return;
223 local_irq_save(flags);
224 time = gator_get_time();
225 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
226 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
227 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
228 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
229 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
230 }
231 // Check and commit; commit is set to occur once buffer is 3/4 full
232 buffer_check(cpu, GPU_TRACE_BUF, time);
233 local_irq_restore(flags);
234 }
236 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
237 {
238 unsigned long cpu = get_physical_cpu(), flags;
239 u64 time;
241 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
242 return;
244 local_irq_save(flags);
245 time = gator_get_time();
246 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
247 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
248 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
249 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
250 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
251 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
252 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
253 }
254 // Check and commit; commit is set to occur once buffer is 3/4 full
255 buffer_check(cpu, SCHED_TRACE_BUF, time);
256 local_irq_restore(flags);
257 }
259 static void marshal_sched_trace_exit(int tgid, int pid)
260 {
261 unsigned long cpu = get_physical_cpu(), flags;
262 u64 time;
264 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
265 return;
267 local_irq_save(flags);
268 time = gator_get_time();
269 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
270 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
271 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
272 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
273 }
274 // Check and commit; commit is set to occur once buffer is 3/4 full
275 buffer_check(cpu, SCHED_TRACE_BUF, time);
276 local_irq_restore(flags);
277 }
279 #if GATOR_CPU_FREQ_SUPPORT
280 static void marshal_idle(int core, int state)
281 {
282 unsigned long flags, cpu;
283 u64 time;
285 local_irq_save(flags);
286 cpu = get_physical_cpu();
287 time = gator_get_time();
288 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
289 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
290 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
291 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
292 }
293 // Check and commit; commit is set to occur once buffer is 3/4 full
294 buffer_check(cpu, IDLE_BUF, time);
295 local_irq_restore(flags);
296 }
297 #endif
299 static void marshal_frame(int cpu, int buftype)
300 {
301 int frame;
303 if (!per_cpu(gator_buffer, cpu)[buftype]) {
304 return;
305 }
307 switch (buftype) {
308 case SUMMARY_BUF:
309 frame = FRAME_SUMMARY;
310 break;
311 case BACKTRACE_BUF:
312 frame = FRAME_BACKTRACE;
313 break;
314 case NAME_BUF:
315 frame = FRAME_NAME;
316 break;
317 case COUNTER_BUF:
318 frame = FRAME_COUNTER;
319 break;
320 case BLOCK_COUNTER_BUF:
321 frame = FRAME_BLOCK_COUNTER;
322 break;
323 case ANNOTATE_BUF:
324 frame = FRAME_ANNOTATE;
325 break;
326 case SCHED_TRACE_BUF:
327 frame = FRAME_SCHED_TRACE;
328 break;
329 case GPU_TRACE_BUF:
330 frame = FRAME_GPU_TRACE;
331 break;
332 case IDLE_BUF:
333 frame = FRAME_IDLE;
334 break;
335 default:
336 frame = -1;
337 break;
338 }
340 // add response type
341 if (gator_response_type > 0) {
342 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
343 }
345 // leave space for 4-byte unpacked length
346 per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + 4) & gator_buffer_mask[buftype];
348 // add frame type and core number
349 gator_buffer_write_packed_int(cpu, buftype, frame);
350 gator_buffer_write_packed_int(cpu, buftype, cpu);
351 }
353 #if defined(__arm__) || defined(__aarch64__)
354 static void marshal_core_name(const int cpuid, const char *name)
355 {
356 int cpu = get_physical_cpu();
357 unsigned long flags;
358 local_irq_save(flags);
359 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
360 gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
361 gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid);
362 gator_buffer_write_string(cpu, NAME_BUF, name);
363 }
364 buffer_check(cpu, NAME_BUF, gator_get_time());
365 local_irq_restore(flags);
366 }
367 #endif