ftrace: ensure every event gets an id
[pandora-kernel.git] / kernel / trace / trace_output.c
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 static DEFINE_MUTEX(trace_event_mutex);
18 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
19
20 static int next_event_type = __TRACE_LAST_TYPE + 1;
21
22 enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
23 {
24         struct trace_seq *s = &iter->seq;
25         struct trace_entry *entry = iter->ent;
26         struct bprint_entry *field;
27         int ret;
28
29         trace_assign_type(field, entry);
30
31         ret = trace_seq_bprintf(s, field->fmt, field->buf);
32         if (!ret)
33                 return TRACE_TYPE_PARTIAL_LINE;
34
35         return TRACE_TYPE_HANDLED;
36 }
37
38 enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
39 {
40         struct trace_seq *s = &iter->seq;
41         struct trace_entry *entry = iter->ent;
42         struct print_entry *field;
43         int ret;
44
45         trace_assign_type(field, entry);
46
47         ret = trace_seq_printf(s, "%s", field->buf);
48         if (!ret)
49                 return TRACE_TYPE_PARTIAL_LINE;
50
51         return TRACE_TYPE_HANDLED;
52 }
53
54 /**
55  * trace_seq_printf - sequence printing of trace information
56  * @s: trace sequence descriptor
57  * @fmt: printf format string
58  *
59  * The tracer may use either sequence operations or its own
60  * copy to user routines. To simplify formating of a trace
61  * trace_seq_printf is used to store strings into a special
62  * buffer (@s). Then the output may be either used by
63  * the sequencer or pulled into another buffer.
64  */
65 int
66 trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
67 {
68         int len = (PAGE_SIZE - 1) - s->len;
69         va_list ap;
70         int ret;
71
72         if (!len)
73                 return 0;
74
75         va_start(ap, fmt);
76         ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
77         va_end(ap);
78
79         /* If we can't write it all, don't bother writing anything */
80         if (ret >= len)
81                 return 0;
82
83         s->len += ret;
84
85         return len;
86 }
87
88 int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
89 {
90         int len = (PAGE_SIZE - 1) - s->len;
91         int ret;
92
93         if (!len)
94                 return 0;
95
96         ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
97
98         /* If we can't write it all, don't bother writing anything */
99         if (ret >= len)
100                 return 0;
101
102         s->len += ret;
103
104         return len;
105 }
106
107 /**
108  * trace_seq_puts - trace sequence printing of simple string
109  * @s: trace sequence descriptor
110  * @str: simple string to record
111  *
112  * The tracer may use either the sequence operations or its own
113  * copy to user routines. This function records a simple string
114  * into a special buffer (@s) for later retrieval by a sequencer
115  * or other mechanism.
116  */
117 int trace_seq_puts(struct trace_seq *s, const char *str)
118 {
119         int len = strlen(str);
120
121         if (len > ((PAGE_SIZE - 1) - s->len))
122                 return 0;
123
124         memcpy(s->buffer + s->len, str, len);
125         s->len += len;
126
127         return len;
128 }
129
130 int trace_seq_putc(struct trace_seq *s, unsigned char c)
131 {
132         if (s->len >= (PAGE_SIZE - 1))
133                 return 0;
134
135         s->buffer[s->len++] = c;
136
137         return 1;
138 }
139
140 int trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
141 {
142         if (len > ((PAGE_SIZE - 1) - s->len))
143                 return 0;
144
145         memcpy(s->buffer + s->len, mem, len);
146         s->len += len;
147
148         return len;
149 }
150
151 int trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
152 {
153         unsigned char hex[HEX_CHARS];
154         unsigned char *data = mem;
155         int i, j;
156
157 #ifdef __BIG_ENDIAN
158         for (i = 0, j = 0; i < len; i++) {
159 #else
160         for (i = len-1, j = 0; i >= 0; i--) {
161 #endif
162                 hex[j++] = hex_asc_hi(data[i]);
163                 hex[j++] = hex_asc_lo(data[i]);
164         }
165         hex[j++] = ' ';
166
167         return trace_seq_putmem(s, hex, j);
168 }
169
170 int trace_seq_path(struct trace_seq *s, struct path *path)
171 {
172         unsigned char *p;
173
174         if (s->len >= (PAGE_SIZE - 1))
175                 return 0;
176         p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
177         if (!IS_ERR(p)) {
178                 p = mangle_path(s->buffer + s->len, p, "\n");
179                 if (p) {
180                         s->len = p - s->buffer;
181                         return 1;
182                 }
183         } else {
184                 s->buffer[s->len++] = '?';
185                 return 1;
186         }
187
188         return 0;
189 }
190
191 #ifdef CONFIG_KRETPROBES
192 static inline const char *kretprobed(const char *name)
193 {
194         static const char tramp_name[] = "kretprobe_trampoline";
195         int size = sizeof(tramp_name);
196
197         if (strncmp(tramp_name, name, size) == 0)
198                 return "[unknown/kretprobe'd]";
199         return name;
200 }
201 #else
202 static inline const char *kretprobed(const char *name)
203 {
204         return name;
205 }
206 #endif /* CONFIG_KRETPROBES */
207
208 static int
209 seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
210 {
211 #ifdef CONFIG_KALLSYMS
212         char str[KSYM_SYMBOL_LEN];
213         const char *name;
214
215         kallsyms_lookup(address, NULL, NULL, NULL, str);
216
217         name = kretprobed(str);
218
219         return trace_seq_printf(s, fmt, name);
220 #endif
221         return 1;
222 }
223
224 static int
225 seq_print_sym_offset(struct trace_seq *s, const char *fmt,
226                      unsigned long address)
227 {
228 #ifdef CONFIG_KALLSYMS
229         char str[KSYM_SYMBOL_LEN];
230         const char *name;
231
232         sprint_symbol(str, address);
233         name = kretprobed(str);
234
235         return trace_seq_printf(s, fmt, name);
236 #endif
237         return 1;
238 }
239
240 #ifndef CONFIG_64BIT
241 # define IP_FMT "%08lx"
242 #else
243 # define IP_FMT "%016lx"
244 #endif
245
246 int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
247                       unsigned long ip, unsigned long sym_flags)
248 {
249         struct file *file = NULL;
250         unsigned long vmstart = 0;
251         int ret = 1;
252
253         if (mm) {
254                 const struct vm_area_struct *vma;
255
256                 down_read(&mm->mmap_sem);
257                 vma = find_vma(mm, ip);
258                 if (vma) {
259                         file = vma->vm_file;
260                         vmstart = vma->vm_start;
261                 }
262                 if (file) {
263                         ret = trace_seq_path(s, &file->f_path);
264                         if (ret)
265                                 ret = trace_seq_printf(s, "[+0x%lx]",
266                                                        ip - vmstart);
267                 }
268                 up_read(&mm->mmap_sem);
269         }
270         if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
271                 ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
272         return ret;
273 }
274
275 int
276 seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
277                       unsigned long sym_flags)
278 {
279         struct mm_struct *mm = NULL;
280         int ret = 1;
281         unsigned int i;
282
283         if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
284                 struct task_struct *task;
285                 /*
286                  * we do the lookup on the thread group leader,
287                  * since individual threads might have already quit!
288                  */
289                 rcu_read_lock();
290                 task = find_task_by_vpid(entry->ent.tgid);
291                 if (task)
292                         mm = get_task_mm(task);
293                 rcu_read_unlock();
294         }
295
296         for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
297                 unsigned long ip = entry->caller[i];
298
299                 if (ip == ULONG_MAX || !ret)
300                         break;
301                 if (i && ret)
302                         ret = trace_seq_puts(s, " <- ");
303                 if (!ip) {
304                         if (ret)
305                                 ret = trace_seq_puts(s, "??");
306                         continue;
307                 }
308                 if (!ret)
309                         break;
310                 if (ret)
311                         ret = seq_print_user_ip(s, mm, ip, sym_flags);
312         }
313
314         if (mm)
315                 mmput(mm);
316         return ret;
317 }
318
319 int
320 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
321 {
322         int ret;
323
324         if (!ip)
325                 return trace_seq_printf(s, "0");
326
327         if (sym_flags & TRACE_ITER_SYM_OFFSET)
328                 ret = seq_print_sym_offset(s, "%s", ip);
329         else
330                 ret = seq_print_sym_short(s, "%s", ip);
331
332         if (!ret)
333                 return 0;
334
335         if (sym_flags & TRACE_ITER_SYM_ADDR)
336                 ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
337         return ret;
338 }
339
340 static int
341 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
342 {
343         int hardirq, softirq;
344         char comm[TASK_COMM_LEN];
345
346         trace_find_cmdline(entry->pid, comm);
347         hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
348         softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
349
350         if (!trace_seq_printf(s, "%8.8s-%-5d %3d%c%c%c",
351                               comm, entry->pid, cpu,
352                               (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
353                                 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
354                                   'X' : '.',
355                               (entry->flags & TRACE_FLAG_NEED_RESCHED) ?
356                                 'N' : '.',
357                               (hardirq && softirq) ? 'H' :
358                                 hardirq ? 'h' : softirq ? 's' : '.'))
359                 return 0;
360
361         if (entry->preempt_count)
362                 return trace_seq_printf(s, "%x", entry->preempt_count);
363         return trace_seq_puts(s, ".");
364 }
365
366 static unsigned long preempt_mark_thresh = 100;
367
368 static int
369 lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
370                     unsigned long rel_usecs)
371 {
372         return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
373                                 rel_usecs > preempt_mark_thresh ? '!' :
374                                   rel_usecs > 1 ? '+' : ' ');
375 }
376
377 int trace_print_context(struct trace_iterator *iter)
378 {
379         struct trace_seq *s = &iter->seq;
380         struct trace_entry *entry = iter->ent;
381         unsigned long long t = ns2usecs(iter->ts);
382         unsigned long usec_rem = do_div(t, USEC_PER_SEC);
383         unsigned long secs = (unsigned long)t;
384         char comm[TASK_COMM_LEN];
385
386         trace_find_cmdline(entry->pid, comm);
387
388         return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ",
389                                 comm, entry->pid, iter->cpu, secs, usec_rem);
390 }
391
392 int trace_print_lat_context(struct trace_iterator *iter)
393 {
394         u64 next_ts;
395         int ret;
396         struct trace_seq *s = &iter->seq;
397         struct trace_entry *entry = iter->ent,
398                            *next_entry = trace_find_next_entry(iter, NULL,
399                                                                &next_ts);
400         unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
401         unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
402         unsigned long rel_usecs;
403
404         if (!next_entry)
405                 next_ts = iter->ts;
406         rel_usecs = ns2usecs(next_ts - iter->ts);
407
408         if (verbose) {
409                 char comm[TASK_COMM_LEN];
410
411                 trace_find_cmdline(entry->pid, comm);
412
413                 ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
414                                        " %ld.%03ldms (+%ld.%03ldms): ", comm,
415                                        entry->pid, iter->cpu, entry->flags,
416                                        entry->preempt_count, iter->idx,
417                                        ns2usecs(iter->ts),
418                                        abs_usecs / USEC_PER_MSEC,
419                                        abs_usecs % USEC_PER_MSEC,
420                                        rel_usecs / USEC_PER_MSEC,
421                                        rel_usecs % USEC_PER_MSEC);
422         } else {
423                 ret = lat_print_generic(s, entry, iter->cpu);
424                 if (ret)
425                         ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
426         }
427
428         return ret;
429 }
430
431 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
432
433 static int task_state_char(unsigned long state)
434 {
435         int bit = state ? __ffs(state) + 1 : 0;
436
437         return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
438 }
439
440 /**
441  * ftrace_find_event - find a registered event
442  * @type: the type of event to look for
443  *
444  * Returns an event of type @type otherwise NULL
445  */
446 struct trace_event *ftrace_find_event(int type)
447 {
448         struct trace_event *event;
449         struct hlist_node *n;
450         unsigned key;
451
452         key = type & (EVENT_HASHSIZE - 1);
453
454         hlist_for_each_entry_rcu(event, n, &event_hash[key], node) {
455                 if (event->type == type)
456                         return event;
457         }
458
459         return NULL;
460 }
461
462 /**
463  * register_ftrace_event - register output for an event type
464  * @event: the event type to register
465  *
466  * Event types are stored in a hash and this hash is used to
467  * find a way to print an event. If the @event->type is set
468  * then it will use that type, otherwise it will assign a
469  * type to use.
470  *
471  * If you assign your own type, please make sure it is added
472  * to the trace_type enum in trace.h, to avoid collisions
473  * with the dynamic types.
474  *
475  * Returns the event type number or zero on error.
476  */
477 int register_ftrace_event(struct trace_event *event)
478 {
479         unsigned key;
480         int ret = 0;
481
482         mutex_lock(&trace_event_mutex);
483
484         if (!event) {
485                 ret = next_event_type++;
486                 goto out;
487         }
488
489         if (!event->type)
490                 event->type = next_event_type++;
491         else if (event->type > __TRACE_LAST_TYPE) {
492                 printk(KERN_WARNING "Need to add type to trace.h\n");
493                 WARN_ON(1);
494         }
495
496         if (ftrace_find_event(event->type))
497                 goto out;
498
499         if (event->trace == NULL)
500                 event->trace = trace_nop_print;
501         if (event->raw == NULL)
502                 event->raw = trace_nop_print;
503         if (event->hex == NULL)
504                 event->hex = trace_nop_print;
505         if (event->binary == NULL)
506                 event->binary = trace_nop_print;
507
508         key = event->type & (EVENT_HASHSIZE - 1);
509
510         hlist_add_head_rcu(&event->node, &event_hash[key]);
511
512         ret = event->type;
513  out:
514         mutex_unlock(&trace_event_mutex);
515
516         return ret;
517 }
518
519 /**
520  * unregister_ftrace_event - remove a no longer used event
521  * @event: the event to remove
522  */
523 int unregister_ftrace_event(struct trace_event *event)
524 {
525         mutex_lock(&trace_event_mutex);
526         hlist_del(&event->node);
527         mutex_unlock(&trace_event_mutex);
528
529         return 0;
530 }
531
532 /*
533  * Standard events
534  */
535
536 enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags)
537 {
538         return TRACE_TYPE_HANDLED;
539 }
540
541 /* TRACE_FN */
542 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags)
543 {
544         struct ftrace_entry *field;
545         struct trace_seq *s = &iter->seq;
546
547         trace_assign_type(field, iter->ent);
548
549         if (!seq_print_ip_sym(s, field->ip, flags))
550                 goto partial;
551
552         if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
553                 if (!trace_seq_printf(s, " <-"))
554                         goto partial;
555                 if (!seq_print_ip_sym(s,
556                                       field->parent_ip,
557                                       flags))
558                         goto partial;
559         }
560         if (!trace_seq_printf(s, "\n"))
561                 goto partial;
562
563         return TRACE_TYPE_HANDLED;
564
565  partial:
566         return TRACE_TYPE_PARTIAL_LINE;
567 }
568
569 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags)
570 {
571         struct ftrace_entry *field;
572
573         trace_assign_type(field, iter->ent);
574
575         if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
576                               field->ip,
577                               field->parent_ip))
578                 return TRACE_TYPE_PARTIAL_LINE;
579
580         return TRACE_TYPE_HANDLED;
581 }
582
583 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags)
584 {
585         struct ftrace_entry *field;
586         struct trace_seq *s = &iter->seq;
587
588         trace_assign_type(field, iter->ent);
589
590         SEQ_PUT_HEX_FIELD_RET(s, field->ip);
591         SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
592
593         return TRACE_TYPE_HANDLED;
594 }
595
596 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags)
597 {
598         struct ftrace_entry *field;
599         struct trace_seq *s = &iter->seq;
600
601         trace_assign_type(field, iter->ent);
602
603         SEQ_PUT_FIELD_RET(s, field->ip);
604         SEQ_PUT_FIELD_RET(s, field->parent_ip);
605
606         return TRACE_TYPE_HANDLED;
607 }
608
609 static struct trace_event trace_fn_event = {
610         .type           = TRACE_FN,
611         .trace          = trace_fn_trace,
612         .raw            = trace_fn_raw,
613         .hex            = trace_fn_hex,
614         .binary         = trace_fn_bin,
615 };
616
617 /* TRACE_CTX an TRACE_WAKE */
618 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
619                                              char *delim)
620 {
621         struct ctx_switch_entry *field;
622         char comm[TASK_COMM_LEN];
623         int S, T;
624
625
626         trace_assign_type(field, iter->ent);
627
628         T = task_state_char(field->next_state);
629         S = task_state_char(field->prev_state);
630         trace_find_cmdline(field->next_pid, comm);
631         if (!trace_seq_printf(&iter->seq,
632                               " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
633                               field->prev_pid,
634                               field->prev_prio,
635                               S, delim,
636                               field->next_cpu,
637                               field->next_pid,
638                               field->next_prio,
639                               T, comm))
640                 return TRACE_TYPE_PARTIAL_LINE;
641
642         return TRACE_TYPE_HANDLED;
643 }
644
645 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags)
646 {
647         return trace_ctxwake_print(iter, "==>");
648 }
649
650 static enum print_line_t trace_wake_print(struct trace_iterator *iter,
651                                           int flags)
652 {
653         return trace_ctxwake_print(iter, "  +");
654 }
655
656 static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
657 {
658         struct ctx_switch_entry *field;
659         int T;
660
661         trace_assign_type(field, iter->ent);
662
663         if (!S)
664                 task_state_char(field->prev_state);
665         T = task_state_char(field->next_state);
666         if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
667                               field->prev_pid,
668                               field->prev_prio,
669                               S,
670                               field->next_cpu,
671                               field->next_pid,
672                               field->next_prio,
673                               T))
674                 return TRACE_TYPE_PARTIAL_LINE;
675
676         return TRACE_TYPE_HANDLED;
677 }
678
679 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags)
680 {
681         return trace_ctxwake_raw(iter, 0);
682 }
683
684 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags)
685 {
686         return trace_ctxwake_raw(iter, '+');
687 }
688
689
690 static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
691 {
692         struct ctx_switch_entry *field;
693         struct trace_seq *s = &iter->seq;
694         int T;
695
696         trace_assign_type(field, iter->ent);
697
698         if (!S)
699                 task_state_char(field->prev_state);
700         T = task_state_char(field->next_state);
701
702         SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
703         SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
704         SEQ_PUT_HEX_FIELD_RET(s, S);
705         SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
706         SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
707         SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
708         SEQ_PUT_HEX_FIELD_RET(s, T);
709
710         return TRACE_TYPE_HANDLED;
711 }
712
713 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags)
714 {
715         return trace_ctxwake_hex(iter, 0);
716 }
717
718 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags)
719 {
720         return trace_ctxwake_hex(iter, '+');
721 }
722
723 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
724                                            int flags)
725 {
726         struct ctx_switch_entry *field;
727         struct trace_seq *s = &iter->seq;
728
729         trace_assign_type(field, iter->ent);
730
731         SEQ_PUT_FIELD_RET(s, field->prev_pid);
732         SEQ_PUT_FIELD_RET(s, field->prev_prio);
733         SEQ_PUT_FIELD_RET(s, field->prev_state);
734         SEQ_PUT_FIELD_RET(s, field->next_pid);
735         SEQ_PUT_FIELD_RET(s, field->next_prio);
736         SEQ_PUT_FIELD_RET(s, field->next_state);
737
738         return TRACE_TYPE_HANDLED;
739 }
740
741 static struct trace_event trace_ctx_event = {
742         .type           = TRACE_CTX,
743         .trace          = trace_ctx_print,
744         .raw            = trace_ctx_raw,
745         .hex            = trace_ctx_hex,
746         .binary         = trace_ctxwake_bin,
747 };
748
749 static struct trace_event trace_wake_event = {
750         .type           = TRACE_WAKE,
751         .trace          = trace_wake_print,
752         .raw            = trace_wake_raw,
753         .hex            = trace_wake_hex,
754         .binary         = trace_ctxwake_bin,
755 };
756
757 /* TRACE_SPECIAL */
758 static enum print_line_t trace_special_print(struct trace_iterator *iter,
759                                              int flags)
760 {
761         struct special_entry *field;
762
763         trace_assign_type(field, iter->ent);
764
765         if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
766                               field->arg1,
767                               field->arg2,
768                               field->arg3))
769                 return TRACE_TYPE_PARTIAL_LINE;
770
771         return TRACE_TYPE_HANDLED;
772 }
773
774 static enum print_line_t trace_special_hex(struct trace_iterator *iter,
775                                            int flags)
776 {
777         struct special_entry *field;
778         struct trace_seq *s = &iter->seq;
779
780         trace_assign_type(field, iter->ent);
781
782         SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
783         SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
784         SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
785
786         return TRACE_TYPE_HANDLED;
787 }
788
789 static enum print_line_t trace_special_bin(struct trace_iterator *iter,
790                                            int flags)
791 {
792         struct special_entry *field;
793         struct trace_seq *s = &iter->seq;
794
795         trace_assign_type(field, iter->ent);
796
797         SEQ_PUT_FIELD_RET(s, field->arg1);
798         SEQ_PUT_FIELD_RET(s, field->arg2);
799         SEQ_PUT_FIELD_RET(s, field->arg3);
800
801         return TRACE_TYPE_HANDLED;
802 }
803
804 static struct trace_event trace_special_event = {
805         .type           = TRACE_SPECIAL,
806         .trace          = trace_special_print,
807         .raw            = trace_special_print,
808         .hex            = trace_special_hex,
809         .binary         = trace_special_bin,
810 };
811
812 /* TRACE_STACK */
813
814 static enum print_line_t trace_stack_print(struct trace_iterator *iter,
815                                            int flags)
816 {
817         struct stack_entry *field;
818         struct trace_seq *s = &iter->seq;
819         int i;
820
821         trace_assign_type(field, iter->ent);
822
823         for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
824                 if (i) {
825                         if (!trace_seq_puts(s, " <= "))
826                                 goto partial;
827
828                         if (!seq_print_ip_sym(s, field->caller[i], flags))
829                                 goto partial;
830                 }
831                 if (!trace_seq_puts(s, "\n"))
832                         goto partial;
833         }
834
835         return TRACE_TYPE_HANDLED;
836
837  partial:
838         return TRACE_TYPE_PARTIAL_LINE;
839 }
840
841 static struct trace_event trace_stack_event = {
842         .type           = TRACE_STACK,
843         .trace          = trace_stack_print,
844         .raw            = trace_special_print,
845         .hex            = trace_special_hex,
846         .binary         = trace_special_bin,
847 };
848
849 /* TRACE_USER_STACK */
850 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
851                                                 int flags)
852 {
853         struct userstack_entry *field;
854         struct trace_seq *s = &iter->seq;
855
856         trace_assign_type(field, iter->ent);
857
858         if (!seq_print_userip_objs(field, s, flags))
859                 goto partial;
860
861         if (!trace_seq_putc(s, '\n'))
862                 goto partial;
863
864         return TRACE_TYPE_HANDLED;
865
866  partial:
867         return TRACE_TYPE_PARTIAL_LINE;
868 }
869
870 static struct trace_event trace_user_stack_event = {
871         .type           = TRACE_USER_STACK,
872         .trace          = trace_user_stack_print,
873         .raw            = trace_special_print,
874         .hex            = trace_special_hex,
875         .binary         = trace_special_bin,
876 };
877
878 /* TRACE_BPRINT */
879 static enum print_line_t
880 trace_bprint_print(struct trace_iterator *iter, int flags)
881 {
882         struct trace_entry *entry = iter->ent;
883         struct trace_seq *s = &iter->seq;
884         struct bprint_entry *field;
885
886         trace_assign_type(field, entry);
887
888         if (!seq_print_ip_sym(s, field->ip, flags))
889                 goto partial;
890
891         if (!trace_seq_puts(s, ": "))
892                 goto partial;
893
894         if (!trace_seq_bprintf(s, field->fmt, field->buf))
895                 goto partial;
896
897         return TRACE_TYPE_HANDLED;
898
899  partial:
900         return TRACE_TYPE_PARTIAL_LINE;
901 }
902
903
904 static enum print_line_t
905 trace_bprint_raw(struct trace_iterator *iter, int flags)
906 {
907         struct bprint_entry *field;
908         struct trace_seq *s = &iter->seq;
909
910         trace_assign_type(field, iter->ent);
911
912         if (!trace_seq_printf(s, ": %lx : ", field->ip))
913                 goto partial;
914
915         if (!trace_seq_bprintf(s, field->fmt, field->buf))
916                 goto partial;
917
918         return TRACE_TYPE_HANDLED;
919
920  partial:
921         return TRACE_TYPE_PARTIAL_LINE;
922 }
923
924
925 static struct trace_event trace_bprint_event = {
926         .type           = TRACE_BPRINT,
927         .trace          = trace_bprint_print,
928         .raw            = trace_bprint_raw,
929 };
930
931 /* TRACE_PRINT */
932 static enum print_line_t trace_print_print(struct trace_iterator *iter,
933                                            int flags)
934 {
935         struct print_entry *field;
936         struct trace_seq *s = &iter->seq;
937
938         trace_assign_type(field, iter->ent);
939
940         if (!seq_print_ip_sym(s, field->ip, flags))
941                 goto partial;
942
943         if (!trace_seq_printf(s, ": %s", field->buf))
944                 goto partial;
945
946         return TRACE_TYPE_HANDLED;
947
948  partial:
949         return TRACE_TYPE_PARTIAL_LINE;
950 }
951
952 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
953 {
954         struct print_entry *field;
955
956         trace_assign_type(field, iter->ent);
957
958         if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
959                 goto partial;
960
961         return TRACE_TYPE_HANDLED;
962
963  partial:
964         return TRACE_TYPE_PARTIAL_LINE;
965 }
966
967 static struct trace_event trace_print_event = {
968         .type           = TRACE_PRINT,
969         .trace          = trace_print_print,
970         .raw            = trace_print_raw,
971 };
972
973
974 static struct trace_event *events[] __initdata = {
975         &trace_fn_event,
976         &trace_ctx_event,
977         &trace_wake_event,
978         &trace_special_event,
979         &trace_stack_event,
980         &trace_user_stack_event,
981         &trace_bprint_event,
982         &trace_print_event,
983         NULL
984 };
985
986 __init static int init_events(void)
987 {
988         struct trace_event *event;
989         int i, ret;
990
991         for (i = 0; events[i]; i++) {
992                 event = events[i];
993
994                 ret = register_ftrace_event(event);
995                 if (!ret) {
996                         printk(KERN_WARNING "event %d failed to register\n",
997                                event->type);
998                         WARN_ON_ONCE(1);
999                 }
1000         }
1001
1002         return 0;
1003 }
1004 device_initcall(init_events);