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