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