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: ", ftrace_event_name(event)); 435 if (!ret) 436 return TRACE_TYPE_PARTIAL_LINE; 437 438 return 0; 439 } 440 EXPORT_SYMBOL(ftrace_raw_output_prep); 441 442 static int ftrace_output_raw(struct trace_iterator *iter, char *name, 443 char *fmt, va_list ap) 444 { 445 struct trace_seq *s = &iter->seq; 446 int ret; 447 448 ret = trace_seq_printf(s, "%s: ", name); 449 if (!ret) 450 return TRACE_TYPE_PARTIAL_LINE; 451 452 ret = trace_seq_vprintf(s, fmt, ap); 453 454 if (!ret) 455 return TRACE_TYPE_PARTIAL_LINE; 456 457 return TRACE_TYPE_HANDLED; 458 } 459 460 int ftrace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...) 461 { 462 va_list ap; 463 int ret; 464 465 va_start(ap, fmt); 466 ret = ftrace_output_raw(iter, name, fmt, ap); 467 va_end(ap); 468 469 return ret; 470 } 471 EXPORT_SYMBOL_GPL(ftrace_output_call); 472 473 #ifdef CONFIG_KRETPROBES 474 static inline const char *kretprobed(const char *name) 475 { 476 static const char tramp_name[] = "kretprobe_trampoline"; 477 int size = sizeof(tramp_name); 478 479 if (strncmp(tramp_name, name, size) == 0) 480 return "[unknown/kretprobe'd]"; 481 return name; 482 } 483 #else 484 static inline const char *kretprobed(const char *name) 485 { 486 return name; 487 } 488 #endif /* CONFIG_KRETPROBES */ 489 490 static int 491 seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) 492 { 493 #ifdef CONFIG_KALLSYMS 494 char str[KSYM_SYMBOL_LEN]; 495 const char *name; 496 497 kallsyms_lookup(address, NULL, NULL, NULL, str); 498 499 name = kretprobed(str); 500 501 return trace_seq_printf(s, fmt, name); 502 #endif 503 return 1; 504 } 505 506 static int 507 seq_print_sym_offset(struct trace_seq *s, const char *fmt, 508 unsigned long address) 509 { 510 #ifdef CONFIG_KALLSYMS 511 char str[KSYM_SYMBOL_LEN]; 512 const char *name; 513 514 sprint_symbol(str, address); 515 name = kretprobed(str); 516 517 return trace_seq_printf(s, fmt, name); 518 #endif 519 return 1; 520 } 521 522 #ifndef CONFIG_64BIT 523 # define IP_FMT "%08lx" 524 #else 525 # define IP_FMT "%016lx" 526 #endif 527 528 int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm, 529 unsigned long ip, unsigned long sym_flags) 530 { 531 struct file *file = NULL; 532 unsigned long vmstart = 0; 533 int ret = 1; 534 535 if (s->full) 536 return 0; 537 538 if (mm) { 539 const struct vm_area_struct *vma; 540 541 down_read(&mm->mmap_sem); 542 vma = find_vma(mm, ip); 543 if (vma) { 544 file = vma->vm_file; 545 vmstart = vma->vm_start; 546 } 547 if (file) { 548 ret = trace_seq_path(s, &file->f_path); 549 if (ret) 550 ret = trace_seq_printf(s, "[+0x%lx]", 551 ip - vmstart); 552 } 553 up_read(&mm->mmap_sem); 554 } 555 if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file)) 556 ret = trace_seq_printf(s, " <" IP_FMT ">", ip); 557 return ret; 558 } 559 560 int 561 seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s, 562 unsigned long sym_flags) 563 { 564 struct mm_struct *mm = NULL; 565 int ret = 1; 566 unsigned int i; 567 568 if (trace_flags & TRACE_ITER_SYM_USEROBJ) { 569 struct task_struct *task; 570 /* 571 * we do the lookup on the thread group leader, 572 * since individual threads might have already quit! 573 */ 574 rcu_read_lock(); 575 task = find_task_by_vpid(entry->tgid); 576 if (task) 577 mm = get_task_mm(task); 578 rcu_read_unlock(); 579 } 580 581 for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { 582 unsigned long ip = entry->caller[i]; 583 584 if (ip == ULONG_MAX || !ret) 585 break; 586 if (ret) 587 ret = trace_seq_puts(s, " => "); 588 if (!ip) { 589 if (ret) 590 ret = trace_seq_puts(s, "??"); 591 if (ret) 592 ret = trace_seq_putc(s, '\n'); 593 continue; 594 } 595 if (!ret) 596 break; 597 if (ret) 598 ret = seq_print_user_ip(s, mm, ip, sym_flags); 599 ret = trace_seq_putc(s, '\n'); 600 } 601 602 if (mm) 603 mmput(mm); 604 return ret; 605 } 606 607 int 608 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) 609 { 610 int ret; 611 612 if (!ip) 613 return trace_seq_putc(s, '0'); 614 615 if (sym_flags & TRACE_ITER_SYM_OFFSET) 616 ret = seq_print_sym_offset(s, "%s", ip); 617 else 618 ret = seq_print_sym_short(s, "%s", ip); 619 620 if (!ret) 621 return 0; 622 623 if (sym_flags & TRACE_ITER_SYM_ADDR) 624 ret = trace_seq_printf(s, " <" IP_FMT ">", ip); 625 return ret; 626 } 627 628 /** 629 * trace_print_lat_fmt - print the irq, preempt and lockdep fields 630 * @s: trace seq struct to write to 631 * @entry: The trace entry field from the ring buffer 632 * 633 * Prints the generic fields of irqs off, in hard or softirq, preempt 634 * count. 635 */ 636 int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) 637 { 638 char hardsoft_irq; 639 char need_resched; 640 char irqs_off; 641 int hardirq; 642 int softirq; 643 int ret; 644 645 hardirq = entry->flags & TRACE_FLAG_HARDIRQ; 646 softirq = entry->flags & TRACE_FLAG_SOFTIRQ; 647 648 irqs_off = 649 (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : 650 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : 651 '.'; 652 653 switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | 654 TRACE_FLAG_PREEMPT_RESCHED)) { 655 case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED: 656 need_resched = 'N'; 657 break; 658 case TRACE_FLAG_NEED_RESCHED: 659 need_resched = 'n'; 660 break; 661 case TRACE_FLAG_PREEMPT_RESCHED: 662 need_resched = 'p'; 663 break; 664 default: 665 need_resched = '.'; 666 break; 667 } 668 669 hardsoft_irq = 670 (hardirq && softirq) ? 'H' : 671 hardirq ? 'h' : 672 softirq ? 's' : 673 '.'; 674 675 if (!trace_seq_printf(s, "%c%c%c", 676 irqs_off, need_resched, hardsoft_irq)) 677 return 0; 678 679 if (entry->preempt_count) 680 ret = trace_seq_printf(s, "%x", entry->preempt_count); 681 else 682 ret = trace_seq_putc(s, '.'); 683 684 return ret; 685 } 686 687 static int 688 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) 689 { 690 char comm[TASK_COMM_LEN]; 691 692 trace_find_cmdline(entry->pid, comm); 693 694 if (!trace_seq_printf(s, "%8.8s-%-5d %3d", 695 comm, entry->pid, cpu)) 696 return 0; 697 698 return trace_print_lat_fmt(s, entry); 699 } 700 701 static unsigned long preempt_mark_thresh_us = 100; 702 703 static int 704 lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) 705 { 706 unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE; 707 unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; 708 unsigned long long abs_ts = iter->ts - iter->trace_buffer->time_start; 709 unsigned long long rel_ts = next_ts - iter->ts; 710 struct trace_seq *s = &iter->seq; 711 712 if (in_ns) { 713 abs_ts = ns2usecs(abs_ts); 714 rel_ts = ns2usecs(rel_ts); 715 } 716 717 if (verbose && in_ns) { 718 unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC); 719 unsigned long abs_msec = (unsigned long)abs_ts; 720 unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC); 721 unsigned long rel_msec = (unsigned long)rel_ts; 722 723 return trace_seq_printf( 724 s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ", 725 ns2usecs(iter->ts), 726 abs_msec, abs_usec, 727 rel_msec, rel_usec); 728 } else if (verbose && !in_ns) { 729 return trace_seq_printf( 730 s, "[%016llx] %lld (+%lld): ", 731 iter->ts, abs_ts, rel_ts); 732 } else if (!verbose && in_ns) { 733 return trace_seq_printf( 734 s, " %4lldus%c: ", 735 abs_ts, 736 rel_ts > preempt_mark_thresh_us ? '!' : 737 rel_ts > 1 ? '+' : ' '); 738 } else { /* !verbose && !in_ns */ 739 return trace_seq_printf(s, " %4lld: ", abs_ts); 740 } 741 } 742 743 int trace_print_context(struct trace_iterator *iter) 744 { 745 struct trace_seq *s = &iter->seq; 746 struct trace_entry *entry = iter->ent; 747 unsigned long long t; 748 unsigned long secs, usec_rem; 749 char comm[TASK_COMM_LEN]; 750 int ret; 751 752 trace_find_cmdline(entry->pid, comm); 753 754 ret = trace_seq_printf(s, "%16s-%-5d [%03d] ", 755 comm, entry->pid, iter->cpu); 756 if (!ret) 757 return 0; 758 759 if (trace_flags & TRACE_ITER_IRQ_INFO) { 760 ret = trace_print_lat_fmt(s, entry); 761 if (!ret) 762 return 0; 763 } 764 765 if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { 766 t = ns2usecs(iter->ts); 767 usec_rem = do_div(t, USEC_PER_SEC); 768 secs = (unsigned long)t; 769 return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); 770 } else 771 return trace_seq_printf(s, " %12llu: ", iter->ts); 772 } 773 774 int trace_print_lat_context(struct trace_iterator *iter) 775 { 776 u64 next_ts; 777 int ret; 778 /* trace_find_next_entry will reset ent_size */ 779 int ent_size = iter->ent_size; 780 struct trace_seq *s = &iter->seq; 781 struct trace_entry *entry = iter->ent, 782 *next_entry = trace_find_next_entry(iter, NULL, 783 &next_ts); 784 unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); 785 786 /* Restore the original ent_size */ 787 iter->ent_size = ent_size; 788 789 if (!next_entry) 790 next_ts = iter->ts; 791 792 if (verbose) { 793 char comm[TASK_COMM_LEN]; 794 795 trace_find_cmdline(entry->pid, comm); 796 797 ret = trace_seq_printf( 798 s, "%16s %5d %3d %d %08x %08lx ", 799 comm, entry->pid, iter->cpu, entry->flags, 800 entry->preempt_count, iter->idx); 801 } else { 802 ret = lat_print_generic(s, entry, iter->cpu); 803 } 804 805 if (ret) 806 ret = lat_print_timestamp(iter, next_ts); 807 808 return ret; 809 } 810 811 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; 812 813 static int task_state_char(unsigned long state) 814 { 815 int bit = state ? __ffs(state) + 1 : 0; 816 817 return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?'; 818 } 819 820 /** 821 * ftrace_find_event - find a registered event 822 * @type: the type of event to look for 823 * 824 * Returns an event of type @type otherwise NULL 825 * Called with trace_event_read_lock() held. 826 */ 827 struct trace_event *ftrace_find_event(int type) 828 { 829 struct trace_event *event; 830 unsigned key; 831 832 key = type & (EVENT_HASHSIZE - 1); 833 834 hlist_for_each_entry(event, &event_hash[key], node) { 835 if (event->type == type) 836 return event; 837 } 838 839 return NULL; 840 } 841 842 static LIST_HEAD(ftrace_event_list); 843 844 static int trace_search_list(struct list_head **list) 845 { 846 struct trace_event *e; 847 int last = __TRACE_LAST_TYPE; 848 849 if (list_empty(&ftrace_event_list)) { 850 *list = &ftrace_event_list; 851 return last + 1; 852 } 853 854 /* 855 * We used up all possible max events, 856 * lets see if somebody freed one. 857 */ 858 list_for_each_entry(e, &ftrace_event_list, list) { 859 if (e->type != last + 1) 860 break; 861 last++; 862 } 863 864 /* Did we used up all 65 thousand events??? */ 865 if ((last + 1) > FTRACE_MAX_EVENT) 866 return 0; 867 868 *list = &e->list; 869 return last + 1; 870 } 871 872 void trace_event_read_lock(void) 873 { 874 down_read(&trace_event_sem); 875 } 876 877 void trace_event_read_unlock(void) 878 { 879 up_read(&trace_event_sem); 880 } 881 882 /** 883 * register_ftrace_event - register output for an event type 884 * @event: the event type to register 885 * 886 * Event types are stored in a hash and this hash is used to 887 * find a way to print an event. If the @event->type is set 888 * then it will use that type, otherwise it will assign a 889 * type to use. 890 * 891 * If you assign your own type, please make sure it is added 892 * to the trace_type enum in trace.h, to avoid collisions 893 * with the dynamic types. 894 * 895 * Returns the event type number or zero on error. 896 */ 897 int register_ftrace_event(struct trace_event *event) 898 { 899 unsigned key; 900 int ret = 0; 901 902 down_write(&trace_event_sem); 903 904 if (WARN_ON(!event)) 905 goto out; 906 907 if (WARN_ON(!event->funcs)) 908 goto out; 909 910 INIT_LIST_HEAD(&event->list); 911 912 if (!event->type) { 913 struct list_head *list = NULL; 914 915 if (next_event_type > FTRACE_MAX_EVENT) { 916 917 event->type = trace_search_list(&list); 918 if (!event->type) 919 goto out; 920 921 } else { 922 923 event->type = next_event_type++; 924 list = &ftrace_event_list; 925 } 926 927 if (WARN_ON(ftrace_find_event(event->type))) 928 goto out; 929 930 list_add_tail(&event->list, list); 931 932 } else if (event->type > __TRACE_LAST_TYPE) { 933 printk(KERN_WARNING "Need to add type to trace.h\n"); 934 WARN_ON(1); 935 goto out; 936 } else { 937 /* Is this event already used */ 938 if (ftrace_find_event(event->type)) 939 goto out; 940 } 941 942 if (event->funcs->trace == NULL) 943 event->funcs->trace = trace_nop_print; 944 if (event->funcs->raw == NULL) 945 event->funcs->raw = trace_nop_print; 946 if (event->funcs->hex == NULL) 947 event->funcs->hex = trace_nop_print; 948 if (event->funcs->binary == NULL) 949 event->funcs->binary = trace_nop_print; 950 951 key = event->type & (EVENT_HASHSIZE - 1); 952 953 hlist_add_head(&event->node, &event_hash[key]); 954 955 ret = event->type; 956 out: 957 up_write(&trace_event_sem); 958 959 return ret; 960 } 961 EXPORT_SYMBOL_GPL(register_ftrace_event); 962 963 /* 964 * Used by module code with the trace_event_sem held for write. 965 */ 966 int __unregister_ftrace_event(struct trace_event *event) 967 { 968 hlist_del(&event->node); 969 list_del(&event->list); 970 return 0; 971 } 972 973 /** 974 * unregister_ftrace_event - remove a no longer used event 975 * @event: the event to remove 976 */ 977 int unregister_ftrace_event(struct trace_event *event) 978 { 979 down_write(&trace_event_sem); 980 __unregister_ftrace_event(event); 981 up_write(&trace_event_sem); 982 983 return 0; 984 } 985 EXPORT_SYMBOL_GPL(unregister_ftrace_event); 986 987 /* 988 * Standard events 989 */ 990 991 enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags, 992 struct trace_event *event) 993 { 994 if (!trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type)) 995 return TRACE_TYPE_PARTIAL_LINE; 996 997 return TRACE_TYPE_HANDLED; 998 } 999 1000 /* TRACE_FN */ 1001 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags, 1002 struct trace_event *event) 1003 { 1004 struct ftrace_entry *field; 1005 struct trace_seq *s = &iter->seq; 1006 1007 trace_assign_type(field, iter->ent); 1008 1009 if (!seq_print_ip_sym(s, field->ip, flags)) 1010 goto partial; 1011 1012 if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) { 1013 if (!trace_seq_puts(s, " <-")) 1014 goto partial; 1015 if (!seq_print_ip_sym(s, 1016 field->parent_ip, 1017 flags)) 1018 goto partial; 1019 } 1020 if (!trace_seq_putc(s, '\n')) 1021 goto partial; 1022 1023 return TRACE_TYPE_HANDLED; 1024 1025 partial: 1026 return TRACE_TYPE_PARTIAL_LINE; 1027 } 1028 1029 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags, 1030 struct trace_event *event) 1031 { 1032 struct ftrace_entry *field; 1033 1034 trace_assign_type(field, iter->ent); 1035 1036 if (!trace_seq_printf(&iter->seq, "%lx %lx\n", 1037 field->ip, 1038 field->parent_ip)) 1039 return TRACE_TYPE_PARTIAL_LINE; 1040 1041 return TRACE_TYPE_HANDLED; 1042 } 1043 1044 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags, 1045 struct trace_event *event) 1046 { 1047 struct ftrace_entry *field; 1048 struct trace_seq *s = &iter->seq; 1049 1050 trace_assign_type(field, iter->ent); 1051 1052 SEQ_PUT_HEX_FIELD_RET(s, field->ip); 1053 SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip); 1054 1055 return TRACE_TYPE_HANDLED; 1056 } 1057 1058 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags, 1059 struct trace_event *event) 1060 { 1061 struct ftrace_entry *field; 1062 struct trace_seq *s = &iter->seq; 1063 1064 trace_assign_type(field, iter->ent); 1065 1066 SEQ_PUT_FIELD_RET(s, field->ip); 1067 SEQ_PUT_FIELD_RET(s, field->parent_ip); 1068 1069 return TRACE_TYPE_HANDLED; 1070 } 1071 1072 static struct trace_event_functions trace_fn_funcs = { 1073 .trace = trace_fn_trace, 1074 .raw = trace_fn_raw, 1075 .hex = trace_fn_hex, 1076 .binary = trace_fn_bin, 1077 }; 1078 1079 static struct trace_event trace_fn_event = { 1080 .type = TRACE_FN, 1081 .funcs = &trace_fn_funcs, 1082 }; 1083 1084 /* TRACE_CTX an TRACE_WAKE */ 1085 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, 1086 char *delim) 1087 { 1088 struct ctx_switch_entry *field; 1089 char comm[TASK_COMM_LEN]; 1090 int S, T; 1091 1092 1093 trace_assign_type(field, iter->ent); 1094 1095 T = task_state_char(field->next_state); 1096 S = task_state_char(field->prev_state); 1097 trace_find_cmdline(field->next_pid, comm); 1098 if (!trace_seq_printf(&iter->seq, 1099 " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", 1100 field->prev_pid, 1101 field->prev_prio, 1102 S, delim, 1103 field->next_cpu, 1104 field->next_pid, 1105 field->next_prio, 1106 T, comm)) 1107 return TRACE_TYPE_PARTIAL_LINE; 1108 1109 return TRACE_TYPE_HANDLED; 1110 } 1111 1112 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags, 1113 struct trace_event *event) 1114 { 1115 return trace_ctxwake_print(iter, "==>"); 1116 } 1117 1118 static enum print_line_t trace_wake_print(struct trace_iterator *iter, 1119 int flags, struct trace_event *event) 1120 { 1121 return trace_ctxwake_print(iter, " +"); 1122 } 1123 1124 static int trace_ctxwake_raw(struct trace_iterator *iter, char S) 1125 { 1126 struct ctx_switch_entry *field; 1127 int T; 1128 1129 trace_assign_type(field, iter->ent); 1130 1131 if (!S) 1132 S = task_state_char(field->prev_state); 1133 T = task_state_char(field->next_state); 1134 if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", 1135 field->prev_pid, 1136 field->prev_prio, 1137 S, 1138 field->next_cpu, 1139 field->next_pid, 1140 field->next_prio, 1141 T)) 1142 return TRACE_TYPE_PARTIAL_LINE; 1143 1144 return TRACE_TYPE_HANDLED; 1145 } 1146 1147 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags, 1148 struct trace_event *event) 1149 { 1150 return trace_ctxwake_raw(iter, 0); 1151 } 1152 1153 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags, 1154 struct trace_event *event) 1155 { 1156 return trace_ctxwake_raw(iter, '+'); 1157 } 1158 1159 1160 static int trace_ctxwake_hex(struct trace_iterator *iter, char S) 1161 { 1162 struct ctx_switch_entry *field; 1163 struct trace_seq *s = &iter->seq; 1164 int T; 1165 1166 trace_assign_type(field, iter->ent); 1167 1168 if (!S) 1169 S = task_state_char(field->prev_state); 1170 T = task_state_char(field->next_state); 1171 1172 SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid); 1173 SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio); 1174 SEQ_PUT_HEX_FIELD_RET(s, S); 1175 SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu); 1176 SEQ_PUT_HEX_FIELD_RET(s, field->next_pid); 1177 SEQ_PUT_HEX_FIELD_RET(s, field->next_prio); 1178 SEQ_PUT_HEX_FIELD_RET(s, T); 1179 1180 return TRACE_TYPE_HANDLED; 1181 } 1182 1183 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags, 1184 struct trace_event *event) 1185 { 1186 return trace_ctxwake_hex(iter, 0); 1187 } 1188 1189 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags, 1190 struct trace_event *event) 1191 { 1192 return trace_ctxwake_hex(iter, '+'); 1193 } 1194 1195 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, 1196 int flags, struct trace_event *event) 1197 { 1198 struct ctx_switch_entry *field; 1199 struct trace_seq *s = &iter->seq; 1200 1201 trace_assign_type(field, iter->ent); 1202 1203 SEQ_PUT_FIELD_RET(s, field->prev_pid); 1204 SEQ_PUT_FIELD_RET(s, field->prev_prio); 1205 SEQ_PUT_FIELD_RET(s, field->prev_state); 1206 SEQ_PUT_FIELD_RET(s, field->next_pid); 1207 SEQ_PUT_FIELD_RET(s, field->next_prio); 1208 SEQ_PUT_FIELD_RET(s, field->next_state); 1209 1210 return TRACE_TYPE_HANDLED; 1211 } 1212 1213 static struct trace_event_functions trace_ctx_funcs = { 1214 .trace = trace_ctx_print, 1215 .raw = trace_ctx_raw, 1216 .hex = trace_ctx_hex, 1217 .binary = trace_ctxwake_bin, 1218 }; 1219 1220 static struct trace_event trace_ctx_event = { 1221 .type = TRACE_CTX, 1222 .funcs = &trace_ctx_funcs, 1223 }; 1224 1225 static struct trace_event_functions trace_wake_funcs = { 1226 .trace = trace_wake_print, 1227 .raw = trace_wake_raw, 1228 .hex = trace_wake_hex, 1229 .binary = trace_ctxwake_bin, 1230 }; 1231 1232 static struct trace_event trace_wake_event = { 1233 .type = TRACE_WAKE, 1234 .funcs = &trace_wake_funcs, 1235 }; 1236 1237 /* TRACE_STACK */ 1238 1239 static enum print_line_t trace_stack_print(struct trace_iterator *iter, 1240 int flags, struct trace_event *event) 1241 { 1242 struct stack_entry *field; 1243 struct trace_seq *s = &iter->seq; 1244 unsigned long *p; 1245 unsigned long *end; 1246 1247 trace_assign_type(field, iter->ent); 1248 end = (unsigned long *)((long)iter->ent + iter->ent_size); 1249 1250 if (!trace_seq_puts(s, "<stack trace>\n")) 1251 goto partial; 1252 1253 for (p = field->caller; p && *p != ULONG_MAX && p < end; p++) { 1254 if (!trace_seq_puts(s, " => ")) 1255 goto partial; 1256 1257 if (!seq_print_ip_sym(s, *p, flags)) 1258 goto partial; 1259 if (!trace_seq_putc(s, '\n')) 1260 goto partial; 1261 } 1262 1263 return TRACE_TYPE_HANDLED; 1264 1265 partial: 1266 return TRACE_TYPE_PARTIAL_LINE; 1267 } 1268 1269 static struct trace_event_functions trace_stack_funcs = { 1270 .trace = trace_stack_print, 1271 }; 1272 1273 static struct trace_event trace_stack_event = { 1274 .type = TRACE_STACK, 1275 .funcs = &trace_stack_funcs, 1276 }; 1277 1278 /* TRACE_USER_STACK */ 1279 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, 1280 int flags, struct trace_event *event) 1281 { 1282 struct userstack_entry *field; 1283 struct trace_seq *s = &iter->seq; 1284 1285 trace_assign_type(field, iter->ent); 1286 1287 if (!trace_seq_puts(s, "<user stack trace>\n")) 1288 goto partial; 1289 1290 if (!seq_print_userip_objs(field, s, flags)) 1291 goto partial; 1292 1293 return TRACE_TYPE_HANDLED; 1294 1295 partial: 1296 return TRACE_TYPE_PARTIAL_LINE; 1297 } 1298 1299 static struct trace_event_functions trace_user_stack_funcs = { 1300 .trace = trace_user_stack_print, 1301 }; 1302 1303 static struct trace_event trace_user_stack_event = { 1304 .type = TRACE_USER_STACK, 1305 .funcs = &trace_user_stack_funcs, 1306 }; 1307 1308 /* TRACE_BPUTS */ 1309 static enum print_line_t 1310 trace_bputs_print(struct trace_iterator *iter, int flags, 1311 struct trace_event *event) 1312 { 1313 struct trace_entry *entry = iter->ent; 1314 struct trace_seq *s = &iter->seq; 1315 struct bputs_entry *field; 1316 1317 trace_assign_type(field, entry); 1318 1319 if (!seq_print_ip_sym(s, field->ip, flags)) 1320 goto partial; 1321 1322 if (!trace_seq_puts(s, ": ")) 1323 goto partial; 1324 1325 if (!trace_seq_puts(s, field->str)) 1326 goto partial; 1327 1328 return TRACE_TYPE_HANDLED; 1329 1330 partial: 1331 return TRACE_TYPE_PARTIAL_LINE; 1332 } 1333 1334 1335 static enum print_line_t 1336 trace_bputs_raw(struct trace_iterator *iter, int flags, 1337 struct trace_event *event) 1338 { 1339 struct bputs_entry *field; 1340 struct trace_seq *s = &iter->seq; 1341 1342 trace_assign_type(field, iter->ent); 1343 1344 if (!trace_seq_printf(s, ": %lx : ", field->ip)) 1345 goto partial; 1346 1347 if (!trace_seq_puts(s, field->str)) 1348 goto partial; 1349 1350 return TRACE_TYPE_HANDLED; 1351 1352 partial: 1353 return TRACE_TYPE_PARTIAL_LINE; 1354 } 1355 1356 static struct trace_event_functions trace_bputs_funcs = { 1357 .trace = trace_bputs_print, 1358 .raw = trace_bputs_raw, 1359 }; 1360 1361 static struct trace_event trace_bputs_event = { 1362 .type = TRACE_BPUTS, 1363 .funcs = &trace_bputs_funcs, 1364 }; 1365 1366 /* TRACE_BPRINT */ 1367 static enum print_line_t 1368 trace_bprint_print(struct trace_iterator *iter, int flags, 1369 struct trace_event *event) 1370 { 1371 struct trace_entry *entry = iter->ent; 1372 struct trace_seq *s = &iter->seq; 1373 struct bprint_entry *field; 1374 1375 trace_assign_type(field, entry); 1376 1377 if (!seq_print_ip_sym(s, field->ip, flags)) 1378 goto partial; 1379 1380 if (!trace_seq_puts(s, ": ")) 1381 goto partial; 1382 1383 if (!trace_seq_bprintf(s, field->fmt, field->buf)) 1384 goto partial; 1385 1386 return TRACE_TYPE_HANDLED; 1387 1388 partial: 1389 return TRACE_TYPE_PARTIAL_LINE; 1390 } 1391 1392 1393 static enum print_line_t 1394 trace_bprint_raw(struct trace_iterator *iter, int flags, 1395 struct trace_event *event) 1396 { 1397 struct bprint_entry *field; 1398 struct trace_seq *s = &iter->seq; 1399 1400 trace_assign_type(field, iter->ent); 1401 1402 if (!trace_seq_printf(s, ": %lx : ", field->ip)) 1403 goto partial; 1404 1405 if (!trace_seq_bprintf(s, field->fmt, field->buf)) 1406 goto partial; 1407 1408 return TRACE_TYPE_HANDLED; 1409 1410 partial: 1411 return TRACE_TYPE_PARTIAL_LINE; 1412 } 1413 1414 static struct trace_event_functions trace_bprint_funcs = { 1415 .trace = trace_bprint_print, 1416 .raw = trace_bprint_raw, 1417 }; 1418 1419 static struct trace_event trace_bprint_event = { 1420 .type = TRACE_BPRINT, 1421 .funcs = &trace_bprint_funcs, 1422 }; 1423 1424 /* TRACE_PRINT */ 1425 static enum print_line_t trace_print_print(struct trace_iterator *iter, 1426 int flags, struct trace_event *event) 1427 { 1428 struct print_entry *field; 1429 struct trace_seq *s = &iter->seq; 1430 1431 trace_assign_type(field, iter->ent); 1432 1433 if (!seq_print_ip_sym(s, field->ip, flags)) 1434 goto partial; 1435 1436 if (!trace_seq_printf(s, ": %s", field->buf)) 1437 goto partial; 1438 1439 return TRACE_TYPE_HANDLED; 1440 1441 partial: 1442 return TRACE_TYPE_PARTIAL_LINE; 1443 } 1444 1445 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, 1446 struct trace_event *event) 1447 { 1448 struct print_entry *field; 1449 1450 trace_assign_type(field, iter->ent); 1451 1452 if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf)) 1453 goto partial; 1454 1455 return TRACE_TYPE_HANDLED; 1456 1457 partial: 1458 return TRACE_TYPE_PARTIAL_LINE; 1459 } 1460 1461 static struct trace_event_functions trace_print_funcs = { 1462 .trace = trace_print_print, 1463 .raw = trace_print_raw, 1464 }; 1465 1466 static struct trace_event trace_print_event = { 1467 .type = TRACE_PRINT, 1468 .funcs = &trace_print_funcs, 1469 }; 1470 1471 1472 static struct trace_event *events[] __initdata = { 1473 &trace_fn_event, 1474 &trace_ctx_event, 1475 &trace_wake_event, 1476 &trace_stack_event, 1477 &trace_user_stack_event, 1478 &trace_bputs_event, 1479 &trace_bprint_event, 1480 &trace_print_event, 1481 NULL 1482 }; 1483 1484 __init static int init_events(void) 1485 { 1486 struct trace_event *event; 1487 int i, ret; 1488 1489 for (i = 0; events[i]; i++) { 1490 event = events[i]; 1491 1492 ret = register_ftrace_event(event); 1493 if (!ret) { 1494 printk(KERN_WARNING "event %d failed to register\n", 1495 event->type); 1496 WARN_ON_ONCE(1); 1497 } 1498 } 1499 1500 return 0; 1501 } 1502 early_initcall(init_events); 1503