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