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