Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
trace_output.c
Go to the documentation of this file.
1 /*
2  * trace_output.c
3  *
4  * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <[email protected]>
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 DECLARE_RWSEM(trace_event_mutex);
18 
19 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
20 
21 static int next_event_type = __TRACE_LAST_TYPE + 1;
22 
23 int trace_print_seq(struct seq_file *m, struct trace_seq *s)
24 {
25  int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
26  int ret;
27 
28  ret = seq_write(m, s->buffer, len);
29 
30  /*
31  * Only reset this buffer if we successfully wrote to the
32  * seq_file buffer.
33  */
34  if (!ret)
35  trace_seq_init(s);
36 
37  return ret;
38 }
39 
41 {
42  struct trace_seq *s = &iter->seq;
43  struct trace_entry *entry = iter->ent;
44  struct bprint_entry *field;
45  int ret;
46 
47  trace_assign_type(field, entry);
48 
49  ret = trace_seq_bprintf(s, field->fmt, field->buf);
50  if (!ret)
52 
53  return TRACE_TYPE_HANDLED;
54 }
55 
57 {
58  struct trace_seq *s = &iter->seq;
59  struct trace_entry *entry = iter->ent;
60  struct print_entry *field;
61  int ret;
62 
63  trace_assign_type(field, entry);
64 
65  ret = trace_seq_printf(s, "%s", field->buf);
66  if (!ret)
68 
69  return TRACE_TYPE_HANDLED;
70 }
71 
86 int
87 trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
88 {
89  int len = (PAGE_SIZE - 1) - s->len;
90  va_list ap;
91  int ret;
92 
93  if (s->full || !len)
94  return 0;
95 
96  va_start(ap, fmt);
97  ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
98  va_end(ap);
99 
100  /* If we can't write it all, don't bother writing anything */
101  if (ret >= len) {
102  s->full = 1;
103  return 0;
104  }
105 
106  s->len += ret;
107 
108  return 1;
109 }
110 EXPORT_SYMBOL_GPL(trace_seq_printf);
111 
123 int
124 trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
125 {
126  int len = (PAGE_SIZE - 1) - s->len;
127  int ret;
128 
129  if (s->full || !len)
130  return 0;
131 
132  ret = vsnprintf(s->buffer + s->len, len, fmt, args);
133 
134  /* If we can't write it all, don't bother writing anything */
135  if (ret >= len) {
136  s->full = 1;
137  return 0;
138  }
139 
140  s->len += ret;
141 
142  return len;
143 }
145 
146 int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
147 {
148  int len = (PAGE_SIZE - 1) - s->len;
149  int ret;
150 
151  if (s->full || !len)
152  return 0;
153 
154  ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
155 
156  /* If we can't write it all, don't bother writing anything */
157  if (ret >= len) {
158  s->full = 1;
159  return 0;
160  }
161 
162  s->len += ret;
163 
164  return len;
165 }
166 
177 int trace_seq_puts(struct trace_seq *s, const char *str)
178 {
179  int len = strlen(str);
180 
181  if (s->full)
182  return 0;
183 
184  if (len > ((PAGE_SIZE - 1) - s->len)) {
185  s->full = 1;
186  return 0;
187  }
188 
189  memcpy(s->buffer + s->len, str, len);
190  s->len += len;
191 
192  return len;
193 }
194 
195 int trace_seq_putc(struct trace_seq *s, unsigned char c)
196 {
197  if (s->full)
198  return 0;
199 
200  if (s->len >= (PAGE_SIZE - 1)) {
201  s->full = 1;
202  return 0;
203  }
204 
205  s->buffer[s->len++] = c;
206 
207  return 1;
208 }
209 EXPORT_SYMBOL(trace_seq_putc);
210 
211 int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
212 {
213  if (s->full)
214  return 0;
215 
216  if (len > ((PAGE_SIZE - 1) - s->len)) {
217  s->full = 1;
218  return 0;
219  }
220 
221  memcpy(s->buffer + s->len, mem, len);
222  s->len += len;
223 
224  return len;
225 }
226 
227 int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
228 {
229  unsigned char hex[HEX_CHARS];
230  const unsigned char *data = mem;
231  int i, j;
232 
233  if (s->full)
234  return 0;
235 
236 #ifdef __BIG_ENDIAN
237  for (i = 0, j = 0; i < len; i++) {
238 #else
239  for (i = len-1, j = 0; i >= 0; i--) {
240 #endif
241  hex[j++] = hex_asc_hi(data[i]);
242  hex[j++] = hex_asc_lo(data[i]);
243  }
244  hex[j++] = ' ';
245 
246  return trace_seq_putmem(s, hex, j);
247 }
248 
249 void *trace_seq_reserve(struct trace_seq *s, size_t len)
250 {
251  void *ret;
252 
253  if (s->full)
254  return NULL;
255 
256  if (len > ((PAGE_SIZE - 1) - s->len)) {
257  s->full = 1;
258  return NULL;
259  }
260 
261  ret = s->buffer + s->len;
262  s->len += len;
263 
264  return ret;
265 }
266 
267 int trace_seq_path(struct trace_seq *s, const struct path *path)
268 {
269  unsigned char *p;
270 
271  if (s->full)
272  return 0;
273 
274  if (s->len >= (PAGE_SIZE - 1)) {
275  s->full = 1;
276  return 0;
277  }
278 
279  p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
280  if (!IS_ERR(p)) {
281  p = mangle_path(s->buffer + s->len, p, "\n");
282  if (p) {
283  s->len = p - s->buffer;
284  return 1;
285  }
286  } else {
287  s->buffer[s->len++] = '?';
288  return 1;
289  }
290 
291  s->full = 1;
292  return 0;
293 }
294 
295 const char *
296 ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
297  unsigned long flags,
298  const struct trace_print_flags *flag_array)
299 {
300  unsigned long mask;
301  const char *str;
302  const char *ret = p->buffer + p->len;
303  int i, first = 1;
304 
305  for (i = 0; flag_array[i].name && flags; i++) {
306 
307  mask = flag_array[i].mask;
308  if ((flags & mask) != mask)
309  continue;
310 
311  str = flag_array[i].name;
312  flags &= ~mask;
313  if (!first && delim)
314  trace_seq_puts(p, delim);
315  else
316  first = 0;
317  trace_seq_puts(p, str);
318  }
319 
320  /* check for left over flags */
321  if (flags) {
322  if (!first && delim)
323  trace_seq_puts(p, delim);
324  trace_seq_printf(p, "0x%lx", flags);
325  }
326 
327  trace_seq_putc(p, 0);
328 
329  return ret;
330 }
332 
333 const char *
334 ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
335  const struct trace_print_flags *symbol_array)
336 {
337  int i;
338  const char *ret = p->buffer + p->len;
339 
340  for (i = 0; symbol_array[i].name; i++) {
341 
342  if (val != symbol_array[i].mask)
343  continue;
344 
345  trace_seq_puts(p, symbol_array[i].name);
346  break;
347  }
348 
349  if (ret == (const char *)(p->buffer + p->len))
350  trace_seq_printf(p, "0x%lx", val);
351 
352  trace_seq_putc(p, 0);
353 
354  return ret;
355 }
357 
358 #if BITS_PER_LONG == 32
359 const char *
360 ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
361  const struct trace_print_flags_u64 *symbol_array)
362 {
363  int i;
364  const char *ret = p->buffer + p->len;
365 
366  for (i = 0; symbol_array[i].name; i++) {
367 
368  if (val != symbol_array[i].mask)
369  continue;
370 
371  trace_seq_puts(p, symbol_array[i].name);
372  break;
373  }
374 
375  if (ret == (const char *)(p->buffer + p->len))
376  trace_seq_printf(p, "0x%llx", val);
377 
378  trace_seq_putc(p, 0);
379 
380  return ret;
381 }
382 EXPORT_SYMBOL(ftrace_print_symbols_seq_u64);
383 #endif
384 
385 const char *
386 ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
387 {
388  int i;
389  const char *ret = p->buffer + p->len;
390 
391  for (i = 0; i < buf_len; i++)
392  trace_seq_printf(p, "%s%2.2x", i == 0 ? "" : " ", buf[i]);
393 
394  trace_seq_putc(p, 0);
395 
396  return ret;
397 }
399 
400 #ifdef CONFIG_KRETPROBES
401 static inline const char *kretprobed(const char *name)
402 {
403  static const char tramp_name[] = "kretprobe_trampoline";
404  int size = sizeof(tramp_name);
405 
406  if (strncmp(tramp_name, name, size) == 0)
407  return "[unknown/kretprobe'd]";
408  return name;
409 }
410 #else
411 static inline const char *kretprobed(const char *name)
412 {
413  return name;
414 }
415 #endif /* CONFIG_KRETPROBES */
416 
417 static int
418 seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
419 {
420 #ifdef CONFIG_KALLSYMS
421  char str[KSYM_SYMBOL_LEN];
422  const char *name;
423 
424  kallsyms_lookup(address, NULL, NULL, NULL, str);
425 
426  name = kretprobed(str);
427 
428  return trace_seq_printf(s, fmt, name);
429 #endif
430  return 1;
431 }
432 
433 static int
434 seq_print_sym_offset(struct trace_seq *s, const char *fmt,
435  unsigned long address)
436 {
437 #ifdef CONFIG_KALLSYMS
438  char str[KSYM_SYMBOL_LEN];
439  const char *name;
440 
441  sprint_symbol(str, address);
442  name = kretprobed(str);
443 
444  return trace_seq_printf(s, fmt, name);
445 #endif
446  return 1;
447 }
448 
449 #ifndef CONFIG_64BIT
450 # define IP_FMT "%08lx"
451 #else
452 # define IP_FMT "%016lx"
453 #endif
454 
455 int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
456  unsigned long ip, unsigned long sym_flags)
457 {
458  struct file *file = NULL;
459  unsigned long vmstart = 0;
460  int ret = 1;
461 
462  if (s->full)
463  return 0;
464 
465  if (mm) {
466  const struct vm_area_struct *vma;
467 
468  down_read(&mm->mmap_sem);
469  vma = find_vma(mm, ip);
470  if (vma) {
471  file = vma->vm_file;
472  vmstart = vma->vm_start;
473  }
474  if (file) {
475  ret = trace_seq_path(s, &file->f_path);
476  if (ret)
477  ret = trace_seq_printf(s, "[+0x%lx]",
478  ip - vmstart);
479  }
480  up_read(&mm->mmap_sem);
481  }
482  if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
483  ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
484  return ret;
485 }
486 
487 int
488 seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
489  unsigned long sym_flags)
490 {
491  struct mm_struct *mm = NULL;
492  int ret = 1;
493  unsigned int i;
494 
496  struct task_struct *task;
497  /*
498  * we do the lookup on the thread group leader,
499  * since individual threads might have already quit!
500  */
501  rcu_read_lock();
502  task = find_task_by_vpid(entry->tgid);
503  if (task)
504  mm = get_task_mm(task);
505  rcu_read_unlock();
506  }
507 
508  for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
509  unsigned long ip = entry->caller[i];
510 
511  if (ip == ULONG_MAX || !ret)
512  break;
513  if (ret)
514  ret = trace_seq_puts(s, " => ");
515  if (!ip) {
516  if (ret)
517  ret = trace_seq_puts(s, "??");
518  if (ret)
519  ret = trace_seq_puts(s, "\n");
520  continue;
521  }
522  if (!ret)
523  break;
524  if (ret)
525  ret = seq_print_user_ip(s, mm, ip, sym_flags);
526  ret = trace_seq_puts(s, "\n");
527  }
528 
529  if (mm)
530  mmput(mm);
531  return ret;
532 }
533 
534 int
535 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
536 {
537  int ret;
538 
539  if (!ip)
540  return trace_seq_printf(s, "0");
541 
542  if (sym_flags & TRACE_ITER_SYM_OFFSET)
543  ret = seq_print_sym_offset(s, "%s", ip);
544  else
545  ret = seq_print_sym_short(s, "%s", ip);
546 
547  if (!ret)
548  return 0;
549 
550  if (sym_flags & TRACE_ITER_SYM_ADDR)
551  ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
552  return ret;
553 }
554 
564 {
565  char hardsoft_irq;
566  char need_resched;
567  char irqs_off;
568  int hardirq;
569  int softirq;
570  int ret;
571 
572  hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
573  softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
574 
575  irqs_off =
576  (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
577  (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' :
578  '.';
579  need_resched =
580  (entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.';
581  hardsoft_irq =
582  (hardirq && softirq) ? 'H' :
583  hardirq ? 'h' :
584  softirq ? 's' :
585  '.';
586 
587  if (!trace_seq_printf(s, "%c%c%c",
588  irqs_off, need_resched, hardsoft_irq))
589  return 0;
590 
591  if (entry->preempt_count)
592  ret = trace_seq_printf(s, "%x", entry->preempt_count);
593  else
594  ret = trace_seq_putc(s, '.');
595 
596  return ret;
597 }
598 
599 static int
600 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
601 {
602  char comm[TASK_COMM_LEN];
603 
604  trace_find_cmdline(entry->pid, comm);
605 
606  if (!trace_seq_printf(s, "%8.8s-%-5d %3d",
607  comm, entry->pid, cpu))
608  return 0;
609 
610  return trace_print_lat_fmt(s, entry);
611 }
612 
613 static unsigned long preempt_mark_thresh = 100;
614 
615 static int
616 lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
617  unsigned long rel_usecs)
618 {
619  return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
620  rel_usecs > preempt_mark_thresh ? '!' :
621  rel_usecs > 1 ? '+' : ' ');
622 }
623 
625 {
626  struct trace_seq *s = &iter->seq;
627  struct trace_entry *entry = iter->ent;
628  unsigned long long t = ns2usecs(iter->ts);
629  unsigned long usec_rem = do_div(t, USEC_PER_SEC);
630  unsigned long secs = (unsigned long)t;
631  char comm[TASK_COMM_LEN];
632  int ret;
633 
634  trace_find_cmdline(entry->pid, comm);
635 
636  ret = trace_seq_printf(s, "%16s-%-5d [%03d] ",
637  comm, entry->pid, iter->cpu);
638  if (!ret)
639  return 0;
640 
642  ret = trace_print_lat_fmt(s, entry);
643  if (!ret)
644  return 0;
645  }
646 
647  return trace_seq_printf(s, " %5lu.%06lu: ",
648  secs, usec_rem);
649 }
650 
652 {
653  u64 next_ts;
654  int ret;
655  /* trace_find_next_entry will reset ent_size */
656  int ent_size = iter->ent_size;
657  struct trace_seq *s = &iter->seq;
658  struct trace_entry *entry = iter->ent,
659  *next_entry = trace_find_next_entry(iter, NULL,
660  &next_ts);
661  unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
662  unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
663  unsigned long rel_usecs;
664 
665  /* Restore the original ent_size */
666  iter->ent_size = ent_size;
667 
668  if (!next_entry)
669  next_ts = iter->ts;
670  rel_usecs = ns2usecs(next_ts - iter->ts);
671 
672  if (verbose) {
673  char comm[TASK_COMM_LEN];
674 
675  trace_find_cmdline(entry->pid, comm);
676 
677  ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]"
678  " %ld.%03ldms (+%ld.%03ldms): ", comm,
679  entry->pid, iter->cpu, entry->flags,
680  entry->preempt_count, iter->idx,
681  ns2usecs(iter->ts),
682  abs_usecs / USEC_PER_MSEC,
683  abs_usecs % USEC_PER_MSEC,
684  rel_usecs / USEC_PER_MSEC,
685  rel_usecs % USEC_PER_MSEC);
686  } else {
687  ret = lat_print_generic(s, entry, iter->cpu);
688  if (ret)
689  ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
690  }
691 
692  return ret;
693 }
694 
695 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
696 
697 static int task_state_char(unsigned long state)
698 {
699  int bit = state ? __ffs(state) + 1 : 0;
700 
701  return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
702 }
703 
712 {
713  struct trace_event *event;
714  struct hlist_node *n;
715  unsigned key;
716 
717  key = type & (EVENT_HASHSIZE - 1);
718 
719  hlist_for_each_entry(event, n, &event_hash[key], node) {
720  if (event->type == type)
721  return event;
722  }
723 
724  return NULL;
725 }
726 
727 static LIST_HEAD(ftrace_event_list);
728 
729 static int trace_search_list(struct list_head **list)
730 {
731  struct trace_event *e;
732  int last = __TRACE_LAST_TYPE;
733 
734  if (list_empty(&ftrace_event_list)) {
735  *list = &ftrace_event_list;
736  return last + 1;
737  }
738 
739  /*
740  * We used up all possible max events,
741  * lets see if somebody freed one.
742  */
743  list_for_each_entry(e, &ftrace_event_list, list) {
744  if (e->type != last + 1)
745  break;
746  last++;
747  }
748 
749  /* Did we used up all 65 thousand events??? */
750  if ((last + 1) > FTRACE_MAX_EVENT)
751  return 0;
752 
753  *list = &e->list;
754  return last + 1;
755 }
756 
758 {
760 }
761 
763 {
765 }
766 
783 {
784  unsigned key;
785  int ret = 0;
786 
788 
789  if (WARN_ON(!event))
790  goto out;
791 
792  if (WARN_ON(!event->funcs))
793  goto out;
794 
795  INIT_LIST_HEAD(&event->list);
796 
797  if (!event->type) {
798  struct list_head *list = NULL;
799 
800  if (next_event_type > FTRACE_MAX_EVENT) {
801 
802  event->type = trace_search_list(&list);
803  if (!event->type)
804  goto out;
805 
806  } else {
807 
808  event->type = next_event_type++;
809  list = &ftrace_event_list;
810  }
811 
812  if (WARN_ON(ftrace_find_event(event->type)))
813  goto out;
814 
815  list_add_tail(&event->list, list);
816 
817  } else if (event->type > __TRACE_LAST_TYPE) {
818  printk(KERN_WARNING "Need to add type to trace.h\n");
819  WARN_ON(1);
820  goto out;
821  } else {
822  /* Is this event already used */
823  if (ftrace_find_event(event->type))
824  goto out;
825  }
826 
827  if (event->funcs->trace == NULL)
828  event->funcs->trace = trace_nop_print;
829  if (event->funcs->raw == NULL)
830  event->funcs->raw = trace_nop_print;
831  if (event->funcs->hex == NULL)
832  event->funcs->hex = trace_nop_print;
833  if (event->funcs->binary == NULL)
834  event->funcs->binary = trace_nop_print;
835 
836  key = event->type & (EVENT_HASHSIZE - 1);
837 
838  hlist_add_head(&event->node, &event_hash[key]);
839 
840  ret = event->type;
841  out:
843 
844  return ret;
845 }
847 
848 /*
849  * Used by module code with the trace_event_mutex held for write.
850  */
852 {
853  hlist_del(&event->node);
854  list_del(&event->list);
855  return 0;
856 }
857 
863 {
867 
868  return 0;
869 }
871 
872 /*
873  * Standard events
874  */
875 
877  struct trace_event *event)
878 {
879  if (!trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type))
881 
882  return TRACE_TYPE_HANDLED;
883 }
884 
885 /* TRACE_FN */
886 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,
887  struct trace_event *event)
888 {
889  struct ftrace_entry *field;
890  struct trace_seq *s = &iter->seq;
891 
892  trace_assign_type(field, iter->ent);
893 
894  if (!seq_print_ip_sym(s, field->ip, flags))
895  goto partial;
896 
897  if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
898  if (!trace_seq_printf(s, " <-"))
899  goto partial;
900  if (!seq_print_ip_sym(s,
901  field->parent_ip,
902  flags))
903  goto partial;
904  }
905  if (!trace_seq_printf(s, "\n"))
906  goto partial;
907 
908  return TRACE_TYPE_HANDLED;
909 
910  partial:
912 }
913 
914 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags,
915  struct trace_event *event)
916 {
917  struct ftrace_entry *field;
918 
919  trace_assign_type(field, iter->ent);
920 
921  if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
922  field->ip,
923  field->parent_ip))
925 
926  return TRACE_TYPE_HANDLED;
927 }
928 
929 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags,
930  struct trace_event *event)
931 {
932  struct ftrace_entry *field;
933  struct trace_seq *s = &iter->seq;
934 
935  trace_assign_type(field, iter->ent);
936 
937  SEQ_PUT_HEX_FIELD_RET(s, field->ip);
938  SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
939 
940  return TRACE_TYPE_HANDLED;
941 }
942 
943 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags,
944  struct trace_event *event)
945 {
946  struct ftrace_entry *field;
947  struct trace_seq *s = &iter->seq;
948 
949  trace_assign_type(field, iter->ent);
950 
951  SEQ_PUT_FIELD_RET(s, field->ip);
952  SEQ_PUT_FIELD_RET(s, field->parent_ip);
953 
954  return TRACE_TYPE_HANDLED;
955 }
956 
957 static struct trace_event_functions trace_fn_funcs = {
958  .trace = trace_fn_trace,
959  .raw = trace_fn_raw,
960  .hex = trace_fn_hex,
961  .binary = trace_fn_bin,
962 };
963 
964 static struct trace_event trace_fn_event = {
965  .type = TRACE_FN,
966  .funcs = &trace_fn_funcs,
967 };
968 
969 /* TRACE_CTX an TRACE_WAKE */
970 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
971  char *delim)
972 {
973  struct ctx_switch_entry *field;
974  char comm[TASK_COMM_LEN];
975  int S, T;
976 
977 
978  trace_assign_type(field, iter->ent);
979 
980  T = task_state_char(field->next_state);
981  S = task_state_char(field->prev_state);
982  trace_find_cmdline(field->next_pid, comm);
983  if (!trace_seq_printf(&iter->seq,
984  " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
985  field->prev_pid,
986  field->prev_prio,
987  S, delim,
988  field->next_cpu,
989  field->next_pid,
990  field->next_prio,
991  T, comm))
993 
994  return TRACE_TYPE_HANDLED;
995 }
996 
997 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags,
998  struct trace_event *event)
999 {
1000  return trace_ctxwake_print(iter, "==>");
1001 }
1002 
1003 static enum print_line_t trace_wake_print(struct trace_iterator *iter,
1004  int flags, struct trace_event *event)
1005 {
1006  return trace_ctxwake_print(iter, " +");
1007 }
1008 
1009 static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
1010 {
1011  struct ctx_switch_entry *field;
1012  int T;
1013 
1014  trace_assign_type(field, iter->ent);
1015 
1016  if (!S)
1017  S = task_state_char(field->prev_state);
1018  T = task_state_char(field->next_state);
1019  if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
1020  field->prev_pid,
1021  field->prev_prio,
1022  S,
1023  field->next_cpu,
1024  field->next_pid,
1025  field->next_prio,
1026  T))
1027  return TRACE_TYPE_PARTIAL_LINE;
1028 
1029  return TRACE_TYPE_HANDLED;
1030 }
1031 
1032 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags,
1033  struct trace_event *event)
1034 {
1035  return trace_ctxwake_raw(iter, 0);
1036 }
1037 
1038 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags,
1039  struct trace_event *event)
1040 {
1041  return trace_ctxwake_raw(iter, '+');
1042 }
1043 
1044 
1045 static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
1046 {
1047  struct ctx_switch_entry *field;
1048  struct trace_seq *s = &iter->seq;
1049  int T;
1050 
1051  trace_assign_type(field, iter->ent);
1052 
1053  if (!S)
1054  S = task_state_char(field->prev_state);
1055  T = task_state_char(field->next_state);
1056 
1057  SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
1058  SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
1059  SEQ_PUT_HEX_FIELD_RET(s, S);
1060  SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
1061  SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
1062  SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
1063  SEQ_PUT_HEX_FIELD_RET(s, T);
1064 
1065  return TRACE_TYPE_HANDLED;
1066 }
1067 
1068 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags,
1069  struct trace_event *event)
1070 {
1071  return trace_ctxwake_hex(iter, 0);
1072 }
1073 
1074 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags,
1075  struct trace_event *event)
1076 {
1077  return trace_ctxwake_hex(iter, '+');
1078 }
1079 
1080 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
1081  int flags, struct trace_event *event)
1082 {
1083  struct ctx_switch_entry *field;
1084  struct trace_seq *s = &iter->seq;
1085 
1086  trace_assign_type(field, iter->ent);
1087 
1088  SEQ_PUT_FIELD_RET(s, field->prev_pid);
1089  SEQ_PUT_FIELD_RET(s, field->prev_prio);
1090  SEQ_PUT_FIELD_RET(s, field->prev_state);
1091  SEQ_PUT_FIELD_RET(s, field->next_pid);
1092  SEQ_PUT_FIELD_RET(s, field->next_prio);
1093  SEQ_PUT_FIELD_RET(s, field->next_state);
1094 
1095  return TRACE_TYPE_HANDLED;
1096 }
1097 
1098 static struct trace_event_functions trace_ctx_funcs = {
1099  .trace = trace_ctx_print,
1100  .raw = trace_ctx_raw,
1101  .hex = trace_ctx_hex,
1102  .binary = trace_ctxwake_bin,
1103 };
1104 
1105 static struct trace_event trace_ctx_event = {
1106  .type = TRACE_CTX,
1107  .funcs = &trace_ctx_funcs,
1108 };
1109 
1110 static struct trace_event_functions trace_wake_funcs = {
1111  .trace = trace_wake_print,
1112  .raw = trace_wake_raw,
1113  .hex = trace_wake_hex,
1114  .binary = trace_ctxwake_bin,
1115 };
1116 
1117 static struct trace_event trace_wake_event = {
1118  .type = TRACE_WAKE,
1119  .funcs = &trace_wake_funcs,
1120 };
1121 
1122 /* TRACE_STACK */
1123 
1124 static enum print_line_t trace_stack_print(struct trace_iterator *iter,
1125  int flags, struct trace_event *event)
1126 {
1127  struct stack_entry *field;
1128  struct trace_seq *s = &iter->seq;
1129  unsigned long *p;
1130  unsigned long *end;
1131 
1132  trace_assign_type(field, iter->ent);
1133  end = (unsigned long *)((long)iter->ent + iter->ent_size);
1134 
1135  if (!trace_seq_puts(s, "<stack trace>\n"))
1136  goto partial;
1137 
1138  for (p = field->caller; p && *p != ULONG_MAX && p < end; p++) {
1139  if (!trace_seq_puts(s, " => "))
1140  goto partial;
1141 
1142  if (!seq_print_ip_sym(s, *p, flags))
1143  goto partial;
1144  if (!trace_seq_puts(s, "\n"))
1145  goto partial;
1146  }
1147 
1148  return TRACE_TYPE_HANDLED;
1149 
1150  partial:
1151  return TRACE_TYPE_PARTIAL_LINE;
1152 }
1153 
1154 static struct trace_event_functions trace_stack_funcs = {
1155  .trace = trace_stack_print,
1156 };
1157 
1158 static struct trace_event trace_stack_event = {
1159  .type = TRACE_STACK,
1160  .funcs = &trace_stack_funcs,
1161 };
1162 
1163 /* TRACE_USER_STACK */
1164 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
1165  int flags, struct trace_event *event)
1166 {
1167  struct userstack_entry *field;
1168  struct trace_seq *s = &iter->seq;
1169 
1170  trace_assign_type(field, iter->ent);
1171 
1172  if (!trace_seq_puts(s, "<user stack trace>\n"))
1173  goto partial;
1174 
1175  if (!seq_print_userip_objs(field, s, flags))
1176  goto partial;
1177 
1178  return TRACE_TYPE_HANDLED;
1179 
1180  partial:
1181  return TRACE_TYPE_PARTIAL_LINE;
1182 }
1183 
1184 static struct trace_event_functions trace_user_stack_funcs = {
1185  .trace = trace_user_stack_print,
1186 };
1187 
1188 static struct trace_event trace_user_stack_event = {
1189  .type = TRACE_USER_STACK,
1190  .funcs = &trace_user_stack_funcs,
1191 };
1192 
1193 /* TRACE_BPRINT */
1194 static enum print_line_t
1195 trace_bprint_print(struct trace_iterator *iter, int flags,
1196  struct trace_event *event)
1197 {
1198  struct trace_entry *entry = iter->ent;
1199  struct trace_seq *s = &iter->seq;
1200  struct bprint_entry *field;
1201 
1202  trace_assign_type(field, entry);
1203 
1204  if (!seq_print_ip_sym(s, field->ip, flags))
1205  goto partial;
1206 
1207  if (!trace_seq_puts(s, ": "))
1208  goto partial;
1209 
1210  if (!trace_seq_bprintf(s, field->fmt, field->buf))
1211  goto partial;
1212 
1213  return TRACE_TYPE_HANDLED;
1214 
1215  partial:
1216  return TRACE_TYPE_PARTIAL_LINE;
1217 }
1218 
1219 
1220 static enum print_line_t
1221 trace_bprint_raw(struct trace_iterator *iter, int flags,
1222  struct trace_event *event)
1223 {
1224  struct bprint_entry *field;
1225  struct trace_seq *s = &iter->seq;
1226 
1227  trace_assign_type(field, iter->ent);
1228 
1229  if (!trace_seq_printf(s, ": %lx : ", field->ip))
1230  goto partial;
1231 
1232  if (!trace_seq_bprintf(s, field->fmt, field->buf))
1233  goto partial;
1234 
1235  return TRACE_TYPE_HANDLED;
1236 
1237  partial:
1238  return TRACE_TYPE_PARTIAL_LINE;
1239 }
1240 
1241 static struct trace_event_functions trace_bprint_funcs = {
1242  .trace = trace_bprint_print,
1243  .raw = trace_bprint_raw,
1244 };
1245 
1246 static struct trace_event trace_bprint_event = {
1247  .type = TRACE_BPRINT,
1248  .funcs = &trace_bprint_funcs,
1249 };
1250 
1251 /* TRACE_PRINT */
1252 static enum print_line_t trace_print_print(struct trace_iterator *iter,
1253  int flags, struct trace_event *event)
1254 {
1255  struct print_entry *field;
1256  struct trace_seq *s = &iter->seq;
1257 
1258  trace_assign_type(field, iter->ent);
1259 
1260  if (!seq_print_ip_sym(s, field->ip, flags))
1261  goto partial;
1262 
1263  if (!trace_seq_printf(s, ": %s", field->buf))
1264  goto partial;
1265 
1266  return TRACE_TYPE_HANDLED;
1267 
1268  partial:
1269  return TRACE_TYPE_PARTIAL_LINE;
1270 }
1271 
1272 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags,
1273  struct trace_event *event)
1274 {
1275  struct print_entry *field;
1276 
1277  trace_assign_type(field, iter->ent);
1278 
1279  if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
1280  goto partial;
1281 
1282  return TRACE_TYPE_HANDLED;
1283 
1284  partial:
1285  return TRACE_TYPE_PARTIAL_LINE;
1286 }
1287 
1288 static struct trace_event_functions trace_print_funcs = {
1289  .trace = trace_print_print,
1290  .raw = trace_print_raw,
1291 };
1292 
1293 static struct trace_event trace_print_event = {
1294  .type = TRACE_PRINT,
1295  .funcs = &trace_print_funcs,
1296 };
1297 
1298 
1299 static struct trace_event *events[] __initdata = {
1300  &trace_fn_event,
1301  &trace_ctx_event,
1302  &trace_wake_event,
1303  &trace_stack_event,
1304  &trace_user_stack_event,
1305  &trace_bprint_event,
1306  &trace_print_event,
1307  NULL
1308 };
1309 
1310 __init static int init_events(void)
1311 {
1312  struct trace_event *event;
1313  int i, ret;
1314 
1315  for (i = 0; events[i]; i++) {
1316  event = events[i];
1317 
1318  ret = register_ftrace_event(event);
1319  if (!ret) {
1320  printk(KERN_WARNING "event %d failed to register\n",
1321  event->type);
1322  WARN_ON_ONCE(1);
1323  }
1324  }
1325 
1326  return 0;
1327 }
1328 early_initcall(init_events);