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