4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
8 #include <linux/module.h>
9 #include <linux/mutex.h>
10 #include <linux/ftrace.h>
12 #include "trace_output.h"
14 /* must be a power of 2 */
15 #define EVENT_HASHSIZE 128
17 static DEFINE_MUTEX(trace_event_mutex);
18 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
20 static int next_event_type = __TRACE_LAST_TYPE + 1;
23 * trace_seq_printf - sequence printing of trace information
24 * @s: trace sequence descriptor
25 * @fmt: printf format string
27 * The tracer may use either sequence operations or its own
28 * copy to user routines. To simplify formating of a trace
29 * trace_seq_printf is used to store strings into a special
30 * buffer (@s). Then the output may be either used by
31 * the sequencer or pulled into another buffer.
34 trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
36 int len = (PAGE_SIZE - 1) - s->len;
44 ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
47 /* If we can't write it all, don't bother writing anything */
56 int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
58 int len = (PAGE_SIZE - 1) - s->len;
64 ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
66 /* If we can't write it all, don't bother writing anything */
76 * trace_seq_puts - trace sequence printing of simple string
77 * @s: trace sequence descriptor
78 * @str: simple string to record
80 * The tracer may use either the sequence operations or its own
81 * copy to user routines. This function records a simple string
82 * into a special buffer (@s) for later retrieval by a sequencer
85 int trace_seq_puts(struct trace_seq *s, const char *str)
87 int len = strlen(str);
89 if (len > ((PAGE_SIZE - 1) - s->len))
92 memcpy(s->buffer + s->len, str, len);
98 int trace_seq_putc(struct trace_seq *s, unsigned char c)
100 if (s->len >= (PAGE_SIZE - 1))
103 s->buffer[s->len++] = c;
108 int trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
110 if (len > ((PAGE_SIZE - 1) - s->len))
113 memcpy(s->buffer + s->len, mem, len);
119 int trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
121 unsigned char hex[HEX_CHARS];
122 unsigned char *data = mem;
126 for (i = 0, j = 0; i < len; i++) {
128 for (i = len-1, j = 0; i >= 0; i--) {
130 hex[j++] = hex_asc_hi(data[i]);
131 hex[j++] = hex_asc_lo(data[i]);
135 return trace_seq_putmem(s, hex, j);
138 int trace_seq_path(struct trace_seq *s, struct path *path)
142 if (s->len >= (PAGE_SIZE - 1))
144 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
146 p = mangle_path(s->buffer + s->len, p, "\n");
148 s->len = p - s->buffer;
152 s->buffer[s->len++] = '?';
159 #ifdef CONFIG_KRETPROBES
160 static inline const char *kretprobed(const char *name)
162 static const char tramp_name[] = "kretprobe_trampoline";
163 int size = sizeof(tramp_name);
165 if (strncmp(tramp_name, name, size) == 0)
166 return "[unknown/kretprobe'd]";
170 static inline const char *kretprobed(const char *name)
174 #endif /* CONFIG_KRETPROBES */
177 seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
179 #ifdef CONFIG_KALLSYMS
180 char str[KSYM_SYMBOL_LEN];
183 kallsyms_lookup(address, NULL, NULL, NULL, str);
185 name = kretprobed(str);
187 return trace_seq_printf(s, fmt, name);
193 seq_print_sym_offset(struct trace_seq *s, const char *fmt,
194 unsigned long address)
196 #ifdef CONFIG_KALLSYMS
197 char str[KSYM_SYMBOL_LEN];
200 sprint_symbol(str, address);
201 name = kretprobed(str);
203 return trace_seq_printf(s, fmt, name);
209 # define IP_FMT "%08lx"
211 # define IP_FMT "%016lx"
214 int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
215 unsigned long ip, unsigned long sym_flags)
217 struct file *file = NULL;
218 unsigned long vmstart = 0;
222 const struct vm_area_struct *vma;
224 down_read(&mm->mmap_sem);
225 vma = find_vma(mm, ip);
228 vmstart = vma->vm_start;
231 ret = trace_seq_path(s, &file->f_path);
233 ret = trace_seq_printf(s, "[+0x%lx]",
236 up_read(&mm->mmap_sem);
238 if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
239 ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
244 seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
245 unsigned long sym_flags)
247 struct mm_struct *mm = NULL;
251 if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
252 struct task_struct *task;
254 * we do the lookup on the thread group leader,
255 * since individual threads might have already quit!
258 task = find_task_by_vpid(entry->ent.tgid);
260 mm = get_task_mm(task);
264 for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
265 unsigned long ip = entry->caller[i];
267 if (ip == ULONG_MAX || !ret)
270 ret = trace_seq_puts(s, " <- ");
273 ret = trace_seq_puts(s, "??");
279 ret = seq_print_user_ip(s, mm, ip, sym_flags);
288 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
293 return trace_seq_printf(s, "0");
295 if (sym_flags & TRACE_ITER_SYM_OFFSET)
296 ret = seq_print_sym_offset(s, "%s", ip);
298 ret = seq_print_sym_short(s, "%s", ip);
303 if (sym_flags & TRACE_ITER_SYM_ADDR)
304 ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
309 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
311 int hardirq, softirq;
314 comm = trace_find_cmdline(entry->pid);
315 hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
316 softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
318 if (!trace_seq_printf(s, "%8.8s-%-5d %3d%c%c%c",
319 comm, entry->pid, cpu,
320 (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
321 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
323 (entry->flags & TRACE_FLAG_NEED_RESCHED) ?
325 (hardirq && softirq) ? 'H' :
326 hardirq ? 'h' : softirq ? 's' : '.'))
329 if (entry->preempt_count)
330 return trace_seq_printf(s, "%x", entry->preempt_count);
331 return trace_seq_puts(s, ".");
334 static unsigned long preempt_mark_thresh = 100;
337 lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
338 unsigned long rel_usecs)
340 return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
341 rel_usecs > preempt_mark_thresh ? '!' :
342 rel_usecs > 1 ? '+' : ' ');
345 int trace_print_context(struct trace_iterator *iter)
347 struct trace_seq *s = &iter->seq;
348 struct trace_entry *entry = iter->ent;
349 char *comm = trace_find_cmdline(entry->pid);
350 unsigned long long t = ns2usecs(iter->ts);
351 unsigned long usec_rem = do_div(t, USEC_PER_SEC);
352 unsigned long secs = (unsigned long)t;
354 return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ",
355 comm, entry->pid, iter->cpu, secs, usec_rem);
358 int trace_print_lat_context(struct trace_iterator *iter)
362 struct trace_seq *s = &iter->seq;
363 struct trace_entry *entry = iter->ent,
364 *next_entry = trace_find_next_entry(iter, NULL,
366 unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
367 unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
368 unsigned long rel_usecs;
372 rel_usecs = ns2usecs(next_ts - iter->ts);
375 char *comm = trace_find_cmdline(entry->pid);
376 ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
377 " %ld.%03ldms (+%ld.%03ldms): ", comm,
378 entry->pid, iter->cpu, entry->flags,
379 entry->preempt_count, iter->idx,
381 abs_usecs / USEC_PER_MSEC,
382 abs_usecs % USEC_PER_MSEC,
383 rel_usecs / USEC_PER_MSEC,
384 rel_usecs % USEC_PER_MSEC);
386 ret = lat_print_generic(s, entry, iter->cpu);
388 ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
394 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
396 static int task_state_char(unsigned long state)
398 int bit = state ? __ffs(state) + 1 : 0;
400 return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
404 * ftrace_find_event - find a registered event
405 * @type: the type of event to look for
407 * Returns an event of type @type otherwise NULL
409 struct trace_event *ftrace_find_event(int type)
411 struct trace_event *event;
412 struct hlist_node *n;
415 key = type & (EVENT_HASHSIZE - 1);
417 hlist_for_each_entry_rcu(event, n, &event_hash[key], node) {
418 if (event->type == type)
426 * register_ftrace_event - register output for an event type
427 * @event: the event type to register
429 * Event types are stored in a hash and this hash is used to
430 * find a way to print an event. If the @event->type is set
431 * then it will use that type, otherwise it will assign a
434 * If you assign your own type, please make sure it is added
435 * to the trace_type enum in trace.h, to avoid collisions
436 * with the dynamic types.
438 * Returns the event type number or zero on error.
440 int register_ftrace_event(struct trace_event *event)
445 mutex_lock(&trace_event_mutex);
448 event->type = next_event_type++;
449 else if (event->type > __TRACE_LAST_TYPE) {
450 printk(KERN_WARNING "Need to add type to trace.h\n");
454 if (ftrace_find_event(event->type))
457 if (event->trace == NULL)
458 event->trace = trace_nop_print;
459 if (event->raw == NULL)
460 event->raw = trace_nop_print;
461 if (event->hex == NULL)
462 event->hex = trace_nop_print;
463 if (event->binary == NULL)
464 event->binary = trace_nop_print;
466 key = event->type & (EVENT_HASHSIZE - 1);
468 hlist_add_head_rcu(&event->node, &event_hash[key]);
472 mutex_unlock(&trace_event_mutex);
478 * unregister_ftrace_event - remove a no longer used event
479 * @event: the event to remove
481 int unregister_ftrace_event(struct trace_event *event)
483 mutex_lock(&trace_event_mutex);
484 hlist_del(&event->node);
485 mutex_unlock(&trace_event_mutex);
494 enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags)
496 return TRACE_TYPE_HANDLED;
500 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags)
502 struct ftrace_entry *field;
503 struct trace_seq *s = &iter->seq;
505 trace_assign_type(field, iter->ent);
507 if (!seq_print_ip_sym(s, field->ip, flags))
510 if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
511 if (!trace_seq_printf(s, " <-"))
513 if (!seq_print_ip_sym(s,
518 if (!trace_seq_printf(s, "\n"))
521 return TRACE_TYPE_HANDLED;
524 return TRACE_TYPE_PARTIAL_LINE;
527 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags)
529 struct ftrace_entry *field;
531 trace_assign_type(field, iter->ent);
533 if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
536 return TRACE_TYPE_PARTIAL_LINE;
538 return TRACE_TYPE_HANDLED;
541 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags)
543 struct ftrace_entry *field;
544 struct trace_seq *s = &iter->seq;
546 trace_assign_type(field, iter->ent);
548 SEQ_PUT_HEX_FIELD_RET(s, field->ip);
549 SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
551 return TRACE_TYPE_HANDLED;
554 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags)
556 struct ftrace_entry *field;
557 struct trace_seq *s = &iter->seq;
559 trace_assign_type(field, iter->ent);
561 SEQ_PUT_FIELD_RET(s, field->ip);
562 SEQ_PUT_FIELD_RET(s, field->parent_ip);
564 return TRACE_TYPE_HANDLED;
567 static struct trace_event trace_fn_event = {
569 .trace = trace_fn_trace,
572 .binary = trace_fn_bin,
575 /* TRACE_CTX an TRACE_WAKE */
576 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
579 struct ctx_switch_entry *field;
583 trace_assign_type(field, iter->ent);
585 T = task_state_char(field->next_state);
586 S = task_state_char(field->prev_state);
587 comm = trace_find_cmdline(field->next_pid);
588 if (!trace_seq_printf(&iter->seq,
589 " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
597 return TRACE_TYPE_PARTIAL_LINE;
599 return TRACE_TYPE_HANDLED;
602 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags)
604 return trace_ctxwake_print(iter, "==>");
607 static enum print_line_t trace_wake_print(struct trace_iterator *iter,
610 return trace_ctxwake_print(iter, " +");
613 static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
615 struct ctx_switch_entry *field;
618 trace_assign_type(field, iter->ent);
621 task_state_char(field->prev_state);
622 T = task_state_char(field->next_state);
623 if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
631 return TRACE_TYPE_PARTIAL_LINE;
633 return TRACE_TYPE_HANDLED;
636 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags)
638 return trace_ctxwake_raw(iter, 0);
641 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags)
643 return trace_ctxwake_raw(iter, '+');
647 static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
649 struct ctx_switch_entry *field;
650 struct trace_seq *s = &iter->seq;
653 trace_assign_type(field, iter->ent);
656 task_state_char(field->prev_state);
657 T = task_state_char(field->next_state);
659 SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
660 SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
661 SEQ_PUT_HEX_FIELD_RET(s, S);
662 SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
663 SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
664 SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
665 SEQ_PUT_HEX_FIELD_RET(s, T);
667 return TRACE_TYPE_HANDLED;
670 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags)
672 return trace_ctxwake_hex(iter, 0);
675 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags)
677 return trace_ctxwake_hex(iter, '+');
680 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
683 struct ctx_switch_entry *field;
684 struct trace_seq *s = &iter->seq;
686 trace_assign_type(field, iter->ent);
688 SEQ_PUT_FIELD_RET(s, field->prev_pid);
689 SEQ_PUT_FIELD_RET(s, field->prev_prio);
690 SEQ_PUT_FIELD_RET(s, field->prev_state);
691 SEQ_PUT_FIELD_RET(s, field->next_pid);
692 SEQ_PUT_FIELD_RET(s, field->next_prio);
693 SEQ_PUT_FIELD_RET(s, field->next_state);
695 return TRACE_TYPE_HANDLED;
698 static struct trace_event trace_ctx_event = {
700 .trace = trace_ctx_print,
701 .raw = trace_ctx_raw,
702 .hex = trace_ctx_hex,
703 .binary = trace_ctxwake_bin,
706 static struct trace_event trace_wake_event = {
708 .trace = trace_wake_print,
709 .raw = trace_wake_raw,
710 .hex = trace_wake_hex,
711 .binary = trace_ctxwake_bin,
715 static enum print_line_t trace_special_print(struct trace_iterator *iter,
718 struct special_entry *field;
720 trace_assign_type(field, iter->ent);
722 if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
726 return TRACE_TYPE_PARTIAL_LINE;
728 return TRACE_TYPE_HANDLED;
731 static enum print_line_t trace_special_hex(struct trace_iterator *iter,
734 struct special_entry *field;
735 struct trace_seq *s = &iter->seq;
737 trace_assign_type(field, iter->ent);
739 SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
740 SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
741 SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
743 return TRACE_TYPE_HANDLED;
746 static enum print_line_t trace_special_bin(struct trace_iterator *iter,
749 struct special_entry *field;
750 struct trace_seq *s = &iter->seq;
752 trace_assign_type(field, iter->ent);
754 SEQ_PUT_FIELD_RET(s, field->arg1);
755 SEQ_PUT_FIELD_RET(s, field->arg2);
756 SEQ_PUT_FIELD_RET(s, field->arg3);
758 return TRACE_TYPE_HANDLED;
761 static struct trace_event trace_special_event = {
762 .type = TRACE_SPECIAL,
763 .trace = trace_special_print,
764 .raw = trace_special_print,
765 .hex = trace_special_hex,
766 .binary = trace_special_bin,
771 static enum print_line_t trace_stack_print(struct trace_iterator *iter,
774 struct stack_entry *field;
775 struct trace_seq *s = &iter->seq;
778 trace_assign_type(field, iter->ent);
780 for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
782 if (!trace_seq_puts(s, " <= "))
785 if (!seq_print_ip_sym(s, field->caller[i], flags))
788 if (!trace_seq_puts(s, "\n"))
792 return TRACE_TYPE_HANDLED;
795 return TRACE_TYPE_PARTIAL_LINE;
798 static struct trace_event trace_stack_event = {
800 .trace = trace_stack_print,
801 .raw = trace_special_print,
802 .hex = trace_special_hex,
803 .binary = trace_special_bin,
806 /* TRACE_USER_STACK */
807 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
810 struct userstack_entry *field;
811 struct trace_seq *s = &iter->seq;
813 trace_assign_type(field, iter->ent);
815 if (!seq_print_userip_objs(field, s, flags))
818 if (!trace_seq_putc(s, '\n'))
821 return TRACE_TYPE_HANDLED;
824 return TRACE_TYPE_PARTIAL_LINE;
827 static struct trace_event trace_user_stack_event = {
828 .type = TRACE_USER_STACK,
829 .trace = trace_user_stack_print,
830 .raw = trace_special_print,
831 .hex = trace_special_hex,
832 .binary = trace_special_bin,
836 static enum print_line_t
837 trace_bprint_print(struct trace_iterator *iter, int flags)
839 struct trace_entry *entry = iter->ent;
840 struct trace_seq *s = &iter->seq;
841 struct bprint_entry *field;
843 trace_assign_type(field, entry);
845 if (!seq_print_ip_sym(s, field->ip, flags))
848 if (!trace_seq_puts(s, ": "))
851 if (!trace_seq_bprintf(s, field->fmt, field->buf))
854 return TRACE_TYPE_HANDLED;
857 return TRACE_TYPE_PARTIAL_LINE;
861 static enum print_line_t
862 trace_bprint_raw(struct trace_iterator *iter, int flags)
864 struct bprint_entry *field;
865 struct trace_seq *s = &iter->seq;
867 trace_assign_type(field, iter->ent);
869 if (!trace_seq_printf(s, ": %lx : ", field->ip))
872 if (!trace_seq_bprintf(s, field->fmt, field->buf))
875 return TRACE_TYPE_HANDLED;
878 return TRACE_TYPE_PARTIAL_LINE;
882 static struct trace_event trace_bprint_event = {
883 .type = TRACE_BPRINT,
884 .trace = trace_bprint_print,
885 .raw = trace_bprint_raw,
889 static enum print_line_t trace_print_print(struct trace_iterator *iter,
892 struct print_entry *field;
893 struct trace_seq *s = &iter->seq;
895 trace_assign_type(field, iter->ent);
897 if (!seq_print_ip_sym(s, field->ip, flags))
900 if (!trace_seq_printf(s, ": %s", field->buf))
903 return TRACE_TYPE_HANDLED;
906 return TRACE_TYPE_PARTIAL_LINE;
909 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
911 struct print_entry *field;
913 trace_assign_type(field, iter->ent);
915 if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
918 return TRACE_TYPE_HANDLED;
921 return TRACE_TYPE_PARTIAL_LINE;
924 static struct trace_event trace_print_event = {
926 .trace = trace_print_print,
927 .raw = trace_print_raw,
931 static struct trace_event *events[] __initdata = {
935 &trace_special_event,
937 &trace_user_stack_event,
943 __init static int init_events(void)
945 struct trace_event *event;
948 for (i = 0; events[i]; i++) {
951 ret = register_ftrace_event(event);
953 printk(KERN_WARNING "event %d failed to register\n",
961 device_initcall(init_events);