2 * Copyright (C) ARM Limited 2012-2014. 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_packed_int(cpu, SUMMARY_BUF, MESSAGE_SUMMARY);
33 gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
34 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
35 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
36 gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, monotonic_delta);
37 gator_buffer_write_string(cpu, SUMMARY_BUF, "uname");
38 gator_buffer_write_string(cpu, SUMMARY_BUF, uname);
40 gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
41 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
43 #ifdef CONFIG_PREEMPT_RTB
44 gator_buffer_write_string(cpu, SUMMARY_BUF, "preempt_rtb");
45 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
47 #ifdef CONFIG_PREEMPT_RT_FULL
48 gator_buffer_write_string(cpu, SUMMARY_BUF, "preempt_rt_full");
49 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
51 /* 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. */
53 gator_buffer_write_string(cpu, SUMMARY_BUF, "mali_type");
54 #if (MALI_SUPPORT == MALI_4xx)
55 gator_buffer_write_string(cpu, SUMMARY_BUF, "4xx");
56 #elif (MALI_SUPPORT == MALI_MIDGARD)
57 gator_buffer_write_string(cpu, SUMMARY_BUF, "6xx");
59 gator_buffer_write_string(cpu, SUMMARY_BUF, "unknown");
62 gator_buffer_write_string(cpu, SUMMARY_BUF, "");
63 /* Commit the buffer now so it can be one of the first frames read by Streamline */
64 local_irq_restore(flags);
65 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
68 static bool marshal_cookie_header(const char *text)
70 int cpu = get_physical_cpu();
72 return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
75 static void marshal_cookie(int cookie, const char *text)
77 int cpu = get_physical_cpu();
78 /* buffer_check_space already called by marshal_cookie_header */
79 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
80 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
81 gator_buffer_write_string(cpu, NAME_BUF, text);
82 buffer_check(cpu, NAME_BUF, gator_get_time());
85 static void marshal_thread_name(int pid, char *name)
87 unsigned long flags, cpu;
90 local_irq_save(flags);
91 cpu = get_physical_cpu();
92 time = gator_get_time();
93 if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
94 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
95 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
96 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
97 gator_buffer_write_string(cpu, NAME_BUF, name);
99 local_irq_restore(flags);
100 buffer_check(cpu, NAME_BUF, time);
103 static void marshal_link(int cookie, int tgid, int pid)
105 unsigned long cpu = get_physical_cpu(), flags;
108 local_irq_save(flags);
109 time = gator_get_time();
110 if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
111 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_LINK);
112 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
113 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
114 gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
115 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
117 local_irq_restore(flags);
118 /* Check and commit; commit is set to occur once buffer is 3/4 full */
119 buffer_check(cpu, NAME_BUF, time);
122 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, u64 time)
124 int cpu = get_physical_cpu();
126 if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
127 /* Check and commit; commit is set to occur once buffer is 3/4 full */
128 buffer_check(cpu, BACKTRACE_BUF, time);
133 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
134 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
135 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
136 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
141 static void marshal_backtrace(unsigned long address, int cookie, int in_kernel)
143 int cpu = get_physical_cpu();
145 if (cookie == 0 && !in_kernel)
146 cookie = UNRESOLVED_COOKIE;
147 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
148 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
151 static void marshal_backtrace_footer(u64 time)
153 int cpu = get_physical_cpu();
155 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
157 /* Check and commit; commit is set to occur once buffer is 3/4 full */
158 buffer_check(cpu, BACKTRACE_BUF, time);
161 static bool marshal_event_header(u64 time)
163 unsigned long flags, cpu = get_physical_cpu();
166 local_irq_save(flags);
167 if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
168 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); /* key of zero indicates a timestamp */
169 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
172 local_irq_restore(flags);
177 static void marshal_event(int len, int *buffer)
179 unsigned long i, flags, cpu = get_physical_cpu();
184 /* length must be even since all data is a (key, value) pair */
186 pr_err("gator: invalid counter data detected and discarded\n");
190 /* events must be written in key,value pairs */
191 local_irq_save(flags);
192 for (i = 0; i < len; i += 2) {
193 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32))
195 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
196 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
198 local_irq_restore(flags);
201 static void marshal_event64(int len, long long *buffer64)
203 unsigned long i, flags, cpu = get_physical_cpu();
208 /* length must be even since all data is a (key, value) pair */
210 pr_err("gator: invalid counter data detected and discarded\n");
214 /* events must be written in key,value pairs */
215 local_irq_save(flags);
216 for (i = 0; i < len; i += 2) {
217 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64))
219 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
220 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
222 local_irq_restore(flags);
225 static void __maybe_unused marshal_event_single(int core, int key, int value)
227 unsigned long flags, cpu;
230 local_irq_save(flags);
231 cpu = get_physical_cpu();
232 time = gator_get_time();
233 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
234 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
235 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
236 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
237 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
239 local_irq_restore(flags);
240 /* Check and commit; commit is set to occur once buffer is 3/4 full */
241 buffer_check(cpu, COUNTER_BUF, time);
244 static void __maybe_unused marshal_event_single64(int core, int key, long long value)
246 unsigned long flags, cpu;
249 local_irq_save(flags);
250 cpu = get_physical_cpu();
251 time = gator_get_time();
252 if (buffer_check_space(cpu, COUNTER_BUF, 2 * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
253 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
254 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
255 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
256 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, value);
258 local_irq_restore(flags);
259 /* Check and commit; commit is set to occur once buffer is 3/4 full */
260 buffer_check(cpu, COUNTER_BUF, time);
263 static void marshal_sched_trace_switch(int pid, int state)
265 unsigned long cpu = get_physical_cpu(), flags;
268 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
271 local_irq_save(flags);
272 time = gator_get_time();
273 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
274 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
275 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
276 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
277 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
279 local_irq_restore(flags);
280 /* Check and commit; commit is set to occur once buffer is 3/4 full */
281 buffer_check(cpu, SCHED_TRACE_BUF, time);
284 static void marshal_sched_trace_exit(int tgid, int pid)
286 unsigned long cpu = get_physical_cpu(), flags;
289 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
292 local_irq_save(flags);
293 time = gator_get_time();
294 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
295 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
296 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
297 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
299 local_irq_restore(flags);
300 /* Check and commit; commit is set to occur once buffer is 3/4 full */
301 buffer_check(cpu, SCHED_TRACE_BUF, time);
304 #if GATOR_CPU_FREQ_SUPPORT
305 static void marshal_idle(int core, int state)
307 unsigned long flags, cpu;
310 local_irq_save(flags);
311 cpu = get_physical_cpu();
312 time = gator_get_time();
313 if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
314 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
315 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
316 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
318 local_irq_restore(flags);
319 /* Check and commit; commit is set to occur once buffer is 3/4 full */
320 buffer_check(cpu, IDLE_BUF, time);
324 #if defined(__arm__) || defined(__aarch64__)
325 static void marshal_core_name(const int core, const int cpuid, const char *name)
327 int cpu = get_physical_cpu();
330 local_irq_save(flags);
331 if (buffer_check_space(cpu, SUMMARY_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
332 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_CORE_NAME);
333 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, core);
334 gator_buffer_write_packed_int(cpu, SUMMARY_BUF, cpuid);
335 gator_buffer_write_string(cpu, SUMMARY_BUF, name);
337 /* Commit core names now so that they can show up in live */
338 local_irq_restore(flags);
339 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
343 static void marshal_activity_switch(int core, int key, int activity, int pid, int state)
345 unsigned long cpu = get_physical_cpu(), flags;
348 if (!per_cpu(gator_buffer, cpu)[ACTIVITY_BUF])
351 local_irq_save(flags);
352 time = gator_get_time();
353 if (buffer_check_space(cpu, ACTIVITY_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
354 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, MESSAGE_SWITCH);
355 gator_buffer_write_packed_int64(cpu, ACTIVITY_BUF, time);
356 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, core);
357 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, key);
358 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, activity);
359 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, pid);
360 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, state);
362 local_irq_restore(flags);
363 /* Check and commit; commit is set to occur once buffer is 3/4 full */
364 buffer_check(cpu, ACTIVITY_BUF, time);
367 void gator_marshal_activity_switch(int core, int key, int activity, int pid)
369 /* state is reserved for cpu use only */
370 marshal_activity_switch(core, key, activity, pid, 0);