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