1 /**
2 * Copyright (C) ARM Limited 2012. 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 static void marshal_summary(long long timestamp, long long uptime)
11 {
12 int cpu = 0;
13 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
14 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
15 buffer_check(cpu, SUMMARY_BUF);
16 }
18 static bool marshal_cookie_header(const char *text)
19 {
20 int cpu = smp_processor_id();
21 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
22 }
24 static void marshal_cookie(int cookie, const char *text)
25 {
26 int cpu = smp_processor_id();
27 // buffer_check_space already called by marshal_cookie_header
28 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
29 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
30 gator_buffer_write_string(cpu, NAME_BUF, text);
31 buffer_check(cpu, NAME_BUF);
32 }
34 static void marshal_thread_name(int pid, char *name)
35 {
36 unsigned long flags, cpu;
37 local_irq_save(flags);
38 cpu = smp_processor_id();
39 if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
40 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
41 gator_buffer_write_packed_int64(cpu, NAME_BUF, gator_get_time());
42 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
43 gator_buffer_write_string(cpu, NAME_BUF, name);
44 }
45 buffer_check(cpu, NAME_BUF);
46 local_irq_restore(flags);
47 }
49 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel)
50 {
51 int cpu = smp_processor_id();
52 if (buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
53 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, gator_get_time());
54 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
55 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
56 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
57 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
58 return true;
59 }
61 // Check and commit; commit is set to occur once buffer is 3/4 full
62 buffer_check(cpu, BACKTRACE_BUF);
64 return false;
65 }
67 static void marshal_backtrace(unsigned long address, int cookie)
68 {
69 int cpu = smp_processor_id();
70 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
71 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
72 }
74 static void marshal_backtrace_footer(void)
75 {
76 int cpu = smp_processor_id();
77 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
79 // Check and commit; commit is set to occur once buffer is 3/4 full
80 buffer_check(cpu, BACKTRACE_BUF);
81 }
83 static bool marshal_event_header(void)
84 {
85 unsigned long flags, cpu = smp_processor_id();
86 bool retval = false;
88 local_irq_save(flags);
89 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
90 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
91 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, gator_get_time());
92 retval = true;
93 }
94 // Check and commit; commit is set to occur once buffer is 3/4 full
95 buffer_check(cpu, BLOCK_COUNTER_BUF);
96 local_irq_restore(flags);
98 return retval;
99 }
101 static void marshal_event(int len, int *buffer)
102 {
103 unsigned long i, flags, cpu = smp_processor_id();
105 if (len <= 0)
106 return;
108 // length must be even since all data is a (key, value) pair
109 if (len & 0x1) {
110 pr_err("gator: invalid counter data detected and discarded");
111 return;
112 }
114 // events must be written in key,value pairs
115 local_irq_save(flags);
116 for (i = 0; i < len; i += 2) {
117 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
118 break;
119 }
120 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
121 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
122 }
123 // Check and commit; commit is set to occur once buffer is 3/4 full
124 buffer_check(cpu, BLOCK_COUNTER_BUF);
125 local_irq_restore(flags);
126 }
128 static void marshal_event64(int len, long long *buffer64)
129 {
130 unsigned long i, flags, cpu = smp_processor_id();
132 if (len <= 0)
133 return;
135 // length must be even since all data is a (key, value) pair
136 if (len & 0x1) {
137 pr_err("gator: invalid counter data detected and discarded");
138 return;
139 }
141 // events must be written in key,value pairs
142 local_irq_save(flags);
143 for (i = 0; i < len; i += 2) {
144 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
145 break;
146 }
147 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
148 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
149 }
150 // Check and commit; commit is set to occur once buffer is 3/4 full
151 buffer_check(cpu, BLOCK_COUNTER_BUF);
152 local_irq_restore(flags);
153 }
155 #if GATOR_CPU_FREQ_SUPPORT
156 static void marshal_event_single(int core, int key, int value)
157 {
158 unsigned long flags, cpu;
160 local_irq_save(flags);
161 cpu = smp_processor_id();
162 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
163 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, gator_get_time());
164 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
165 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
166 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
167 }
168 // Check and commit; commit is set to occur once buffer is 3/4 full
169 buffer_check(cpu, COUNTER_BUF);
170 local_irq_restore(flags);
171 }
172 #endif
174 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
175 {
176 unsigned long cpu = smp_processor_id(), flags;
178 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
179 return;
181 local_irq_save(flags);
182 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
183 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
184 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
185 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
186 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
187 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
188 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
189 }
190 // Check and commit; commit is set to occur once buffer is 3/4 full
191 buffer_check(cpu, GPU_TRACE_BUF);
192 local_irq_restore(flags);
193 }
195 static void marshal_sched_gpu_stop(int unit, int core)
196 {
197 unsigned long cpu = smp_processor_id(), flags;
199 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
200 return;
202 local_irq_save(flags);
203 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
204 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
205 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
206 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
207 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
208 }
209 // Check and commit; commit is set to occur once buffer is 3/4 full
210 buffer_check(cpu, GPU_TRACE_BUF);
211 local_irq_restore(flags);
212 }
214 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
215 {
216 unsigned long cpu = smp_processor_id(), flags;
218 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
219 return;
221 local_irq_save(flags);
222 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
223 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
224 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_time());
225 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
226 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
227 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
228 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
229 }
230 // Check and commit; commit is set to occur once buffer is 3/4 full
231 buffer_check(cpu, SCHED_TRACE_BUF);
232 local_irq_restore(flags);
233 }
235 static void marshal_sched_trace_exit(int tgid, int pid)
236 {
237 unsigned long cpu = smp_processor_id(), flags;
239 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
240 return;
242 local_irq_save(flags);
243 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
244 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
245 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_time());
246 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
247 }
248 // Check and commit; commit is set to occur once buffer is 3/4 full
249 buffer_check(cpu, SCHED_TRACE_BUF);
250 local_irq_restore(flags);
251 }
253 #if GATOR_CPU_FREQ_SUPPORT
254 static void marshal_idle(int core, int state)
255 {
256 unsigned long flags, cpu;
258 local_irq_save(flags);
259 cpu = smp_processor_id();
260 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
261 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
262 gator_buffer_write_packed_int64(cpu, IDLE_BUF, gator_get_time());
263 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
264 }
265 // Check and commit; commit is set to occur once buffer is 3/4 full
266 buffer_check(cpu, IDLE_BUF);
267 local_irq_restore(flags);
268 }
269 #endif
271 static void marshal_frame(int cpu, int buftype)
272 {
273 int frame;
275 if (!per_cpu(gator_buffer, cpu)[buftype]) {
276 return;
277 }
279 switch (buftype) {
280 case SUMMARY_BUF:
281 frame = FRAME_SUMMARY;
282 break;
283 case BACKTRACE_BUF:
284 frame = FRAME_BACKTRACE;
285 break;
286 case NAME_BUF:
287 frame = FRAME_NAME;
288 break;
289 case COUNTER_BUF:
290 frame = FRAME_COUNTER;
291 break;
292 case BLOCK_COUNTER_BUF:
293 frame = FRAME_BLOCK_COUNTER;
294 break;
295 case ANNOTATE_BUF:
296 frame = FRAME_ANNOTATE;
297 break;
298 case SCHED_TRACE_BUF:
299 frame = FRAME_SCHED_TRACE;
300 break;
301 case GPU_TRACE_BUF:
302 frame = FRAME_GPU_TRACE;
303 break;
304 case IDLE_BUF:
305 frame = FRAME_IDLE;
306 break;
307 default:
308 frame = -1;
309 break;
310 }
312 // add response type
313 if (gator_response_type > 0) {
314 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
315 }
317 // leave space for 4-byte unpacked length
318 per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + 4) & gator_buffer_mask[buftype];
320 // add frame type and core number
321 gator_buffer_write_packed_int(cpu, buftype, frame);
322 gator_buffer_write_packed_int(cpu, buftype, cpu);
323 }
325 #if defined(__arm__) || defined(__aarch64__)
326 static void marshal_core_name(const char *name)
327 {
328 int cpu = smp_processor_id();
329 unsigned long flags;
330 local_irq_save(flags);
331 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
332 gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
333 gator_buffer_write_string(cpu, NAME_BUF, name);
334 }
335 buffer_check(cpu, NAME_BUF);
336 local_irq_restore(flags);
337 }
338 #endif