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