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