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