Branch data Line data Source code
1 : : /*
2 : : * trace_output.c
3 : : *
4 : : * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5 : : *
6 : : */
7 : :
8 : : #include <linux/module.h>
9 : : #include <linux/mutex.h>
10 : : #include <linux/ftrace.h>
11 : :
12 : : #include "trace_output.h"
13 : :
14 : : /* must be a power of 2 */
15 : : #define EVENT_HASHSIZE 128
16 : :
17 : : DECLARE_RWSEM(trace_event_sem);
18 : :
19 : : static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
20 : :
21 : : static int next_event_type = __TRACE_LAST_TYPE + 1;
22 : :
23 : 0 : int trace_print_seq(struct seq_file *m, struct trace_seq *s)
24 : : {
25 : 0 : int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
26 : : int ret;
27 : :
28 : 0 : ret = seq_write(m, s->buffer, len);
29 : :
30 : : /*
31 : : * Only reset this buffer if we successfully wrote to the
32 : : * seq_file buffer.
33 : : */
34 [ # # ]: 0 : if (!ret)
35 : : trace_seq_init(s);
36 : :
37 : 0 : return ret;
38 : : }
39 : :
40 : 0 : enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter)
41 : : {
42 : 0 : struct trace_seq *s = &iter->seq;
43 : 0 : struct trace_entry *entry = iter->ent;
44 : : struct bputs_entry *field;
45 : : int ret;
46 : :
47 [ # # ]: 0 : trace_assign_type(field, entry);
48 : :
49 : 0 : ret = trace_seq_puts(s, field->str);
50 [ # # ]: 0 : if (!ret)
51 : : return TRACE_TYPE_PARTIAL_LINE;
52 : :
53 : 0 : return TRACE_TYPE_HANDLED;
54 : : }
55 : :
56 : 0 : enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
57 : : {
58 : 0 : struct trace_seq *s = &iter->seq;
59 : 0 : struct trace_entry *entry = iter->ent;
60 : : struct bprint_entry *field;
61 : : int ret;
62 : :
63 [ # # ]: 0 : trace_assign_type(field, entry);
64 : :
65 : 0 : ret = trace_seq_bprintf(s, field->fmt, field->buf);
66 [ # # ]: 0 : if (!ret)
67 : : return TRACE_TYPE_PARTIAL_LINE;
68 : :
69 : 0 : return TRACE_TYPE_HANDLED;
70 : : }
71 : :
72 : 0 : enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
73 : : {
74 : 0 : struct trace_seq *s = &iter->seq;
75 : 0 : struct trace_entry *entry = iter->ent;
76 : : struct print_entry *field;
77 : : int ret;
78 : :
79 [ # # ]: 0 : trace_assign_type(field, entry);
80 : :
81 : 0 : ret = trace_seq_puts(s, field->buf);
82 [ # # ]: 0 : if (!ret)
83 : : return TRACE_TYPE_PARTIAL_LINE;
84 : :
85 : 0 : return TRACE_TYPE_HANDLED;
86 : : }
87 : :
88 : : /**
89 : : * trace_seq_printf - sequence printing of trace information
90 : : * @s: trace sequence descriptor
91 : : * @fmt: printf format string
92 : : *
93 : : * It returns 0 if the trace oversizes the buffer's free
94 : : * space, 1 otherwise.
95 : : *
96 : : * The tracer may use either sequence operations or its own
97 : : * copy to user routines. To simplify formating of a trace
98 : : * trace_seq_printf is used to store strings into a special
99 : : * buffer (@s). Then the output may be either used by
100 : : * the sequencer or pulled into another buffer.
101 : : */
102 : : int
103 : 0 : trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
104 : : {
105 : 0 : int len = (PAGE_SIZE - 1) - s->len;
106 : : va_list ap;
107 : : int ret;
108 : :
109 [ # # ][ # # ]: 0 : if (s->full || !len)
110 : : return 0;
111 : :
112 : 0 : va_start(ap, fmt);
113 : 0 : ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
114 : 0 : va_end(ap);
115 : :
116 : : /* If we can't write it all, don't bother writing anything */
117 [ # # ]: 0 : if (ret >= len) {
118 : 0 : s->full = 1;
119 : 0 : return 0;
120 : : }
121 : :
122 : 0 : s->len += ret;
123 : :
124 : 0 : return 1;
125 : : }
126 : : EXPORT_SYMBOL_GPL(trace_seq_printf);
127 : :
128 : : /**
129 : : * trace_seq_vprintf - sequence printing of trace information
130 : : * @s: trace sequence descriptor
131 : : * @fmt: printf format string
132 : : *
133 : : * The tracer may use either sequence operations or its own
134 : : * copy to user routines. To simplify formating of a trace
135 : : * trace_seq_printf is used to store strings into a special
136 : : * buffer (@s). Then the output may be either used by
137 : : * the sequencer or pulled into another buffer.
138 : : */
139 : : int
140 : 0 : trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
141 : : {
142 : 0 : int len = (PAGE_SIZE - 1) - s->len;
143 : : int ret;
144 : :
145 [ # # ][ # # ]: 0 : if (s->full || !len)
146 : : return 0;
147 : :
148 : 0 : ret = vsnprintf(s->buffer + s->len, len, fmt, args);
149 : :
150 : : /* If we can't write it all, don't bother writing anything */
151 [ # # ]: 0 : if (ret >= len) {
152 : 0 : s->full = 1;
153 : 0 : return 0;
154 : : }
155 : :
156 : 0 : s->len += ret;
157 : :
158 : 0 : return len;
159 : : }
160 : : EXPORT_SYMBOL_GPL(trace_seq_vprintf);
161 : :
162 : 0 : int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
163 : : {
164 : 0 : int len = (PAGE_SIZE - 1) - s->len;
165 : : int ret;
166 : :
167 [ # # ][ # # ]: 0 : if (s->full || !len)
168 : : return 0;
169 : :
170 : 0 : ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
171 : :
172 : : /* If we can't write it all, don't bother writing anything */
173 [ # # ]: 0 : if (ret >= len) {
174 : 0 : s->full = 1;
175 : 0 : return 0;
176 : : }
177 : :
178 : 0 : s->len += ret;
179 : :
180 : 0 : return len;
181 : : }
182 : :
183 : : /**
184 : : * trace_seq_puts - trace sequence printing of simple string
185 : : * @s: trace sequence descriptor
186 : : * @str: simple string to record
187 : : *
188 : : * The tracer may use either the sequence operations or its own
189 : : * copy to user routines. This function records a simple string
190 : : * into a special buffer (@s) for later retrieval by a sequencer
191 : : * or other mechanism.
192 : : */
193 : 0 : int trace_seq_puts(struct trace_seq *s, const char *str)
194 : : {
195 : 0 : int len = strlen(str);
196 : :
197 [ # # ]: 0 : if (s->full)
198 : : return 0;
199 : :
200 [ # # ]: 0 : if (len > ((PAGE_SIZE - 1) - s->len)) {
201 : 0 : s->full = 1;
202 : 0 : return 0;
203 : : }
204 : :
205 : 0 : memcpy(s->buffer + s->len, str, len);
206 : 0 : s->len += len;
207 : :
208 : 0 : return len;
209 : : }
210 : :
211 : 0 : int trace_seq_putc(struct trace_seq *s, unsigned char c)
212 : : {
213 [ # # ][ # # ]: 0 : if (s->full)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
214 : : return 0;
215 : :
216 [ # # ][ # # ]: 0 : if (s->len >= (PAGE_SIZE - 1)) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
217 : 0 : s->full = 1;
218 : 0 : return 0;
219 : : }
220 : :
221 : 0 : s->buffer[s->len++] = c;
222 : :
223 : 0 : return 1;
224 : : }
225 : : EXPORT_SYMBOL(trace_seq_putc);
226 : :
227 : 0 : int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
228 : : {
229 [ # # ]: 0 : if (s->full)
230 : : return 0;
231 : :
232 [ # # ]: 0 : if (len > ((PAGE_SIZE - 1) - s->len)) {
233 : 0 : s->full = 1;
234 : 0 : return 0;
235 : : }
236 : :
237 : 0 : memcpy(s->buffer + s->len, mem, len);
238 : 0 : s->len += len;
239 : :
240 : 0 : return len;
241 : : }
242 : :
243 : 0 : int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
244 : : {
245 : : unsigned char hex[HEX_CHARS];
246 : : const unsigned char *data = mem;
247 : : int i, j;
248 : :
249 [ # # ]: 0 : if (s->full)
250 : : return 0;
251 : :
252 : : #ifdef __BIG_ENDIAN
253 : : for (i = 0, j = 0; i < len; i++) {
254 : : #else
255 [ # # ]: 0 : for (i = len-1, j = 0; i >= 0; i--) {
256 : : #endif
257 : 0 : hex[j++] = hex_asc_hi(data[i]);
258 : 0 : hex[j++] = hex_asc_lo(data[i]);
259 : : }
260 : 0 : hex[j++] = ' ';
261 : :
262 : 0 : return trace_seq_putmem(s, hex, j);
263 : : }
264 : :
265 : 0 : void *trace_seq_reserve(struct trace_seq *s, size_t len)
266 : : {
267 : : void *ret;
268 : :
269 [ # # ]: 0 : if (s->full)
270 : : return NULL;
271 : :
272 [ # # ]: 0 : if (len > ((PAGE_SIZE - 1) - s->len)) {
273 : 0 : s->full = 1;
274 : 0 : return NULL;
275 : : }
276 : :
277 : : ret = s->buffer + s->len;
278 : 0 : s->len += len;
279 : :
280 : 0 : return ret;
281 : : }
282 : :
283 : 0 : int trace_seq_path(struct trace_seq *s, const struct path *path)
284 : : {
285 : : unsigned char *p;
286 : :
287 [ # # ]: 0 : if (s->full)
288 : : return 0;
289 : :
290 [ # # ]: 0 : if (s->len >= (PAGE_SIZE - 1)) {
291 : 0 : s->full = 1;
292 : 0 : return 0;
293 : : }
294 : :
295 : 0 : p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
296 [ # # ]: 0 : if (!IS_ERR(p)) {
297 : 0 : p = mangle_path(s->buffer + s->len, p, "\n");
298 [ # # ]: 0 : if (p) {
299 : 0 : s->len = p - s->buffer;
300 : 0 : return 1;
301 : : }
302 : : } else {
303 : 0 : s->buffer[s->len++] = '?';
304 : 0 : return 1;
305 : : }
306 : :
307 : 0 : s->full = 1;
308 : 0 : return 0;
309 : : }
310 : :
311 : : const char *
312 : 0 : ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
313 : : unsigned long flags,
314 : : const struct trace_print_flags *flag_array)
315 : : {
316 : : unsigned long mask;
317 : : const char *str;
318 : 0 : const char *ret = p->buffer + p->len;
319 : : int i, first = 1;
320 : :
321 [ # # ][ # # ]: 0 : for (i = 0; flag_array[i].name && flags; i++) {
322 : :
323 : 0 : mask = flag_array[i].mask;
324 [ # # ]: 0 : if ((flags & mask) != mask)
325 : 0 : continue;
326 : :
327 : : str = flag_array[i].name;
328 : 0 : flags &= ~mask;
329 [ # # ]: 0 : if (!first && delim)
330 : 0 : trace_seq_puts(p, delim);
331 : : else
332 : : first = 0;
333 : 0 : trace_seq_puts(p, str);
334 : : }
335 : :
336 : : /* check for left over flags */
337 [ # # ]: 0 : if (flags) {
338 [ # # ]: 0 : if (!first && delim)
339 : 0 : trace_seq_puts(p, delim);
340 : 0 : trace_seq_printf(p, "0x%lx", flags);
341 : : }
342 : :
343 : : trace_seq_putc(p, 0);
344 : :
345 : 0 : return ret;
346 : : }
347 : : EXPORT_SYMBOL(ftrace_print_flags_seq);
348 : :
349 : : const char *
350 : 0 : ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
351 : : const struct trace_print_flags *symbol_array)
352 : : {
353 : : int i;
354 : 0 : const char *ret = p->buffer + p->len;
355 : :
356 [ # # ]: 0 : for (i = 0; symbol_array[i].name; i++) {
357 : :
358 [ # # ]: 0 : if (val != symbol_array[i].mask)
359 : 0 : continue;
360 : :
361 : 0 : trace_seq_puts(p, symbol_array[i].name);
362 : 0 : break;
363 : : }
364 : :
365 [ # # ]: 0 : if (ret == (const char *)(p->buffer + p->len))
366 : 0 : trace_seq_printf(p, "0x%lx", val);
367 : :
368 : : trace_seq_putc(p, 0);
369 : :
370 : 0 : return ret;
371 : : }
372 : : EXPORT_SYMBOL(ftrace_print_symbols_seq);
373 : :
374 : : #if BITS_PER_LONG == 32
375 : : const char *
376 : 0 : ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
377 : : const struct trace_print_flags_u64 *symbol_array)
378 : : {
379 : : int i;
380 : 0 : const char *ret = p->buffer + p->len;
381 : :
382 [ # # ]: 0 : for (i = 0; symbol_array[i].name; i++) {
383 : :
384 [ # # ]: 0 : if (val != symbol_array[i].mask)
385 : 0 : continue;
386 : :
387 : 0 : trace_seq_puts(p, symbol_array[i].name);
388 : 0 : break;
389 : : }
390 : :
391 [ # # ]: 0 : if (ret == (const char *)(p->buffer + p->len))
392 : 0 : trace_seq_printf(p, "0x%llx", val);
393 : :
394 : : trace_seq_putc(p, 0);
395 : :
396 : 0 : return ret;
397 : : }
398 : : EXPORT_SYMBOL(ftrace_print_symbols_seq_u64);
399 : : #endif
400 : :
401 : : const char *
402 : 0 : ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
403 : : {
404 : : int i;
405 : 0 : const char *ret = p->buffer + p->len;
406 : :
407 [ # # ]: 0 : for (i = 0; i < buf_len; i++)
408 [ # # ]: 0 : trace_seq_printf(p, "%s%2.2x", i == 0 ? "" : " ", buf[i]);
409 : :
410 : : trace_seq_putc(p, 0);
411 : :
412 : 0 : return ret;
413 : : }
414 : : EXPORT_SYMBOL(ftrace_print_hex_seq);
415 : :
416 : 0 : int ftrace_raw_output_prep(struct trace_iterator *iter,
417 : : struct trace_event *trace_event)
418 : : {
419 : : struct ftrace_event_call *event;
420 : 0 : struct trace_seq *s = &iter->seq;
421 : : struct trace_seq *p = &iter->tmp_seq;
422 : : struct trace_entry *entry;
423 : : int ret;
424 : :
425 : : event = container_of(trace_event, struct ftrace_event_call, event);
426 : 0 : entry = iter->ent;
427 : :
428 [ # # ]: 0 : if (entry->type != event->event.type) {
429 [ # # ][ # # ]: 0 : WARN_ON_ONCE(1);
430 : : return TRACE_TYPE_UNHANDLED;
431 : : }
432 : :
433 : : trace_seq_init(p);
434 : 0 : ret = trace_seq_printf(s, "%s: ", event->name);
435 : : if (!ret)
436 : : return TRACE_TYPE_PARTIAL_LINE;
437 : :
438 : : return 0;
439 : : }
440 : : EXPORT_SYMBOL(ftrace_raw_output_prep);
441 : :
442 : : #ifdef CONFIG_KRETPROBES
443 : : static inline const char *kretprobed(const char *name)
444 : : {
445 : : static const char tramp_name[] = "kretprobe_trampoline";
446 : : int size = sizeof(tramp_name);
447 : :
448 : : if (strncmp(tramp_name, name, size) == 0)
449 : : return "[unknown/kretprobe'd]";
450 : : return name;
451 : : }
452 : : #else
453 : : static inline const char *kretprobed(const char *name)
454 : : {
455 : : return name;
456 : : }
457 : : #endif /* CONFIG_KRETPROBES */
458 : :
459 : : static int
460 : 0 : seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
461 : : {
462 : : #ifdef CONFIG_KALLSYMS
463 : : char str[KSYM_SYMBOL_LEN];
464 : : const char *name;
465 : :
466 : 0 : kallsyms_lookup(address, NULL, NULL, NULL, str);
467 : :
468 : : name = kretprobed(str);
469 : :
470 : 0 : return trace_seq_printf(s, fmt, name);
471 : : #endif
472 : : return 1;
473 : : }
474 : :
475 : : static int
476 : 0 : seq_print_sym_offset(struct trace_seq *s, const char *fmt,
477 : : unsigned long address)
478 : : {
479 : : #ifdef CONFIG_KALLSYMS
480 : : char str[KSYM_SYMBOL_LEN];
481 : : const char *name;
482 : :
483 : 0 : sprint_symbol(str, address);
484 : : name = kretprobed(str);
485 : :
486 : 0 : return trace_seq_printf(s, fmt, name);
487 : : #endif
488 : : return 1;
489 : : }
490 : :
491 : : #ifndef CONFIG_64BIT
492 : : # define IP_FMT "%08lx"
493 : : #else
494 : : # define IP_FMT "%016lx"
495 : : #endif
496 : :
497 : 0 : int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
498 : : unsigned long ip, unsigned long sym_flags)
499 : : {
500 : : struct file *file = NULL;
501 : : unsigned long vmstart = 0;
502 : : int ret = 1;
503 : :
504 [ # # ]: 0 : if (s->full)
505 : : return 0;
506 : :
507 [ # # ]: 0 : if (mm) {
508 : : const struct vm_area_struct *vma;
509 : :
510 : 0 : down_read(&mm->mmap_sem);
511 : 0 : vma = find_vma(mm, ip);
512 [ # # ]: 0 : if (vma) {
513 : 0 : file = vma->vm_file;
514 : 0 : vmstart = vma->vm_start;
515 : : }
516 [ # # ]: 0 : if (file) {
517 : 0 : ret = trace_seq_path(s, &file->f_path);
518 [ # # ]: 0 : if (ret)
519 : 0 : ret = trace_seq_printf(s, "[+0x%lx]",
520 : : ip - vmstart);
521 : : }
522 : 0 : up_read(&mm->mmap_sem);
523 : : }
524 [ # # ][ # # ]: 0 : if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
[ # # ]
525 : 0 : ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
526 : 0 : return ret;
527 : : }
528 : :
529 : : int
530 : 0 : seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
531 : : unsigned long sym_flags)
532 : : {
533 : : struct mm_struct *mm = NULL;
534 : : int ret = 1;
535 : : unsigned int i;
536 : :
537 [ # # ]: 0 : if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
538 : : struct task_struct *task;
539 : : /*
540 : : * we do the lookup on the thread group leader,
541 : : * since individual threads might have already quit!
542 : : */
543 : : rcu_read_lock();
544 : 0 : task = find_task_by_vpid(entry->tgid);
545 [ # # ]: 0 : if (task)
546 : 0 : mm = get_task_mm(task);
547 : : rcu_read_unlock();
548 : : }
549 : :
550 [ # # ]: 0 : for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
551 : 0 : unsigned long ip = entry->caller[i];
552 : :
553 [ # # ]: 0 : if (ip == ULONG_MAX || !ret)
554 : : break;
555 [ # # ]: 0 : if (ret)
556 : 0 : ret = trace_seq_puts(s, " => ");
557 [ # # ]: 0 : if (!ip) {
558 [ # # ]: 0 : if (ret)
559 : 0 : ret = trace_seq_puts(s, "??");
560 [ # # ]: 0 : if (ret)
561 : : ret = trace_seq_putc(s, '\n');
562 : 0 : continue;
563 : : }
564 [ # # ]: 0 : if (!ret)
565 : : break;
566 [ # # ]: 0 : if (ret)
567 : 0 : ret = seq_print_user_ip(s, mm, ip, sym_flags);
568 : : ret = trace_seq_putc(s, '\n');
569 : : }
570 : :
571 [ # # ]: 0 : if (mm)
572 : 0 : mmput(mm);
573 : 0 : return ret;
574 : : }
575 : :
576 : : int
577 : 0 : seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
578 : : {
579 : : int ret;
580 : :
581 [ # # ]: 0 : if (!ip)
582 : 0 : return trace_seq_putc(s, '0');
583 : :
584 [ # # ]: 0 : if (sym_flags & TRACE_ITER_SYM_OFFSET)
585 : 0 : ret = seq_print_sym_offset(s, "%s", ip);
586 : : else
587 : 0 : ret = seq_print_sym_short(s, "%s", ip);
588 : :
589 [ # # ]: 0 : if (!ret)
590 : : return 0;
591 : :
592 [ # # ]: 0 : if (sym_flags & TRACE_ITER_SYM_ADDR)
593 : 0 : ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
594 : 0 : return ret;
595 : : }
596 : :
597 : : /**
598 : : * trace_print_lat_fmt - print the irq, preempt and lockdep fields
599 : : * @s: trace seq struct to write to
600 : : * @entry: The trace entry field from the ring buffer
601 : : *
602 : : * Prints the generic fields of irqs off, in hard or softirq, preempt
603 : : * count.
604 : : */
605 : 0 : int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
606 : : {
607 : : char hardsoft_irq;
608 : : char need_resched;
609 : : char irqs_off;
610 : : int hardirq;
611 : : int softirq;
612 : : int ret;
613 : :
614 : 0 : hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
615 : 0 : softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
616 : :
617 [ # # ][ # # ]: 0 : irqs_off =
618 : 0 : (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
619 : 0 : (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' :
620 : : '.';
621 : :
622 [ # # # # ]: 0 : switch (entry->flags & (TRACE_FLAG_NEED_RESCHED |
623 : : TRACE_FLAG_PREEMPT_RESCHED)) {
624 : : case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED:
625 : : need_resched = 'N';
626 : : break;
627 : : case TRACE_FLAG_NEED_RESCHED:
628 : : need_resched = 'n';
629 : 0 : break;
630 : : case TRACE_FLAG_PREEMPT_RESCHED:
631 : : need_resched = 'p';
632 : 0 : break;
633 : : default:
634 : : need_resched = '.';
635 : 0 : break;
636 : : }
637 : :
638 [ # # ][ # # ]: 0 : hardsoft_irq =
[ # # ]
639 : 0 : (hardirq && softirq) ? 'H' :
640 : : hardirq ? 'h' :
641 : : softirq ? 's' :
642 : : '.';
643 : :
644 [ # # ]: 0 : if (!trace_seq_printf(s, "%c%c%c",
645 : : irqs_off, need_resched, hardsoft_irq))
646 : : return 0;
647 : :
648 [ # # ]: 0 : if (entry->preempt_count)
649 : 0 : ret = trace_seq_printf(s, "%x", entry->preempt_count);
650 : : else
651 : : ret = trace_seq_putc(s, '.');
652 : :
653 : 0 : return ret;
654 : : }
655 : :
656 : : static int
657 : 0 : lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
658 : : {
659 : : char comm[TASK_COMM_LEN];
660 : :
661 : 0 : trace_find_cmdline(entry->pid, comm);
662 : :
663 [ # # ]: 0 : if (!trace_seq_printf(s, "%8.8s-%-5d %3d",
664 : : comm, entry->pid, cpu))
665 : : return 0;
666 : :
667 : 0 : return trace_print_lat_fmt(s, entry);
668 : : }
669 : :
670 : : static unsigned long preempt_mark_thresh_us = 100;
671 : :
672 : : static int
673 : 0 : lat_print_timestamp(struct trace_iterator *iter, u64 next_ts)
674 : : {
675 : 0 : unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE;
676 : 0 : unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS;
677 : 0 : unsigned long long abs_ts = iter->ts - iter->trace_buffer->time_start;
678 : 0 : unsigned long long rel_ts = next_ts - iter->ts;
679 : 0 : struct trace_seq *s = &iter->seq;
680 : :
681 [ # # ]: 0 : if (in_ns) {
682 : 0 : abs_ts = ns2usecs(abs_ts);
683 : 0 : rel_ts = ns2usecs(rel_ts);
684 : : }
685 : :
686 [ # # ]: 0 : if (verbose && in_ns) {
687 : 0 : unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC);
688 : : unsigned long abs_msec = (unsigned long)abs_ts;
689 : 0 : unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC);
690 : : unsigned long rel_msec = (unsigned long)rel_ts;
691 : :
692 : 0 : return trace_seq_printf(
693 : : s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ",
694 : : ns2usecs(iter->ts),
695 : : abs_msec, abs_usec,
696 : : rel_msec, rel_usec);
697 [ # # ]: 0 : } else if (verbose && !in_ns) {
698 : 0 : return trace_seq_printf(
699 : : s, "[%016llx] %lld (+%lld): ",
700 : : iter->ts, abs_ts, rel_ts);
701 [ # # ]: 0 : } else if (!verbose && in_ns) {
702 [ # # ]: 0 : return trace_seq_printf(
703 : : s, " %4lldus%c: ",
704 : : abs_ts,
705 : 0 : rel_ts > preempt_mark_thresh_us ? '!' :
706 [ # # ]: 0 : rel_ts > 1 ? '+' : ' ');
707 : : } else { /* !verbose && !in_ns */
708 : 0 : return trace_seq_printf(s, " %4lld: ", abs_ts);
709 : : }
710 : : }
711 : :
712 : 0 : int trace_print_context(struct trace_iterator *iter)
713 : : {
714 : 0 : struct trace_seq *s = &iter->seq;
715 : 0 : struct trace_entry *entry = iter->ent;
716 : : unsigned long long t;
717 : : unsigned long secs, usec_rem;
718 : : char comm[TASK_COMM_LEN];
719 : : int ret;
720 : : int tgid;
721 : :
722 : 0 : trace_find_cmdline(entry->pid, comm);
723 : :
724 : 0 : ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
725 [ # # ]: 0 : if (!ret)
726 : : return 0;
727 : :
728 [ # # ]: 0 : if (trace_flags & TRACE_ITER_TGID) {
729 : 0 : tgid = trace_find_tgid(entry->pid);
730 [ # # ]: 0 : if (tgid < 0)
731 : 0 : ret = trace_seq_puts(s, "(-----) ");
732 : : else
733 : 0 : ret = trace_seq_printf(s, "(%5d) ", tgid);
734 [ # # ]: 0 : if (!ret)
735 : : return 0;
736 : : }
737 : :
738 : 0 : ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
739 [ # # ]: 0 : if (!ret)
740 : : return 0;
741 : :
742 [ # # ]: 0 : if (trace_flags & TRACE_ITER_IRQ_INFO) {
743 : 0 : ret = trace_print_lat_fmt(s, entry);
744 [ # # ]: 0 : if (!ret)
745 : : return 0;
746 : : }
747 : :
748 [ # # ]: 0 : if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) {
749 : 0 : t = ns2usecs(iter->ts);
750 : 0 : usec_rem = do_div(t, USEC_PER_SEC);
751 : : secs = (unsigned long)t;
752 : 0 : return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem);
753 : : } else
754 : 0 : return trace_seq_printf(s, " %12llu: ", iter->ts);
755 : : }
756 : :
757 : 0 : int trace_print_lat_context(struct trace_iterator *iter)
758 : : {
759 : : u64 next_ts;
760 : : int ret;
761 : : /* trace_find_next_entry will reset ent_size */
762 : 0 : int ent_size = iter->ent_size;
763 : 0 : struct trace_seq *s = &iter->seq;
764 : 0 : struct trace_entry *entry = iter->ent,
765 : 0 : *next_entry = trace_find_next_entry(iter, NULL,
766 : : &next_ts);
767 : 0 : unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
768 : :
769 : : /* Restore the original ent_size */
770 : 0 : iter->ent_size = ent_size;
771 : :
772 [ # # ]: 0 : if (!next_entry)
773 : 0 : next_ts = iter->ts;
774 : :
775 [ # # ]: 0 : if (verbose) {
776 : : char comm[TASK_COMM_LEN];
777 : :
778 : 0 : trace_find_cmdline(entry->pid, comm);
779 : :
780 : 0 : ret = trace_seq_printf(
781 : : s, "%16s %5d %3d %d %08x %08lx ",
782 : 0 : comm, entry->pid, iter->cpu, entry->flags,
783 : 0 : entry->preempt_count, iter->idx);
784 : : } else {
785 : 0 : ret = lat_print_generic(s, entry, iter->cpu);
786 : : }
787 : :
788 [ # # ]: 0 : if (ret)
789 : 0 : ret = lat_print_timestamp(iter, next_ts);
790 : :
791 : 0 : return ret;
792 : : }
793 : :
794 : : static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
795 : :
796 : 0 : static int task_state_char(unsigned long state)
797 : : {
798 [ # # ]: 0 : int bit = state ? __ffs(state) + 1 : 0;
799 : :
800 [ # # ]: 0 : return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
801 : : }
802 : :
803 : : /**
804 : : * ftrace_find_event - find a registered event
805 : : * @type: the type of event to look for
806 : : *
807 : : * Returns an event of type @type otherwise NULL
808 : : * Called with trace_event_read_lock() held.
809 : : */
810 : 0 : struct trace_event *ftrace_find_event(int type)
811 : : {
812 : : struct trace_event *event;
813 : : unsigned key;
814 : :
815 : 0 : key = type & (EVENT_HASHSIZE - 1);
816 : :
817 [ # # ][ # # ]: 0 : hlist_for_each_entry(event, &event_hash[key], node) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
818 [ # # ][ # # ]: 0 : if (event->type == type)
[ # # ]
819 : : return event;
820 : : }
821 : :
822 : : return NULL;
823 : : }
824 : :
825 : : static LIST_HEAD(ftrace_event_list);
826 : :
827 : : static int trace_search_list(struct list_head **list)
828 : : {
829 : : struct trace_event *e;
830 : : int last = __TRACE_LAST_TYPE;
831 : :
832 [ # # ]: 0 : if (list_empty(&ftrace_event_list)) {
833 : : *list = &ftrace_event_list;
834 : : return last + 1;
835 : : }
836 : :
837 : : /*
838 : : * We used up all possible max events,
839 : : * lets see if somebody freed one.
840 : : */
841 [ # # ]: 0 : list_for_each_entry(e, &ftrace_event_list, list) {
842 [ # # ]: 0 : if (e->type != last + 1)
843 : : break;
844 : : last++;
845 : : }
846 : :
847 : : /* Did we used up all 65 thousand events??? */
848 [ # # ]: 0 : if ((last + 1) > FTRACE_MAX_EVENT)
849 : : return 0;
850 : :
851 : : *list = &e->list;
852 : : return last + 1;
853 : : }
854 : :
855 : 0 : void trace_event_read_lock(void)
856 : : {
857 : 0 : down_read(&trace_event_sem);
858 : 0 : }
859 : :
860 : 0 : void trace_event_read_unlock(void)
861 : : {
862 : 0 : up_read(&trace_event_sem);
863 : 0 : }
864 : :
865 : : /**
866 : : * register_ftrace_event - register output for an event type
867 : : * @event: the event type to register
868 : : *
869 : : * Event types are stored in a hash and this hash is used to
870 : : * find a way to print an event. If the @event->type is set
871 : : * then it will use that type, otherwise it will assign a
872 : : * type to use.
873 : : *
874 : : * If you assign your own type, please make sure it is added
875 : : * to the trace_type enum in trace.h, to avoid collisions
876 : : * with the dynamic types.
877 : : *
878 : : * Returns the event type number or zero on error.
879 : : */
880 : 0 : int register_ftrace_event(struct trace_event *event)
881 : : {
882 : : unsigned key;
883 : : int ret = 0;
884 : :
885 : 0 : down_write(&trace_event_sem);
886 : :
887 [ # # ][ # # ]: 0 : if (WARN_ON(!event))
888 : : goto out;
889 : :
890 [ # # ][ # # ]: 0 : if (WARN_ON(!event->funcs))
891 : : goto out;
892 : :
893 : 0 : INIT_LIST_HEAD(&event->list);
894 : :
895 [ # # ]: 0 : if (!event->type) {
896 : : struct list_head *list = NULL;
897 : :
898 [ # # ]: 0 : if (next_event_type > FTRACE_MAX_EVENT) {
899 : :
900 : 0 : event->type = trace_search_list(&list);
901 [ # # ]: 0 : if (!event->type)
902 : : goto out;
903 : :
904 : : } else {
905 : :
906 : 0 : event->type = next_event_type++;
907 : : list = &ftrace_event_list;
908 : : }
909 : :
910 [ # # ][ # # ]: 0 : if (WARN_ON(ftrace_find_event(event->type)))
911 : : goto out;
912 : :
913 : : list_add_tail(&event->list, list);
914 : :
915 [ # # ]: 0 : } else if (event->type > __TRACE_LAST_TYPE) {
916 : 0 : printk(KERN_WARNING "Need to add type to trace.h\n");
917 : 0 : WARN_ON(1);
918 : 0 : goto out;
919 : : } else {
920 : : /* Is this event already used */
921 [ # # ]: 0 : if (ftrace_find_event(event->type))
922 : : goto out;
923 : : }
924 : :
925 [ # # ]: 0 : if (event->funcs->trace == NULL)
926 : 0 : event->funcs->trace = trace_nop_print;
927 [ # # ]: 0 : if (event->funcs->raw == NULL)
928 : 0 : event->funcs->raw = trace_nop_print;
929 [ # # ]: 0 : if (event->funcs->hex == NULL)
930 : 0 : event->funcs->hex = trace_nop_print;
931 [ # # ]: 0 : if (event->funcs->binary == NULL)
932 : 0 : event->funcs->binary = trace_nop_print;
933 : :
934 : 0 : key = event->type & (EVENT_HASHSIZE - 1);
935 : :
936 : 0 : hlist_add_head(&event->node, &event_hash[key]);
937 : :
938 : 0 : ret = event->type;
939 : : out:
940 : 0 : up_write(&trace_event_sem);
941 : :
942 : 0 : return ret;
943 : : }
944 : : EXPORT_SYMBOL_GPL(register_ftrace_event);
945 : :
946 : : /*
947 : : * Used by module code with the trace_event_sem held for write.
948 : : */
949 : 0 : int __unregister_ftrace_event(struct trace_event *event)
950 : : {
951 : : hlist_del(&event->node);
952 : : list_del(&event->list);
953 : 0 : return 0;
954 : : }
955 : :
956 : : /**
957 : : * unregister_ftrace_event - remove a no longer used event
958 : : * @event: the event to remove
959 : : */
960 : 0 : int unregister_ftrace_event(struct trace_event *event)
961 : : {
962 : 0 : down_write(&trace_event_sem);
963 : : __unregister_ftrace_event(event);
964 : 0 : up_write(&trace_event_sem);
965 : :
966 : 0 : return 0;
967 : : }
968 : : EXPORT_SYMBOL_GPL(unregister_ftrace_event);
969 : :
970 : : /*
971 : : * Standard events
972 : : */
973 : :
974 : 0 : enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags,
975 : : struct trace_event *event)
976 : : {
977 [ # # ]: 0 : if (!trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type))
978 : : return TRACE_TYPE_PARTIAL_LINE;
979 : :
980 : 0 : return TRACE_TYPE_HANDLED;
981 : : }
982 : :
983 : : /* TRACE_FN */
984 : 0 : static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,
985 : : struct trace_event *event)
986 : : {
987 : : struct ftrace_entry *field;
988 : 0 : struct trace_seq *s = &iter->seq;
989 : :
990 [ # # ]: 0 : trace_assign_type(field, iter->ent);
991 : :
992 [ # # ]: 0 : if (!seq_print_ip_sym(s, field->ip, flags))
993 : : goto partial;
994 : :
995 [ # # ][ # # ]: 0 : if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
996 [ # # ]: 0 : if (!trace_seq_puts(s, " <-"))
997 : : goto partial;
998 [ # # ]: 0 : if (!seq_print_ip_sym(s,
999 : : field->parent_ip,
1000 : : flags))
1001 : : goto partial;
1002 : : }
1003 [ # # ]: 0 : if (!trace_seq_putc(s, '\n'))
1004 : : goto partial;
1005 : :
1006 : : return TRACE_TYPE_HANDLED;
1007 : :
1008 : : partial:
1009 : : return TRACE_TYPE_PARTIAL_LINE;
1010 : : }
1011 : :
1012 : 0 : static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags,
1013 : : struct trace_event *event)
1014 : : {
1015 : : struct ftrace_entry *field;
1016 : :
1017 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1018 : :
1019 [ # # ]: 0 : if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
1020 : : field->ip,
1021 : : field->parent_ip))
1022 : : return TRACE_TYPE_PARTIAL_LINE;
1023 : :
1024 : 0 : return TRACE_TYPE_HANDLED;
1025 : : }
1026 : :
1027 : 0 : static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags,
1028 : : struct trace_event *event)
1029 : : {
1030 : : struct ftrace_entry *field;
1031 : 0 : struct trace_seq *s = &iter->seq;
1032 : :
1033 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1034 : :
1035 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->ip);
1036 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
1037 : :
1038 : 0 : return TRACE_TYPE_HANDLED;
1039 : : }
1040 : :
1041 : 0 : static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags,
1042 : : struct trace_event *event)
1043 : : {
1044 : : struct ftrace_entry *field;
1045 : 0 : struct trace_seq *s = &iter->seq;
1046 : :
1047 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1048 : :
1049 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->ip);
1050 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->parent_ip);
1051 : :
1052 : 0 : return TRACE_TYPE_HANDLED;
1053 : : }
1054 : :
1055 : : static struct trace_event_functions trace_fn_funcs = {
1056 : : .trace = trace_fn_trace,
1057 : : .raw = trace_fn_raw,
1058 : : .hex = trace_fn_hex,
1059 : : .binary = trace_fn_bin,
1060 : : };
1061 : :
1062 : : static struct trace_event trace_fn_event = {
1063 : : .type = TRACE_FN,
1064 : : .funcs = &trace_fn_funcs,
1065 : : };
1066 : :
1067 : : /* TRACE_GRAPH_ENT */
1068 : 0 : static enum print_line_t trace_graph_ent_trace(struct trace_iterator *iter, int flags,
1069 : : struct trace_event *event)
1070 : : {
1071 : 0 : struct trace_seq *s = &iter->seq;
1072 : : struct ftrace_graph_ent_entry *field;
1073 : :
1074 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1075 : :
1076 [ # # ]: 0 : if (!trace_seq_puts(s, "graph_ent: func="))
1077 : : return TRACE_TYPE_PARTIAL_LINE;
1078 : :
1079 [ # # ]: 0 : if (!seq_print_ip_sym(s, field->graph_ent.func, flags))
1080 : : return TRACE_TYPE_PARTIAL_LINE;
1081 : :
1082 [ # # ]: 0 : if (!trace_seq_puts(s, "\n"))
1083 : : return TRACE_TYPE_PARTIAL_LINE;
1084 : :
1085 : 0 : return TRACE_TYPE_HANDLED;
1086 : : }
1087 : :
1088 : 0 : static enum print_line_t trace_graph_ent_raw(struct trace_iterator *iter, int flags,
1089 : : struct trace_event *event)
1090 : : {
1091 : : struct ftrace_graph_ent_entry *field;
1092 : :
1093 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1094 : :
1095 [ # # ]: 0 : if (!trace_seq_printf(&iter->seq, "%lx %d\n",
1096 : : field->graph_ent.func,
1097 : : field->graph_ent.depth))
1098 : : return TRACE_TYPE_PARTIAL_LINE;
1099 : :
1100 : 0 : return TRACE_TYPE_HANDLED;
1101 : : }
1102 : :
1103 : 0 : static enum print_line_t trace_graph_ent_hex(struct trace_iterator *iter, int flags,
1104 : : struct trace_event *event)
1105 : : {
1106 : : struct ftrace_graph_ent_entry *field;
1107 : 0 : struct trace_seq *s = &iter->seq;
1108 : :
1109 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1110 : :
1111 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->graph_ent.func);
1112 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->graph_ent.depth);
1113 : :
1114 : 0 : return TRACE_TYPE_HANDLED;
1115 : : }
1116 : :
1117 : 0 : static enum print_line_t trace_graph_ent_bin(struct trace_iterator *iter, int flags,
1118 : : struct trace_event *event)
1119 : : {
1120 : : struct ftrace_graph_ent_entry *field;
1121 : 0 : struct trace_seq *s = &iter->seq;
1122 : :
1123 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1124 : :
1125 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->graph_ent.func);
1126 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->graph_ent.depth);
1127 : :
1128 : 0 : return TRACE_TYPE_HANDLED;
1129 : : }
1130 : :
1131 : : static struct trace_event_functions trace_graph_ent_funcs = {
1132 : : .trace = trace_graph_ent_trace,
1133 : : .raw = trace_graph_ent_raw,
1134 : : .hex = trace_graph_ent_hex,
1135 : : .binary = trace_graph_ent_bin,
1136 : : };
1137 : :
1138 : : static struct trace_event trace_graph_ent_event = {
1139 : : .type = TRACE_GRAPH_ENT,
1140 : : .funcs = &trace_graph_ent_funcs,
1141 : : };
1142 : :
1143 : : /* TRACE_GRAPH_RET */
1144 : 0 : static enum print_line_t trace_graph_ret_trace(struct trace_iterator *iter, int flags,
1145 : : struct trace_event *event)
1146 : : {
1147 : 0 : struct trace_seq *s = &iter->seq;
1148 : 0 : struct trace_entry *entry = iter->ent;
1149 : : struct ftrace_graph_ret_entry *field;
1150 : :
1151 [ # # ]: 0 : trace_assign_type(field, entry);
1152 : :
1153 [ # # ]: 0 : if (!trace_seq_puts(s, "graph_ret: func="))
1154 : : return TRACE_TYPE_PARTIAL_LINE;
1155 : :
1156 [ # # ]: 0 : if (!seq_print_ip_sym(s, field->ret.func, flags))
1157 : : return TRACE_TYPE_PARTIAL_LINE;
1158 : :
1159 [ # # ]: 0 : if (!trace_seq_puts(s, "\n"))
1160 : : return TRACE_TYPE_PARTIAL_LINE;
1161 : :
1162 : 0 : return TRACE_TYPE_HANDLED;
1163 : : }
1164 : :
1165 : 0 : static enum print_line_t trace_graph_ret_raw(struct trace_iterator *iter, int flags,
1166 : : struct trace_event *event)
1167 : : {
1168 : : struct ftrace_graph_ret_entry *field;
1169 : :
1170 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1171 : :
1172 : 0 : if (!trace_seq_printf(&iter->seq, "%lx %lld %lld %ld %d\n",
1173 : : field->ret.func,
1174 : : field->ret.calltime,
1175 : : field->ret.rettime,
1176 : : field->ret.overrun,
1177 : : field->ret.depth));
1178 : : return TRACE_TYPE_PARTIAL_LINE;
1179 : :
1180 : : return TRACE_TYPE_HANDLED;
1181 : : }
1182 : :
1183 : 0 : static enum print_line_t trace_graph_ret_hex(struct trace_iterator *iter, int flags,
1184 : : struct trace_event *event)
1185 : : {
1186 : : struct ftrace_graph_ret_entry *field;
1187 : 0 : struct trace_seq *s = &iter->seq;
1188 : :
1189 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1190 : :
1191 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->ret.func);
1192 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->ret.calltime);
1193 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->ret.rettime);
1194 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->ret.overrun);
1195 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->ret.depth);
1196 : :
1197 : 0 : return TRACE_TYPE_HANDLED;
1198 : : }
1199 : :
1200 : 0 : static enum print_line_t trace_graph_ret_bin(struct trace_iterator *iter, int flags,
1201 : : struct trace_event *event)
1202 : : {
1203 : : struct ftrace_graph_ret_entry *field;
1204 : 0 : struct trace_seq *s = &iter->seq;
1205 : :
1206 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1207 : :
1208 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->ret.func);
1209 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->ret.calltime);
1210 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->ret.rettime);
1211 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->ret.overrun);
1212 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->ret.depth);
1213 : :
1214 : 0 : return TRACE_TYPE_HANDLED;
1215 : : }
1216 : :
1217 : : static struct trace_event_functions trace_graph_ret_funcs = {
1218 : : .trace = trace_graph_ret_trace,
1219 : : .raw = trace_graph_ret_raw,
1220 : : .hex = trace_graph_ret_hex,
1221 : : .binary = trace_graph_ret_bin,
1222 : : };
1223 : :
1224 : : static struct trace_event trace_graph_ret_event = {
1225 : : .type = TRACE_GRAPH_RET,
1226 : : .funcs = &trace_graph_ret_funcs,
1227 : : };
1228 : :
1229 : : /* TRACE_CTX an TRACE_WAKE */
1230 : 0 : static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
1231 : : char *delim)
1232 : : {
1233 : : struct ctx_switch_entry *field;
1234 : : char comm[TASK_COMM_LEN];
1235 : : int S, T;
1236 : :
1237 : :
1238 : 0 : trace_assign_type(field, iter->ent);
1239 : :
1240 : 0 : T = task_state_char(field->next_state);
1241 : 0 : S = task_state_char(field->prev_state);
1242 : 0 : trace_find_cmdline(field->next_pid, comm);
1243 [ # # ]: 0 : if (!trace_seq_printf(&iter->seq,
1244 : : " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
1245 : : field->prev_pid,
1246 : 0 : field->prev_prio,
1247 : : S, delim,
1248 : : field->next_cpu,
1249 : : field->next_pid,
1250 : 0 : field->next_prio,
1251 : : T, comm))
1252 : : return TRACE_TYPE_PARTIAL_LINE;
1253 : :
1254 : 0 : return TRACE_TYPE_HANDLED;
1255 : : }
1256 : :
1257 : 0 : static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags,
1258 : : struct trace_event *event)
1259 : : {
1260 : 0 : return trace_ctxwake_print(iter, "==>");
1261 : : }
1262 : :
1263 : 0 : static enum print_line_t trace_wake_print(struct trace_iterator *iter,
1264 : : int flags, struct trace_event *event)
1265 : : {
1266 : 0 : return trace_ctxwake_print(iter, " +");
1267 : : }
1268 : :
1269 : 0 : static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
1270 : : {
1271 : : struct ctx_switch_entry *field;
1272 : : int T;
1273 : :
1274 : 0 : trace_assign_type(field, iter->ent);
1275 : :
1276 [ # # ]: 0 : if (!S)
1277 : 0 : S = task_state_char(field->prev_state);
1278 : 0 : T = task_state_char(field->next_state);
1279 [ # # ]: 0 : if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
1280 : : field->prev_pid,
1281 : 0 : field->prev_prio,
1282 : : S,
1283 : : field->next_cpu,
1284 : : field->next_pid,
1285 : 0 : field->next_prio,
1286 : : T))
1287 : : return TRACE_TYPE_PARTIAL_LINE;
1288 : :
1289 : 0 : return TRACE_TYPE_HANDLED;
1290 : : }
1291 : :
1292 : 0 : static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags,
1293 : : struct trace_event *event)
1294 : : {
1295 : 0 : return trace_ctxwake_raw(iter, 0);
1296 : : }
1297 : :
1298 : 0 : static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags,
1299 : : struct trace_event *event)
1300 : : {
1301 : 0 : return trace_ctxwake_raw(iter, '+');
1302 : : }
1303 : :
1304 : :
1305 : 0 : static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
1306 : : {
1307 : : struct ctx_switch_entry *field;
1308 : 0 : struct trace_seq *s = &iter->seq;
1309 : : int T;
1310 : :
1311 : 0 : trace_assign_type(field, iter->ent);
1312 : :
1313 [ # # ]: 0 : if (!S)
1314 : 0 : S = task_state_char(field->prev_state);
1315 : 0 : T = task_state_char(field->next_state);
1316 : :
1317 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
1318 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
1319 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, S);
1320 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
1321 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
1322 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
1323 [ # # ]: 0 : SEQ_PUT_HEX_FIELD_RET(s, T);
1324 : :
1325 : 0 : return TRACE_TYPE_HANDLED;
1326 : : }
1327 : :
1328 : 0 : static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags,
1329 : : struct trace_event *event)
1330 : : {
1331 : 0 : return trace_ctxwake_hex(iter, 0);
1332 : : }
1333 : :
1334 : 0 : static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags,
1335 : : struct trace_event *event)
1336 : : {
1337 : 0 : return trace_ctxwake_hex(iter, '+');
1338 : : }
1339 : :
1340 : 0 : static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
1341 : : int flags, struct trace_event *event)
1342 : : {
1343 : : struct ctx_switch_entry *field;
1344 : 0 : struct trace_seq *s = &iter->seq;
1345 : :
1346 : 0 : trace_assign_type(field, iter->ent);
1347 : :
1348 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->prev_pid);
1349 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->prev_prio);
1350 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->prev_state);
1351 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->next_pid);
1352 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->next_prio);
1353 [ # # ]: 0 : SEQ_PUT_FIELD_RET(s, field->next_state);
1354 : :
1355 : 0 : return TRACE_TYPE_HANDLED;
1356 : : }
1357 : :
1358 : : static struct trace_event_functions trace_ctx_funcs = {
1359 : : .trace = trace_ctx_print,
1360 : : .raw = trace_ctx_raw,
1361 : : .hex = trace_ctx_hex,
1362 : : .binary = trace_ctxwake_bin,
1363 : : };
1364 : :
1365 : : static struct trace_event trace_ctx_event = {
1366 : : .type = TRACE_CTX,
1367 : : .funcs = &trace_ctx_funcs,
1368 : : };
1369 : :
1370 : : static struct trace_event_functions trace_wake_funcs = {
1371 : : .trace = trace_wake_print,
1372 : : .raw = trace_wake_raw,
1373 : : .hex = trace_wake_hex,
1374 : : .binary = trace_ctxwake_bin,
1375 : : };
1376 : :
1377 : : static struct trace_event trace_wake_event = {
1378 : : .type = TRACE_WAKE,
1379 : : .funcs = &trace_wake_funcs,
1380 : : };
1381 : :
1382 : : /* TRACE_STACK */
1383 : :
1384 : 0 : static enum print_line_t trace_stack_print(struct trace_iterator *iter,
1385 : : int flags, struct trace_event *event)
1386 : : {
1387 : : struct stack_entry *field;
1388 : 0 : struct trace_seq *s = &iter->seq;
1389 : : unsigned long *p;
1390 : : unsigned long *end;
1391 : :
1392 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1393 : 0 : end = (unsigned long *)((long)iter->ent + iter->ent_size);
1394 : :
1395 [ # # ]: 0 : if (!trace_seq_puts(s, "<stack trace>\n"))
1396 : : goto partial;
1397 : :
1398 [ # # ][ # # ]: 0 : for (p = field->caller; p && *p != ULONG_MAX && p < end; p++) {
[ # # ]
1399 [ # # ]: 0 : if (!trace_seq_puts(s, " => "))
1400 : : goto partial;
1401 : :
1402 [ # # ]: 0 : if (!seq_print_ip_sym(s, *p, flags))
1403 : : goto partial;
1404 [ # # ]: 0 : if (!trace_seq_putc(s, '\n'))
1405 : : goto partial;
1406 : : }
1407 : :
1408 : : return TRACE_TYPE_HANDLED;
1409 : :
1410 : : partial:
1411 : : return TRACE_TYPE_PARTIAL_LINE;
1412 : : }
1413 : :
1414 : : static struct trace_event_functions trace_stack_funcs = {
1415 : : .trace = trace_stack_print,
1416 : : };
1417 : :
1418 : : static struct trace_event trace_stack_event = {
1419 : : .type = TRACE_STACK,
1420 : : .funcs = &trace_stack_funcs,
1421 : : };
1422 : :
1423 : : /* TRACE_USER_STACK */
1424 : 0 : static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
1425 : : int flags, struct trace_event *event)
1426 : : {
1427 : : struct userstack_entry *field;
1428 : 0 : struct trace_seq *s = &iter->seq;
1429 : :
1430 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1431 : :
1432 [ # # ]: 0 : if (!trace_seq_puts(s, "<user stack trace>\n"))
1433 : : goto partial;
1434 : :
1435 [ # # ]: 0 : if (!seq_print_userip_objs(field, s, flags))
1436 : : goto partial;
1437 : :
1438 : : return TRACE_TYPE_HANDLED;
1439 : :
1440 : : partial:
1441 : : return TRACE_TYPE_PARTIAL_LINE;
1442 : : }
1443 : :
1444 : : static struct trace_event_functions trace_user_stack_funcs = {
1445 : : .trace = trace_user_stack_print,
1446 : : };
1447 : :
1448 : : static struct trace_event trace_user_stack_event = {
1449 : : .type = TRACE_USER_STACK,
1450 : : .funcs = &trace_user_stack_funcs,
1451 : : };
1452 : :
1453 : : /* TRACE_BPUTS */
1454 : : static enum print_line_t
1455 : 0 : trace_bputs_print(struct trace_iterator *iter, int flags,
1456 : : struct trace_event *event)
1457 : : {
1458 : 0 : struct trace_entry *entry = iter->ent;
1459 : 0 : struct trace_seq *s = &iter->seq;
1460 : : struct bputs_entry *field;
1461 : :
1462 [ # # ]: 0 : trace_assign_type(field, entry);
1463 : :
1464 [ # # ]: 0 : if (!seq_print_ip_sym(s, field->ip, flags))
1465 : : goto partial;
1466 : :
1467 [ # # ]: 0 : if (!trace_seq_puts(s, ": "))
1468 : : goto partial;
1469 : :
1470 [ # # ]: 0 : if (!trace_seq_puts(s, field->str))
1471 : : goto partial;
1472 : :
1473 : : return TRACE_TYPE_HANDLED;
1474 : :
1475 : : partial:
1476 : : return TRACE_TYPE_PARTIAL_LINE;
1477 : : }
1478 : :
1479 : :
1480 : : static enum print_line_t
1481 : 0 : trace_bputs_raw(struct trace_iterator *iter, int flags,
1482 : : struct trace_event *event)
1483 : : {
1484 : : struct bputs_entry *field;
1485 : 0 : struct trace_seq *s = &iter->seq;
1486 : :
1487 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1488 : :
1489 [ # # ]: 0 : if (!trace_seq_printf(s, ": %lx : ", field->ip))
1490 : : goto partial;
1491 : :
1492 [ # # ]: 0 : if (!trace_seq_puts(s, field->str))
1493 : : goto partial;
1494 : :
1495 : : return TRACE_TYPE_HANDLED;
1496 : :
1497 : : partial:
1498 : : return TRACE_TYPE_PARTIAL_LINE;
1499 : : }
1500 : :
1501 : : static struct trace_event_functions trace_bputs_funcs = {
1502 : : .trace = trace_bputs_print,
1503 : : .raw = trace_bputs_raw,
1504 : : };
1505 : :
1506 : : static struct trace_event trace_bputs_event = {
1507 : : .type = TRACE_BPUTS,
1508 : : .funcs = &trace_bputs_funcs,
1509 : : };
1510 : :
1511 : : /* TRACE_BPRINT */
1512 : : static enum print_line_t
1513 : 0 : trace_bprint_print(struct trace_iterator *iter, int flags,
1514 : : struct trace_event *event)
1515 : : {
1516 : 0 : struct trace_entry *entry = iter->ent;
1517 : 0 : struct trace_seq *s = &iter->seq;
1518 : : struct bprint_entry *field;
1519 : :
1520 [ # # ]: 0 : trace_assign_type(field, entry);
1521 : :
1522 [ # # ]: 0 : if (!seq_print_ip_sym(s, field->ip, flags))
1523 : : goto partial;
1524 : :
1525 [ # # ]: 0 : if (!trace_seq_puts(s, ": "))
1526 : : goto partial;
1527 : :
1528 [ # # ]: 0 : if (!trace_seq_bprintf(s, field->fmt, field->buf))
1529 : : goto partial;
1530 : :
1531 : : return TRACE_TYPE_HANDLED;
1532 : :
1533 : : partial:
1534 : : return TRACE_TYPE_PARTIAL_LINE;
1535 : : }
1536 : :
1537 : :
1538 : : static enum print_line_t
1539 : 0 : trace_bprint_raw(struct trace_iterator *iter, int flags,
1540 : : struct trace_event *event)
1541 : : {
1542 : : struct bprint_entry *field;
1543 : 0 : struct trace_seq *s = &iter->seq;
1544 : :
1545 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1546 : :
1547 [ # # ]: 0 : if (!trace_seq_printf(s, ": %lx : ", field->ip))
1548 : : goto partial;
1549 : :
1550 [ # # ]: 0 : if (!trace_seq_bprintf(s, field->fmt, field->buf))
1551 : : goto partial;
1552 : :
1553 : : return TRACE_TYPE_HANDLED;
1554 : :
1555 : : partial:
1556 : : return TRACE_TYPE_PARTIAL_LINE;
1557 : : }
1558 : :
1559 : : static struct trace_event_functions trace_bprint_funcs = {
1560 : : .trace = trace_bprint_print,
1561 : : .raw = trace_bprint_raw,
1562 : : };
1563 : :
1564 : : static struct trace_event trace_bprint_event = {
1565 : : .type = TRACE_BPRINT,
1566 : : .funcs = &trace_bprint_funcs,
1567 : : };
1568 : :
1569 : : /* TRACE_PRINT */
1570 : 0 : static enum print_line_t trace_print_print(struct trace_iterator *iter,
1571 : : int flags, struct trace_event *event)
1572 : : {
1573 : : struct print_entry *field;
1574 : 0 : struct trace_seq *s = &iter->seq;
1575 : :
1576 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1577 : :
1578 [ # # ]: 0 : if (!seq_print_ip_sym(s, field->ip, flags))
1579 : : goto partial;
1580 : :
1581 [ # # ]: 0 : if (!trace_seq_printf(s, ": %s", field->buf))
1582 : : goto partial;
1583 : :
1584 : : return TRACE_TYPE_HANDLED;
1585 : :
1586 : : partial:
1587 : : return TRACE_TYPE_PARTIAL_LINE;
1588 : : }
1589 : :
1590 : 0 : static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags,
1591 : : struct trace_event *event)
1592 : : {
1593 : : struct print_entry *field;
1594 : :
1595 [ # # ]: 0 : trace_assign_type(field, iter->ent);
1596 : :
1597 [ # # ]: 0 : if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
1598 : : goto partial;
1599 : :
1600 : : return TRACE_TYPE_HANDLED;
1601 : :
1602 : : partial:
1603 : 0 : return TRACE_TYPE_PARTIAL_LINE;
1604 : : }
1605 : :
1606 : : static struct trace_event_functions trace_print_funcs = {
1607 : : .trace = trace_print_print,
1608 : : .raw = trace_print_raw,
1609 : : };
1610 : :
1611 : : static struct trace_event trace_print_event = {
1612 : : .type = TRACE_PRINT,
1613 : : .funcs = &trace_print_funcs,
1614 : : };
1615 : :
1616 : :
1617 : : static struct trace_event *events[] __initdata = {
1618 : : &trace_fn_event,
1619 : : &trace_graph_ent_event,
1620 : : &trace_graph_ret_event,
1621 : : &trace_ctx_event,
1622 : : &trace_wake_event,
1623 : : &trace_stack_event,
1624 : : &trace_user_stack_event,
1625 : : &trace_bputs_event,
1626 : : &trace_bprint_event,
1627 : : &trace_print_event,
1628 : : NULL
1629 : : };
1630 : :
1631 : 0 : __init static int init_events(void)
1632 : : {
1633 : : struct trace_event *event;
1634 : : int i, ret;
1635 : :
1636 [ # # ]: 0 : for (i = 0; events[i]; i++) {
1637 : : event = events[i];
1638 : :
1639 : 0 : ret = register_ftrace_event(event);
1640 [ # # ]: 0 : if (!ret) {
1641 : 0 : printk(KERN_WARNING "event %d failed to register\n",
1642 : : event->type);
1643 [ # # ][ # # ]: 0 : WARN_ON_ONCE(1);
1644 : : }
1645 : : }
1646 : :
1647 : 0 : return 0;
1648 : : }
1649 : : early_initcall(init_events);
|