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 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 40 enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) 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) 51 return TRACE_TYPE_PARTIAL_LINE; 52 53 return TRACE_TYPE_HANDLED; 54 } 55 56 enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter) 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) 67 return TRACE_TYPE_PARTIAL_LINE; 68 69 return TRACE_TYPE_HANDLED; 70 } 71 72 /** 73 * trace_seq_printf - sequence printing of trace information 74 * @s: trace sequence descriptor 75 * @fmt: printf format string 76 * 77 * It returns 0 if the trace oversizes the buffer's free 78 * space, 1 otherwise. 79 * 80 * The tracer may use either sequence operations or its own 81 * copy to user routines. To simplify formating of a trace 82 * trace_seq_printf is used to store strings into a special 83 * buffer (@s). Then the output may be either used by 84 * the sequencer or pulled into another buffer. 85 */ 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 112 /** 113 * trace_seq_vprintf - sequence printing of trace information 114 * @s: trace sequence descriptor 115 * @fmt: printf format string 116 * 117 * The tracer may use either sequence operations or its own 118 * copy to user routines. To simplify formating of a trace 119 * trace_seq_printf is used to store strings into a special 120 * buffer (@s). Then the output may be either used by 121 * the sequencer or pulled into another buffer. 122 */ 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 } 144 EXPORT_SYMBOL_GPL(trace_seq_vprintf); 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 167 /** 168 * trace_seq_puts - trace sequence printing of simple string 169 * @s: trace sequence descriptor 170 * @str: simple string to record 171 * 172 * The tracer may use either the sequence operations or its own 173 * copy to user routines. This function records a simple string 174 * into a special buffer (@s) for later retrieval by a sequencer 175 * or other mechanism. 176 */ 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, 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; 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 (p->len && delim) 314 trace_seq_puts(p, delim); 315 trace_seq_puts(p, str); 316 } 317 318 /* check for left over flags */ 319 if (flags) { 320 if (p->len && delim) 321 trace_seq_puts(p, delim); 322 trace_seq_printf(p, "0x%lx", flags); 323 } 324 325 trace_seq_putc(p, 0); 326 327 return ret; 328 } 329 EXPORT_SYMBOL(ftrace_print_flags_seq); 330 331 const char * 332 ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, 333 const struct trace_print_flags *symbol_array) 334 { 335 int i; 336 const char *ret = p->buffer + p->len; 337 338 for (i = 0; symbol_array[i].name; i++) { 339 340 if (val != symbol_array[i].mask) 341 continue; 342 343 trace_seq_puts(p, symbol_array[i].name); 344 break; 345 } 346 347 if (!p->len) 348 trace_seq_printf(p, "0x%lx", val); 349 350 trace_seq_putc(p, 0); 351 352 return ret; 353 } 354 EXPORT_SYMBOL(ftrace_print_symbols_seq); 355 356 const char * 357 ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) 358 { 359 int i; 360 const char *ret = p->buffer + p->len; 361 362 for (i = 0; i < buf_len; i++) 363 trace_seq_printf(p, "%s%2.2x", i == 0 ? "" : " ", buf[i]); 364 365 trace_seq_putc(p, 0); 366 367 return ret; 368 } 369 EXPORT_SYMBOL(ftrace_print_hex_seq); 370 371 #ifdef CONFIG_KRETPROBES 372 static inline const char *kretprobed(const char *name) 373 { 374 static const char tramp_name[] = "kretprobe_trampoline"; 375 int size = sizeof(tramp_name); 376 377 if (strncmp(tramp_name, name, size) == 0) 378 return "[unknown/kretprobe'd]"; 379 return name; 380 } 381 #else 382 static inline const char *kretprobed(const char *name) 383 { 384 return name; 385 } 386 #endif /* CONFIG_KRETPROBES */ 387 388 static int 389 seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) 390 { 391 #ifdef CONFIG_KALLSYMS 392 char str[KSYM_SYMBOL_LEN]; 393 const char *name; 394 395 kallsyms_lookup(address, NULL, NULL, NULL, str); 396 397 name = kretprobed(str); 398 399 return trace_seq_printf(s, fmt, name); 400 #endif 401 return 1; 402 } 403 404 static int 405 seq_print_sym_offset(struct trace_seq *s, const char *fmt, 406 unsigned long address) 407 { 408 #ifdef CONFIG_KALLSYMS 409 char str[KSYM_SYMBOL_LEN]; 410 const char *name; 411 412 sprint_symbol(str, address); 413 name = kretprobed(str); 414 415 return trace_seq_printf(s, fmt, name); 416 #endif 417 return 1; 418 } 419 420 #ifndef CONFIG_64BIT 421 # define IP_FMT "%08lx" 422 #else 423 # define IP_FMT "%016lx" 424 #endif 425 426 int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm, 427 unsigned long ip, unsigned long sym_flags) 428 { 429 struct file *file = NULL; 430 unsigned long vmstart = 0; 431 int ret = 1; 432 433 if (s->full) 434 return 0; 435 436 if (mm) { 437 const struct vm_area_struct *vma; 438 439 down_read(&mm->mmap_sem); 440 vma = find_vma(mm, ip); 441 if (vma) { 442 file = vma->vm_file; 443 vmstart = vma->vm_start; 444 } 445 if (file) { 446 ret = trace_seq_path(s, &file->f_path); 447 if (ret) 448 ret = trace_seq_printf(s, "[+0x%lx]", 449 ip - vmstart); 450 } 451 up_read(&mm->mmap_sem); 452 } 453 if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file)) 454 ret = trace_seq_printf(s, " <" IP_FMT ">", ip); 455 return ret; 456 } 457 458 int 459 seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s, 460 unsigned long sym_flags) 461 { 462 struct mm_struct *mm = NULL; 463 int ret = 1; 464 unsigned int i; 465 466 if (trace_flags & TRACE_ITER_SYM_USEROBJ) { 467 struct task_struct *task; 468 /* 469 * we do the lookup on the thread group leader, 470 * since individual threads might have already quit! 471 */ 472 rcu_read_lock(); 473 task = find_task_by_vpid(entry->tgid); 474 if (task) 475 mm = get_task_mm(task); 476 rcu_read_unlock(); 477 } 478 479 for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { 480 unsigned long ip = entry->caller[i]; 481 482 if (ip == ULONG_MAX || !ret) 483 break; 484 if (ret) 485 ret = trace_seq_puts(s, " => "); 486 if (!ip) { 487 if (ret) 488 ret = trace_seq_puts(s, "??"); 489 if (ret) 490 ret = trace_seq_puts(s, "\n"); 491 continue; 492 } 493 if (!ret) 494 break; 495 if (ret) 496 ret = seq_print_user_ip(s, mm, ip, sym_flags); 497 ret = trace_seq_puts(s, "\n"); 498 } 499 500 if (mm) 501 mmput(mm); 502 return ret; 503 } 504 505 int 506 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) 507 { 508 int ret; 509 510 if (!ip) 511 return trace_seq_printf(s, "0"); 512 513 if (sym_flags & TRACE_ITER_SYM_OFFSET) 514 ret = seq_print_sym_offset(s, "%s", ip); 515 else 516 ret = seq_print_sym_short(s, "%s", ip); 517 518 if (!ret) 519 return 0; 520 521 if (sym_flags & TRACE_ITER_SYM_ADDR) 522 ret = trace_seq_printf(s, " <" IP_FMT ">", ip); 523 return ret; 524 } 525 526 /** 527 * trace_print_lat_fmt - print the irq, preempt and lockdep fields 528 * @s: trace seq struct to write to 529 * @entry: The trace entry field from the ring buffer 530 * 531 * Prints the generic fields of irqs off, in hard or softirq, preempt 532 * count. 533 */ 534 int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) 535 { 536 char hardsoft_irq; 537 char need_resched; 538 char irqs_off; 539 int hardirq; 540 int softirq; 541 int ret; 542 543 hardirq = entry->flags & TRACE_FLAG_HARDIRQ; 544 softirq = entry->flags & TRACE_FLAG_SOFTIRQ; 545 546 irqs_off = 547 (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : 548 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : 549 '.'; 550 need_resched = 551 (entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'; 552 hardsoft_irq = 553 (hardirq && softirq) ? 'H' : 554 hardirq ? 'h' : 555 softirq ? 's' : 556 '.'; 557 558 if (!trace_seq_printf(s, "%c%c%c", 559 irqs_off, need_resched, hardsoft_irq)) 560 return 0; 561 562 if (entry->preempt_count) 563 ret = trace_seq_printf(s, "%x", entry->preempt_count); 564 else 565 ret = trace_seq_putc(s, '.'); 566 567 return ret; 568 } 569 570 static int 571 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) 572 { 573 char comm[TASK_COMM_LEN]; 574 575 trace_find_cmdline(entry->pid, comm); 576 577 if (!trace_seq_printf(s, "%8.8s-%-5d %3d", 578 comm, entry->pid, cpu)) 579 return 0; 580 581 return trace_print_lat_fmt(s, entry); 582 } 583 584 static unsigned long preempt_mark_thresh = 100; 585 586 static int 587 lat_print_timestamp(struct trace_seq *s, u64 abs_usecs, 588 unsigned long rel_usecs) 589 { 590 return trace_seq_printf(s, " %4lldus%c: ", abs_usecs, 591 rel_usecs > preempt_mark_thresh ? '!' : 592 rel_usecs > 1 ? '+' : ' '); 593 } 594 595 int trace_print_context(struct trace_iterator *iter) 596 { 597 struct trace_seq *s = &iter->seq; 598 struct trace_entry *entry = iter->ent; 599 unsigned long long t = ns2usecs(iter->ts); 600 unsigned long usec_rem = do_div(t, USEC_PER_SEC); 601 unsigned long secs = (unsigned long)t; 602 char comm[TASK_COMM_LEN]; 603 604 trace_find_cmdline(entry->pid, comm); 605 606 return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ", 607 comm, entry->pid, iter->cpu, secs, usec_rem); 608 } 609 610 int trace_print_lat_context(struct trace_iterator *iter) 611 { 612 u64 next_ts; 613 int ret; 614 struct trace_seq *s = &iter->seq; 615 struct trace_entry *entry = iter->ent, 616 *next_entry = trace_find_next_entry(iter, NULL, 617 &next_ts); 618 unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); 619 unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); 620 unsigned long rel_usecs; 621 622 if (!next_entry) 623 next_ts = iter->ts; 624 rel_usecs = ns2usecs(next_ts - iter->ts); 625 626 if (verbose) { 627 char comm[TASK_COMM_LEN]; 628 629 trace_find_cmdline(entry->pid, comm); 630 631 ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]" 632 " %ld.%03ldms (+%ld.%03ldms): ", comm, 633 entry->pid, iter->cpu, entry->flags, 634 entry->preempt_count, iter->idx, 635 ns2usecs(iter->ts), 636 abs_usecs / USEC_PER_MSEC, 637 abs_usecs % USEC_PER_MSEC, 638 rel_usecs / USEC_PER_MSEC, 639 rel_usecs % USEC_PER_MSEC); 640 } else { 641 ret = lat_print_generic(s, entry, iter->cpu); 642 if (ret) 643 ret = lat_print_timestamp(s, abs_usecs, rel_usecs); 644 } 645 646 return ret; 647 } 648 649 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; 650 651 static int task_state_char(unsigned long state) 652 { 653 int bit = state ? __ffs(state) + 1 : 0; 654 655 return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?'; 656 } 657 658 /** 659 * ftrace_find_event - find a registered event 660 * @type: the type of event to look for 661 * 662 * Returns an event of type @type otherwise NULL 663 * Called with trace_event_read_lock() held. 664 */ 665 struct trace_event *ftrace_find_event(int type) 666 { 667 struct trace_event *event; 668 struct hlist_node *n; 669 unsigned key; 670 671 key = type & (EVENT_HASHSIZE - 1); 672 673 hlist_for_each_entry(event, n, &event_hash[key], node) { 674 if (event->type == type) 675 return event; 676 } 677 678 return NULL; 679 } 680 681 static LIST_HEAD(ftrace_event_list); 682 683 static int trace_search_list(struct list_head **list) 684 { 685 struct trace_event *e; 686 int last = __TRACE_LAST_TYPE; 687 688 if (list_empty(&ftrace_event_list)) { 689 *list = &ftrace_event_list; 690 return last + 1; 691 } 692 693 /* 694 * We used up all possible max events, 695 * lets see if somebody freed one. 696 */ 697 list_for_each_entry(e, &ftrace_event_list, list) { 698 if (e->type != last + 1) 699 break; 700 last++; 701 } 702 703 /* Did we used up all 65 thousand events??? */ 704 if ((last + 1) > FTRACE_MAX_EVENT) 705 return 0; 706 707 *list = &e->list; 708 return last + 1; 709 } 710 711 void trace_event_read_lock(void) 712 { 713 down_read(&trace_event_mutex); 714 } 715 716 void trace_event_read_unlock(void) 717 { 718 up_read(&trace_event_mutex); 719 } 720 721 /** 722 * register_ftrace_event - register output for an event type 723 * @event: the event type to register 724 * 725 * Event types are stored in a hash and this hash is used to 726 * find a way to print an event. If the @event->type is set 727 * then it will use that type, otherwise it will assign a 728 * type to use. 729 * 730 * If you assign your own type, please make sure it is added 731 * to the trace_type enum in trace.h, to avoid collisions 732 * with the dynamic types. 733 * 734 * Returns the event type number or zero on error. 735 */ 736 int register_ftrace_event(struct trace_event *event) 737 { 738 unsigned key; 739 int ret = 0; 740 741 down_write(&trace_event_mutex); 742 743 if (WARN_ON(!event)) 744 goto out; 745 746 if (WARN_ON(!event->funcs)) 747 goto out; 748 749 INIT_LIST_HEAD(&event->list); 750 751 if (!event->type) { 752 struct list_head *list = NULL; 753 754 if (next_event_type > FTRACE_MAX_EVENT) { 755 756 event->type = trace_search_list(&list); 757 if (!event->type) 758 goto out; 759 760 } else { 761 762 event->type = next_event_type++; 763 list = &ftrace_event_list; 764 } 765 766 if (WARN_ON(ftrace_find_event(event->type))) 767 goto out; 768 769 list_add_tail(&event->list, list); 770 771 } else if (event->type > __TRACE_LAST_TYPE) { 772 printk(KERN_WARNING "Need to add type to trace.h\n"); 773 WARN_ON(1); 774 goto out; 775 } else { 776 /* Is this event already used */ 777 if (ftrace_find_event(event->type)) 778 goto out; 779 } 780 781 if (event->funcs->trace == NULL) 782 event->funcs->trace = trace_nop_print; 783 if (event->funcs->raw == NULL) 784 event->funcs->raw = trace_nop_print; 785 if (event->funcs->hex == NULL) 786 event->funcs->hex = trace_nop_print; 787 if (event->funcs->binary == NULL) 788 event->funcs->binary = trace_nop_print; 789 790 key = event->type & (EVENT_HASHSIZE - 1); 791 792 hlist_add_head(&event->node, &event_hash[key]); 793 794 ret = event->type; 795 out: 796 up_write(&trace_event_mutex); 797 798 return ret; 799 } 800 EXPORT_SYMBOL_GPL(register_ftrace_event); 801 802 /* 803 * Used by module code with the trace_event_mutex held for write. 804 */ 805 int __unregister_ftrace_event(struct trace_event *event) 806 { 807 hlist_del(&event->node); 808 list_del(&event->list); 809 return 0; 810 } 811 812 /** 813 * unregister_ftrace_event - remove a no longer used event 814 * @event: the event to remove 815 */ 816 int unregister_ftrace_event(struct trace_event *event) 817 { 818 down_write(&trace_event_mutex); 819 __unregister_ftrace_event(event); 820 up_write(&trace_event_mutex); 821 822 return 0; 823 } 824 EXPORT_SYMBOL_GPL(unregister_ftrace_event); 825 826 /* 827 * Standard events 828 */ 829 830 enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags, 831 struct trace_event *event) 832 { 833 return TRACE_TYPE_HANDLED; 834 } 835 836 /* TRACE_FN */ 837 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags, 838 struct trace_event *event) 839 { 840 struct ftrace_entry *field; 841 struct trace_seq *s = &iter->seq; 842 843 trace_assign_type(field, iter->ent); 844 845 if (!seq_print_ip_sym(s, field->ip, flags)) 846 goto partial; 847 848 if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) { 849 if (!trace_seq_printf(s, " <-")) 850 goto partial; 851 if (!seq_print_ip_sym(s, 852 field->parent_ip, 853 flags)) 854 goto partial; 855 } 856 if (!trace_seq_printf(s, "\n")) 857 goto partial; 858 859 return TRACE_TYPE_HANDLED; 860 861 partial: 862 return TRACE_TYPE_PARTIAL_LINE; 863 } 864 865 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags, 866 struct trace_event *event) 867 { 868 struct ftrace_entry *field; 869 870 trace_assign_type(field, iter->ent); 871 872 if (!trace_seq_printf(&iter->seq, "%lx %lx\n", 873 field->ip, 874 field->parent_ip)) 875 return TRACE_TYPE_PARTIAL_LINE; 876 877 return TRACE_TYPE_HANDLED; 878 } 879 880 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags, 881 struct trace_event *event) 882 { 883 struct ftrace_entry *field; 884 struct trace_seq *s = &iter->seq; 885 886 trace_assign_type(field, iter->ent); 887 888 SEQ_PUT_HEX_FIELD_RET(s, field->ip); 889 SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip); 890 891 return TRACE_TYPE_HANDLED; 892 } 893 894 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags, 895 struct trace_event *event) 896 { 897 struct ftrace_entry *field; 898 struct trace_seq *s = &iter->seq; 899 900 trace_assign_type(field, iter->ent); 901 902 SEQ_PUT_FIELD_RET(s, field->ip); 903 SEQ_PUT_FIELD_RET(s, field->parent_ip); 904 905 return TRACE_TYPE_HANDLED; 906 } 907 908 static struct trace_event_functions trace_fn_funcs = { 909 .trace = trace_fn_trace, 910 .raw = trace_fn_raw, 911 .hex = trace_fn_hex, 912 .binary = trace_fn_bin, 913 }; 914 915 static struct trace_event trace_fn_event = { 916 .type = TRACE_FN, 917 .funcs = &trace_fn_funcs, 918 }; 919 920 /* TRACE_CTX an TRACE_WAKE */ 921 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, 922 char *delim) 923 { 924 struct ctx_switch_entry *field; 925 char comm[TASK_COMM_LEN]; 926 int S, T; 927 928 929 trace_assign_type(field, iter->ent); 930 931 T = task_state_char(field->next_state); 932 S = task_state_char(field->prev_state); 933 trace_find_cmdline(field->next_pid, comm); 934 if (!trace_seq_printf(&iter->seq, 935 " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", 936 field->prev_pid, 937 field->prev_prio, 938 S, delim, 939 field->next_cpu, 940 field->next_pid, 941 field->next_prio, 942 T, comm)) 943 return TRACE_TYPE_PARTIAL_LINE; 944 945 return TRACE_TYPE_HANDLED; 946 } 947 948 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags, 949 struct trace_event *event) 950 { 951 return trace_ctxwake_print(iter, "==>"); 952 } 953 954 static enum print_line_t trace_wake_print(struct trace_iterator *iter, 955 int flags, struct trace_event *event) 956 { 957 return trace_ctxwake_print(iter, " +"); 958 } 959 960 static int trace_ctxwake_raw(struct trace_iterator *iter, char S) 961 { 962 struct ctx_switch_entry *field; 963 int T; 964 965 trace_assign_type(field, iter->ent); 966 967 if (!S) 968 S = task_state_char(field->prev_state); 969 T = task_state_char(field->next_state); 970 if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", 971 field->prev_pid, 972 field->prev_prio, 973 S, 974 field->next_cpu, 975 field->next_pid, 976 field->next_prio, 977 T)) 978 return TRACE_TYPE_PARTIAL_LINE; 979 980 return TRACE_TYPE_HANDLED; 981 } 982 983 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags, 984 struct trace_event *event) 985 { 986 return trace_ctxwake_raw(iter, 0); 987 } 988 989 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags, 990 struct trace_event *event) 991 { 992 return trace_ctxwake_raw(iter, '+'); 993 } 994 995 996 static int trace_ctxwake_hex(struct trace_iterator *iter, char S) 997 { 998 struct ctx_switch_entry *field; 999 struct trace_seq *s = &iter->seq; 1000 int T; 1001 1002 trace_assign_type(field, iter->ent); 1003 1004 if (!S) 1005 S = task_state_char(field->prev_state); 1006 T = task_state_char(field->next_state); 1007 1008 SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid); 1009 SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio); 1010 SEQ_PUT_HEX_FIELD_RET(s, S); 1011 SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu); 1012 SEQ_PUT_HEX_FIELD_RET(s, field->next_pid); 1013 SEQ_PUT_HEX_FIELD_RET(s, field->next_prio); 1014 SEQ_PUT_HEX_FIELD_RET(s, T); 1015 1016 return TRACE_TYPE_HANDLED; 1017 } 1018 1019 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags, 1020 struct trace_event *event) 1021 { 1022 return trace_ctxwake_hex(iter, 0); 1023 } 1024 1025 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags, 1026 struct trace_event *event) 1027 { 1028 return trace_ctxwake_hex(iter, '+'); 1029 } 1030 1031 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, 1032 int flags, struct trace_event *event) 1033 { 1034 struct ctx_switch_entry *field; 1035 struct trace_seq *s = &iter->seq; 1036 1037 trace_assign_type(field, iter->ent); 1038 1039 SEQ_PUT_FIELD_RET(s, field->prev_pid); 1040 SEQ_PUT_FIELD_RET(s, field->prev_prio); 1041 SEQ_PUT_FIELD_RET(s, field->prev_state); 1042 SEQ_PUT_FIELD_RET(s, field->next_pid); 1043 SEQ_PUT_FIELD_RET(s, field->next_prio); 1044 SEQ_PUT_FIELD_RET(s, field->next_state); 1045 1046 return TRACE_TYPE_HANDLED; 1047 } 1048 1049 static struct trace_event_functions trace_ctx_funcs = { 1050 .trace = trace_ctx_print, 1051 .raw = trace_ctx_raw, 1052 .hex = trace_ctx_hex, 1053 .binary = trace_ctxwake_bin, 1054 }; 1055 1056 static struct trace_event trace_ctx_event = { 1057 .type = TRACE_CTX, 1058 .funcs = &trace_ctx_funcs, 1059 }; 1060 1061 static struct trace_event_functions trace_wake_funcs = { 1062 .trace = trace_wake_print, 1063 .raw = trace_wake_raw, 1064 .hex = trace_wake_hex, 1065 .binary = trace_ctxwake_bin, 1066 }; 1067 1068 static struct trace_event trace_wake_event = { 1069 .type = TRACE_WAKE, 1070 .funcs = &trace_wake_funcs, 1071 }; 1072 1073 /* TRACE_STACK */ 1074 1075 static enum print_line_t trace_stack_print(struct trace_iterator *iter, 1076 int flags, struct trace_event *event) 1077 { 1078 struct stack_entry *field; 1079 struct trace_seq *s = &iter->seq; 1080 int i; 1081 1082 trace_assign_type(field, iter->ent); 1083 1084 if (!trace_seq_puts(s, "<stack trace>\n")) 1085 goto partial; 1086 for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { 1087 if (!field->caller[i] || (field->caller[i] == ULONG_MAX)) 1088 break; 1089 if (!trace_seq_puts(s, " => ")) 1090 goto partial; 1091 1092 if (!seq_print_ip_sym(s, field->caller[i], flags)) 1093 goto partial; 1094 if (!trace_seq_puts(s, "\n")) 1095 goto partial; 1096 } 1097 1098 return TRACE_TYPE_HANDLED; 1099 1100 partial: 1101 return TRACE_TYPE_PARTIAL_LINE; 1102 } 1103 1104 static struct trace_event_functions trace_stack_funcs = { 1105 .trace = trace_stack_print, 1106 }; 1107 1108 static struct trace_event trace_stack_event = { 1109 .type = TRACE_STACK, 1110 .funcs = &trace_stack_funcs, 1111 }; 1112 1113 /* TRACE_USER_STACK */ 1114 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, 1115 int flags, struct trace_event *event) 1116 { 1117 struct userstack_entry *field; 1118 struct trace_seq *s = &iter->seq; 1119 1120 trace_assign_type(field, iter->ent); 1121 1122 if (!trace_seq_puts(s, "<user stack trace>\n")) 1123 goto partial; 1124 1125 if (!seq_print_userip_objs(field, s, flags)) 1126 goto partial; 1127 1128 return TRACE_TYPE_HANDLED; 1129 1130 partial: 1131 return TRACE_TYPE_PARTIAL_LINE; 1132 } 1133 1134 static struct trace_event_functions trace_user_stack_funcs = { 1135 .trace = trace_user_stack_print, 1136 }; 1137 1138 static struct trace_event trace_user_stack_event = { 1139 .type = TRACE_USER_STACK, 1140 .funcs = &trace_user_stack_funcs, 1141 }; 1142 1143 /* TRACE_BPRINT */ 1144 static enum print_line_t 1145 trace_bprint_print(struct trace_iterator *iter, int flags, 1146 struct trace_event *event) 1147 { 1148 struct trace_entry *entry = iter->ent; 1149 struct trace_seq *s = &iter->seq; 1150 struct bprint_entry *field; 1151 1152 trace_assign_type(field, entry); 1153 1154 if (!seq_print_ip_sym(s, field->ip, flags)) 1155 goto partial; 1156 1157 if (!trace_seq_puts(s, ": ")) 1158 goto partial; 1159 1160 if (!trace_seq_bprintf(s, field->fmt, field->buf)) 1161 goto partial; 1162 1163 return TRACE_TYPE_HANDLED; 1164 1165 partial: 1166 return TRACE_TYPE_PARTIAL_LINE; 1167 } 1168 1169 1170 static enum print_line_t 1171 trace_bprint_raw(struct trace_iterator *iter, int flags, 1172 struct trace_event *event) 1173 { 1174 struct bprint_entry *field; 1175 struct trace_seq *s = &iter->seq; 1176 1177 trace_assign_type(field, iter->ent); 1178 1179 if (!trace_seq_printf(s, ": %lx : ", field->ip)) 1180 goto partial; 1181 1182 if (!trace_seq_bprintf(s, field->fmt, field->buf)) 1183 goto partial; 1184 1185 return TRACE_TYPE_HANDLED; 1186 1187 partial: 1188 return TRACE_TYPE_PARTIAL_LINE; 1189 } 1190 1191 static struct trace_event_functions trace_bprint_funcs = { 1192 .trace = trace_bprint_print, 1193 .raw = trace_bprint_raw, 1194 }; 1195 1196 static struct trace_event trace_bprint_event = { 1197 .type = TRACE_BPRINT, 1198 .funcs = &trace_bprint_funcs, 1199 }; 1200 1201 /* TRACE_PRINT */ 1202 static enum print_line_t trace_print_print(struct trace_iterator *iter, 1203 int flags, struct trace_event *event) 1204 { 1205 struct print_entry *field; 1206 struct trace_seq *s = &iter->seq; 1207 1208 trace_assign_type(field, iter->ent); 1209 1210 if (!seq_print_ip_sym(s, field->ip, flags)) 1211 goto partial; 1212 1213 if (!trace_seq_printf(s, ": %s", field->buf)) 1214 goto partial; 1215 1216 return TRACE_TYPE_HANDLED; 1217 1218 partial: 1219 return TRACE_TYPE_PARTIAL_LINE; 1220 } 1221 1222 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, 1223 struct trace_event *event) 1224 { 1225 struct print_entry *field; 1226 1227 trace_assign_type(field, iter->ent); 1228 1229 if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf)) 1230 goto partial; 1231 1232 return TRACE_TYPE_HANDLED; 1233 1234 partial: 1235 return TRACE_TYPE_PARTIAL_LINE; 1236 } 1237 1238 static struct trace_event_functions trace_print_funcs = { 1239 .trace = trace_print_print, 1240 .raw = trace_print_raw, 1241 }; 1242 1243 static struct trace_event trace_print_event = { 1244 .type = TRACE_PRINT, 1245 .funcs = &trace_print_funcs, 1246 }; 1247 1248 1249 static struct trace_event *events[] __initdata = { 1250 &trace_fn_event, 1251 &trace_ctx_event, 1252 &trace_wake_event, 1253 &trace_stack_event, 1254 &trace_user_stack_event, 1255 &trace_bprint_event, 1256 &trace_print_event, 1257 NULL 1258 }; 1259 1260 __init static int init_events(void) 1261 { 1262 struct trace_event *event; 1263 int i, ret; 1264 1265 for (i = 0; events[i]; i++) { 1266 event = events[i]; 1267 1268 ret = register_ftrace_event(event); 1269 if (!ret) { 1270 printk(KERN_WARNING "event %d failed to register\n", 1271 event->type); 1272 WARN_ON_ONCE(1); 1273 } 1274 } 1275 1276 return 0; 1277 } 1278 device_initcall(init_events); 1279