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