1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * trace_output.c 4 * 5 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 6 * 7 */ 8 #include <linux/module.h> 9 #include <linux/mutex.h> 10 #include <linux/ftrace.h> 11 #include <linux/kprobes.h> 12 #include <linux/sched/clock.h> 13 #include <linux/sched/mm.h> 14 #include <linux/idr.h> 15 16 #include "trace_output.h" 17 18 /* must be a power of 2 */ 19 #define EVENT_HASHSIZE 128 20 21 DECLARE_RWSEM(trace_event_sem); 22 23 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; 24 25 enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter) 26 { 27 struct trace_seq *s = &iter->seq; 28 struct trace_entry *entry = iter->ent; 29 struct bputs_entry *field; 30 31 trace_assign_type(field, entry); 32 33 trace_seq_puts(s, field->str); 34 35 return trace_handle_return(s); 36 } 37 38 enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) 39 { 40 struct trace_seq *s = &iter->seq; 41 struct trace_entry *entry = iter->ent; 42 struct bprint_entry *field; 43 44 trace_assign_type(field, entry); 45 46 trace_seq_bprintf(s, field->fmt, field->buf); 47 48 return trace_handle_return(s); 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 57 trace_assign_type(field, entry); 58 59 trace_seq_puts(s, field->buf); 60 61 return trace_handle_return(s); 62 } 63 64 const char * 65 trace_print_flags_seq(struct trace_seq *p, const char *delim, 66 unsigned long flags, 67 const struct trace_print_flags *flag_array) 68 { 69 unsigned long mask; 70 const char *str; 71 const char *ret = trace_seq_buffer_ptr(p); 72 int i, first = 1; 73 74 for (i = 0; flag_array[i].name && flags; i++) { 75 76 mask = flag_array[i].mask; 77 if ((flags & mask) != mask) 78 continue; 79 80 str = flag_array[i].name; 81 flags &= ~mask; 82 if (!first && delim) 83 trace_seq_puts(p, delim); 84 else 85 first = 0; 86 trace_seq_puts(p, str); 87 } 88 89 /* check for left over flags */ 90 if (flags) { 91 if (!first && delim) 92 trace_seq_puts(p, delim); 93 trace_seq_printf(p, "0x%lx", flags); 94 } 95 96 trace_seq_putc(p, 0); 97 98 return ret; 99 } 100 EXPORT_SYMBOL(trace_print_flags_seq); 101 102 const char * 103 trace_print_symbols_seq(struct trace_seq *p, unsigned long val, 104 const struct trace_print_flags *symbol_array) 105 { 106 int i; 107 const char *ret = trace_seq_buffer_ptr(p); 108 109 for (i = 0; symbol_array[i].name; i++) { 110 111 if (val != symbol_array[i].mask) 112 continue; 113 114 trace_seq_puts(p, symbol_array[i].name); 115 break; 116 } 117 118 if (ret == (const char *)(trace_seq_buffer_ptr(p))) 119 trace_seq_printf(p, "0x%lx", val); 120 121 trace_seq_putc(p, 0); 122 123 return ret; 124 } 125 EXPORT_SYMBOL(trace_print_symbols_seq); 126 127 #if BITS_PER_LONG == 32 128 const char * 129 trace_print_flags_seq_u64(struct trace_seq *p, const char *delim, 130 unsigned long long flags, 131 const struct trace_print_flags_u64 *flag_array) 132 { 133 unsigned long long mask; 134 const char *str; 135 const char *ret = trace_seq_buffer_ptr(p); 136 int i, first = 1; 137 138 for (i = 0; flag_array[i].name && flags; i++) { 139 140 mask = flag_array[i].mask; 141 if ((flags & mask) != mask) 142 continue; 143 144 str = flag_array[i].name; 145 flags &= ~mask; 146 if (!first && delim) 147 trace_seq_puts(p, delim); 148 else 149 first = 0; 150 trace_seq_puts(p, str); 151 } 152 153 /* check for left over flags */ 154 if (flags) { 155 if (!first && delim) 156 trace_seq_puts(p, delim); 157 trace_seq_printf(p, "0x%llx", flags); 158 } 159 160 trace_seq_putc(p, 0); 161 162 return ret; 163 } 164 EXPORT_SYMBOL(trace_print_flags_seq_u64); 165 166 const char * 167 trace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, 168 const struct trace_print_flags_u64 *symbol_array) 169 { 170 int i; 171 const char *ret = trace_seq_buffer_ptr(p); 172 173 for (i = 0; symbol_array[i].name; i++) { 174 175 if (val != symbol_array[i].mask) 176 continue; 177 178 trace_seq_puts(p, symbol_array[i].name); 179 break; 180 } 181 182 if (ret == (const char *)(trace_seq_buffer_ptr(p))) 183 trace_seq_printf(p, "0x%llx", val); 184 185 trace_seq_putc(p, 0); 186 187 return ret; 188 } 189 EXPORT_SYMBOL(trace_print_symbols_seq_u64); 190 #endif 191 192 const char * 193 trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, 194 unsigned int bitmask_size) 195 { 196 const char *ret = trace_seq_buffer_ptr(p); 197 198 trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8); 199 trace_seq_putc(p, 0); 200 201 return ret; 202 } 203 EXPORT_SYMBOL_GPL(trace_print_bitmask_seq); 204 205 /** 206 * trace_print_hex_seq - print buffer as hex sequence 207 * @p: trace seq struct to write to 208 * @buf: The buffer to print 209 * @buf_len: Length of @buf in bytes 210 * @concatenate: Print @buf as single hex string or with spacing 211 * 212 * Prints the passed buffer as a hex sequence either as a whole, 213 * single hex string if @concatenate is true or with spacing after 214 * each byte in case @concatenate is false. 215 */ 216 const char * 217 trace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len, 218 bool concatenate) 219 { 220 int i; 221 const char *ret = trace_seq_buffer_ptr(p); 222 const char *fmt = concatenate ? "%*phN" : "%*ph"; 223 224 for (i = 0; i < buf_len; i += 16) { 225 if (!concatenate && i != 0) 226 trace_seq_putc(p, ' '); 227 trace_seq_printf(p, fmt, min(buf_len - i, 16), &buf[i]); 228 } 229 trace_seq_putc(p, 0); 230 231 return ret; 232 } 233 EXPORT_SYMBOL(trace_print_hex_seq); 234 235 const char * 236 trace_print_array_seq(struct trace_seq *p, const void *buf, int count, 237 size_t el_size) 238 { 239 const char *ret = trace_seq_buffer_ptr(p); 240 const char *prefix = ""; 241 void *ptr = (void *)buf; 242 size_t buf_len = count * el_size; 243 244 trace_seq_putc(p, '{'); 245 246 while (ptr < buf + buf_len) { 247 switch (el_size) { 248 case 1: 249 trace_seq_printf(p, "%s0x%x", prefix, 250 *(u8 *)ptr); 251 break; 252 case 2: 253 trace_seq_printf(p, "%s0x%x", prefix, 254 *(u16 *)ptr); 255 break; 256 case 4: 257 trace_seq_printf(p, "%s0x%x", prefix, 258 *(u32 *)ptr); 259 break; 260 case 8: 261 trace_seq_printf(p, "%s0x%llx", prefix, 262 *(u64 *)ptr); 263 break; 264 default: 265 trace_seq_printf(p, "BAD SIZE:%zu 0x%x", el_size, 266 *(u8 *)ptr); 267 el_size = 1; 268 } 269 prefix = ","; 270 ptr += el_size; 271 } 272 273 trace_seq_putc(p, '}'); 274 trace_seq_putc(p, 0); 275 276 return ret; 277 } 278 EXPORT_SYMBOL(trace_print_array_seq); 279 280 const char * 281 trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, 282 int prefix_type, int rowsize, int groupsize, 283 const void *buf, size_t len, bool ascii) 284 { 285 const char *ret = trace_seq_buffer_ptr(p); 286 287 trace_seq_putc(p, '\n'); 288 trace_seq_hex_dump(p, prefix_str, prefix_type, 289 rowsize, groupsize, buf, len, ascii); 290 trace_seq_putc(p, 0); 291 return ret; 292 } 293 EXPORT_SYMBOL(trace_print_hex_dump_seq); 294 295 int trace_raw_output_prep(struct trace_iterator *iter, 296 struct trace_event *trace_event) 297 { 298 struct trace_event_call *event; 299 struct trace_seq *s = &iter->seq; 300 struct trace_seq *p = &iter->tmp_seq; 301 struct trace_entry *entry; 302 303 event = container_of(trace_event, struct trace_event_call, event); 304 entry = iter->ent; 305 306 if (entry->type != event->event.type) { 307 WARN_ON_ONCE(1); 308 return TRACE_TYPE_UNHANDLED; 309 } 310 311 trace_seq_init(p); 312 trace_seq_printf(s, "%s: ", trace_event_name(event)); 313 314 return trace_handle_return(s); 315 } 316 EXPORT_SYMBOL(trace_raw_output_prep); 317 318 void trace_event_printf(struct trace_iterator *iter, const char *fmt, ...) 319 { 320 struct trace_seq *s = &iter->seq; 321 va_list ap; 322 323 if (ignore_event(iter)) 324 return; 325 326 va_start(ap, fmt); 327 trace_seq_vprintf(s, trace_event_format(iter, fmt), ap); 328 va_end(ap); 329 } 330 EXPORT_SYMBOL(trace_event_printf); 331 332 static __printf(3, 0) 333 int trace_output_raw(struct trace_iterator *iter, char *name, 334 char *fmt, va_list ap) 335 { 336 struct trace_seq *s = &iter->seq; 337 338 trace_seq_printf(s, "%s: ", name); 339 trace_seq_vprintf(s, trace_event_format(iter, fmt), ap); 340 341 return trace_handle_return(s); 342 } 343 344 int trace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...) 345 { 346 va_list ap; 347 int ret; 348 349 va_start(ap, fmt); 350 ret = trace_output_raw(iter, name, fmt, ap); 351 va_end(ap); 352 353 return ret; 354 } 355 EXPORT_SYMBOL_GPL(trace_output_call); 356 357 static inline const char *kretprobed(const char *name, unsigned long addr) 358 { 359 if (is_kretprobe_trampoline(addr)) 360 return "[unknown/kretprobe'd]"; 361 return name; 362 } 363 364 void 365 trace_seq_print_sym(struct trace_seq *s, unsigned long address, bool offset) 366 { 367 #ifdef CONFIG_KALLSYMS 368 char str[KSYM_SYMBOL_LEN]; 369 const char *name; 370 371 if (offset) 372 sprint_symbol(str, address); 373 else 374 kallsyms_lookup(address, NULL, NULL, NULL, str); 375 name = kretprobed(str, address); 376 377 if (name && strlen(name)) { 378 trace_seq_puts(s, name); 379 return; 380 } 381 #endif 382 trace_seq_printf(s, "0x%08lx", address); 383 } 384 385 #ifndef CONFIG_64BIT 386 # define IP_FMT "%08lx" 387 #else 388 # define IP_FMT "%016lx" 389 #endif 390 391 static int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm, 392 unsigned long ip, unsigned long sym_flags) 393 { 394 struct file *file = NULL; 395 unsigned long vmstart = 0; 396 int ret = 1; 397 398 if (s->full) 399 return 0; 400 401 if (mm) { 402 const struct vm_area_struct *vma; 403 404 mmap_read_lock(mm); 405 vma = find_vma(mm, ip); 406 if (vma) { 407 file = vma->vm_file; 408 vmstart = vma->vm_start; 409 } 410 if (file) { 411 ret = trace_seq_path(s, &file->f_path); 412 if (ret) 413 trace_seq_printf(s, "[+0x%lx]", 414 ip - vmstart); 415 } 416 mmap_read_unlock(mm); 417 } 418 if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file)) 419 trace_seq_printf(s, " <" IP_FMT ">", ip); 420 return !trace_seq_has_overflowed(s); 421 } 422 423 int 424 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) 425 { 426 if (!ip) { 427 trace_seq_putc(s, '0'); 428 goto out; 429 } 430 431 trace_seq_print_sym(s, ip, sym_flags & TRACE_ITER_SYM_OFFSET); 432 433 if (sym_flags & TRACE_ITER_SYM_ADDR) 434 trace_seq_printf(s, " <" IP_FMT ">", ip); 435 436 out: 437 return !trace_seq_has_overflowed(s); 438 } 439 440 /** 441 * trace_print_lat_fmt - print the irq, preempt and lockdep fields 442 * @s: trace seq struct to write to 443 * @entry: The trace entry field from the ring buffer 444 * 445 * Prints the generic fields of irqs off, in hard or softirq, preempt 446 * count. 447 */ 448 int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) 449 { 450 char hardsoft_irq; 451 char need_resched; 452 char irqs_off; 453 int hardirq; 454 int softirq; 455 int bh_off; 456 int nmi; 457 458 nmi = entry->flags & TRACE_FLAG_NMI; 459 hardirq = entry->flags & TRACE_FLAG_HARDIRQ; 460 softirq = entry->flags & TRACE_FLAG_SOFTIRQ; 461 bh_off = entry->flags & TRACE_FLAG_BH_OFF; 462 463 irqs_off = 464 (entry->flags & TRACE_FLAG_IRQS_OFF && bh_off) ? 'D' : 465 (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : 466 bh_off ? 'b' : 467 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : 468 '.'; 469 470 switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | 471 TRACE_FLAG_PREEMPT_RESCHED)) { 472 case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED: 473 need_resched = 'N'; 474 break; 475 case TRACE_FLAG_NEED_RESCHED: 476 need_resched = 'n'; 477 break; 478 case TRACE_FLAG_PREEMPT_RESCHED: 479 need_resched = 'p'; 480 break; 481 default: 482 need_resched = '.'; 483 break; 484 } 485 486 hardsoft_irq = 487 (nmi && hardirq) ? 'Z' : 488 nmi ? 'z' : 489 (hardirq && softirq) ? 'H' : 490 hardirq ? 'h' : 491 softirq ? 's' : 492 '.' ; 493 494 trace_seq_printf(s, "%c%c%c", 495 irqs_off, need_resched, hardsoft_irq); 496 497 if (entry->preempt_count & 0xf) 498 trace_seq_printf(s, "%x", entry->preempt_count & 0xf); 499 else 500 trace_seq_putc(s, '.'); 501 502 if (entry->preempt_count & 0xf0) 503 trace_seq_printf(s, "%x", entry->preempt_count >> 4); 504 else 505 trace_seq_putc(s, '.'); 506 507 return !trace_seq_has_overflowed(s); 508 } 509 510 static int 511 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) 512 { 513 char comm[TASK_COMM_LEN]; 514 515 trace_find_cmdline(entry->pid, comm); 516 517 trace_seq_printf(s, "%8.8s-%-7d %3d", 518 comm, entry->pid, cpu); 519 520 return trace_print_lat_fmt(s, entry); 521 } 522 523 #undef MARK 524 #define MARK(v, s) {.val = v, .sym = s} 525 /* trace overhead mark */ 526 static const struct trace_mark { 527 unsigned long long val; /* unit: nsec */ 528 char sym; 529 } mark[] = { 530 MARK(1000000000ULL , '$'), /* 1 sec */ 531 MARK(100000000ULL , '@'), /* 100 msec */ 532 MARK(10000000ULL , '*'), /* 10 msec */ 533 MARK(1000000ULL , '#'), /* 1000 usecs */ 534 MARK(100000ULL , '!'), /* 100 usecs */ 535 MARK(10000ULL , '+'), /* 10 usecs */ 536 }; 537 #undef MARK 538 539 char trace_find_mark(unsigned long long d) 540 { 541 int i; 542 int size = ARRAY_SIZE(mark); 543 544 for (i = 0; i < size; i++) { 545 if (d > mark[i].val) 546 break; 547 } 548 549 return (i == size) ? ' ' : mark[i].sym; 550 } 551 552 static int 553 lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) 554 { 555 struct trace_array *tr = iter->tr; 556 unsigned long verbose = tr->trace_flags & TRACE_ITER_VERBOSE; 557 unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; 558 unsigned long long abs_ts = iter->ts - iter->array_buffer->time_start; 559 unsigned long long rel_ts = next_ts - iter->ts; 560 struct trace_seq *s = &iter->seq; 561 562 if (in_ns) { 563 abs_ts = ns2usecs(abs_ts); 564 rel_ts = ns2usecs(rel_ts); 565 } 566 567 if (verbose && in_ns) { 568 unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC); 569 unsigned long abs_msec = (unsigned long)abs_ts; 570 unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC); 571 unsigned long rel_msec = (unsigned long)rel_ts; 572 573 trace_seq_printf( 574 s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ", 575 ns2usecs(iter->ts), 576 abs_msec, abs_usec, 577 rel_msec, rel_usec); 578 579 } else if (verbose && !in_ns) { 580 trace_seq_printf( 581 s, "[%016llx] %lld (+%lld): ", 582 iter->ts, abs_ts, rel_ts); 583 584 } else if (!verbose && in_ns) { 585 trace_seq_printf( 586 s, " %4lldus%c: ", 587 abs_ts, 588 trace_find_mark(rel_ts * NSEC_PER_USEC)); 589 590 } else { /* !verbose && !in_ns */ 591 trace_seq_printf(s, " %4lld: ", abs_ts); 592 } 593 594 return !trace_seq_has_overflowed(s); 595 } 596 597 static void trace_print_time(struct trace_seq *s, struct trace_iterator *iter, 598 unsigned long long ts) 599 { 600 unsigned long secs, usec_rem; 601 unsigned long long t; 602 603 if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { 604 t = ns2usecs(ts); 605 usec_rem = do_div(t, USEC_PER_SEC); 606 secs = (unsigned long)t; 607 trace_seq_printf(s, " %5lu.%06lu", secs, usec_rem); 608 } else 609 trace_seq_printf(s, " %12llu", ts); 610 } 611 612 int trace_print_context(struct trace_iterator *iter) 613 { 614 struct trace_array *tr = iter->tr; 615 struct trace_seq *s = &iter->seq; 616 struct trace_entry *entry = iter->ent; 617 char comm[TASK_COMM_LEN]; 618 619 trace_find_cmdline(entry->pid, comm); 620 621 trace_seq_printf(s, "%16s-%-7d ", comm, entry->pid); 622 623 if (tr->trace_flags & TRACE_ITER_RECORD_TGID) { 624 unsigned int tgid = trace_find_tgid(entry->pid); 625 626 if (!tgid) 627 trace_seq_printf(s, "(-------) "); 628 else 629 trace_seq_printf(s, "(%7d) ", tgid); 630 } 631 632 trace_seq_printf(s, "[%03d] ", iter->cpu); 633 634 if (tr->trace_flags & TRACE_ITER_IRQ_INFO) 635 trace_print_lat_fmt(s, entry); 636 637 trace_print_time(s, iter, iter->ts); 638 trace_seq_puts(s, ": "); 639 640 return !trace_seq_has_overflowed(s); 641 } 642 643 int trace_print_lat_context(struct trace_iterator *iter) 644 { 645 struct trace_entry *entry, *next_entry; 646 struct trace_array *tr = iter->tr; 647 struct trace_seq *s = &iter->seq; 648 unsigned long verbose = (tr->trace_flags & TRACE_ITER_VERBOSE); 649 u64 next_ts; 650 651 next_entry = trace_find_next_entry(iter, NULL, &next_ts); 652 if (!next_entry) 653 next_ts = iter->ts; 654 655 /* trace_find_next_entry() may change iter->ent */ 656 entry = iter->ent; 657 658 if (verbose) { 659 char comm[TASK_COMM_LEN]; 660 661 trace_find_cmdline(entry->pid, comm); 662 663 trace_seq_printf( 664 s, "%16s %7d %3d %d %08x %08lx ", 665 comm, entry->pid, iter->cpu, entry->flags, 666 entry->preempt_count & 0xf, iter->idx); 667 } else { 668 lat_print_generic(s, entry, iter->cpu); 669 } 670 671 lat_print_timestamp(iter, next_ts); 672 673 return !trace_seq_has_overflowed(s); 674 } 675 676 /** 677 * ftrace_find_event - find a registered event 678 * @type: the type of event to look for 679 * 680 * Returns an event of type @type otherwise NULL 681 * Called with trace_event_read_lock() held. 682 */ 683 struct trace_event *ftrace_find_event(int type) 684 { 685 struct trace_event *event; 686 unsigned key; 687 688 key = type & (EVENT_HASHSIZE - 1); 689 690 hlist_for_each_entry(event, &event_hash[key], node) { 691 if (event->type == type) 692 return event; 693 } 694 695 return NULL; 696 } 697 698 static DEFINE_IDA(trace_event_ida); 699 700 static void free_trace_event_type(int type) 701 { 702 if (type >= __TRACE_LAST_TYPE) 703 ida_free(&trace_event_ida, type); 704 } 705 706 static int alloc_trace_event_type(void) 707 { 708 int next; 709 710 /* Skip static defined type numbers */ 711 next = ida_alloc_range(&trace_event_ida, __TRACE_LAST_TYPE, 712 TRACE_EVENT_TYPE_MAX, GFP_KERNEL); 713 if (next < 0) 714 return 0; 715 return next; 716 } 717 718 void trace_event_read_lock(void) 719 { 720 down_read(&trace_event_sem); 721 } 722 723 void trace_event_read_unlock(void) 724 { 725 up_read(&trace_event_sem); 726 } 727 728 /** 729 * register_trace_event - register output for an event type 730 * @event: the event type to register 731 * 732 * Event types are stored in a hash and this hash is used to 733 * find a way to print an event. If the @event->type is set 734 * then it will use that type, otherwise it will assign a 735 * type to use. 736 * 737 * If you assign your own type, please make sure it is added 738 * to the trace_type enum in trace.h, to avoid collisions 739 * with the dynamic types. 740 * 741 * Returns the event type number or zero on error. 742 */ 743 int register_trace_event(struct trace_event *event) 744 { 745 unsigned key; 746 int ret = 0; 747 748 down_write(&trace_event_sem); 749 750 if (WARN_ON(!event)) 751 goto out; 752 753 if (WARN_ON(!event->funcs)) 754 goto out; 755 756 if (!event->type) { 757 event->type = alloc_trace_event_type(); 758 if (!event->type) 759 goto out; 760 } else if (WARN(event->type > __TRACE_LAST_TYPE, 761 "Need to add type to trace.h")) { 762 goto out; 763 } else { 764 /* Is this event already used */ 765 if (ftrace_find_event(event->type)) 766 goto out; 767 } 768 769 if (event->funcs->trace == NULL) 770 event->funcs->trace = trace_nop_print; 771 if (event->funcs->raw == NULL) 772 event->funcs->raw = trace_nop_print; 773 if (event->funcs->hex == NULL) 774 event->funcs->hex = trace_nop_print; 775 if (event->funcs->binary == NULL) 776 event->funcs->binary = trace_nop_print; 777 778 key = event->type & (EVENT_HASHSIZE - 1); 779 780 hlist_add_head(&event->node, &event_hash[key]); 781 782 ret = event->type; 783 out: 784 up_write(&trace_event_sem); 785 786 return ret; 787 } 788 EXPORT_SYMBOL_GPL(register_trace_event); 789 790 /* 791 * Used by module code with the trace_event_sem held for write. 792 */ 793 int __unregister_trace_event(struct trace_event *event) 794 { 795 hlist_del(&event->node); 796 free_trace_event_type(event->type); 797 return 0; 798 } 799 800 /** 801 * unregister_trace_event - remove a no longer used event 802 * @event: the event to remove 803 */ 804 int unregister_trace_event(struct trace_event *event) 805 { 806 down_write(&trace_event_sem); 807 __unregister_trace_event(event); 808 up_write(&trace_event_sem); 809 810 return 0; 811 } 812 EXPORT_SYMBOL_GPL(unregister_trace_event); 813 814 /* 815 * Standard events 816 */ 817 818 static void print_array(struct trace_iterator *iter, void *pos, 819 struct ftrace_event_field *field) 820 { 821 int offset; 822 int len; 823 int i; 824 825 offset = *(int *)pos & 0xffff; 826 len = *(int *)pos >> 16; 827 828 if (field) 829 offset += field->offset + sizeof(int); 830 831 if (offset + len > iter->ent_size) { 832 trace_seq_puts(&iter->seq, "<OVERFLOW>"); 833 return; 834 } 835 836 pos = (void *)iter->ent + offset; 837 838 for (i = 0; i < len; i++, pos++) { 839 if (i) 840 trace_seq_putc(&iter->seq, ','); 841 trace_seq_printf(&iter->seq, "%02x", *(unsigned char *)pos); 842 } 843 } 844 845 static void print_fields(struct trace_iterator *iter, struct trace_event_call *call, 846 struct list_head *head) 847 { 848 struct ftrace_event_field *field; 849 int offset; 850 int len; 851 int ret; 852 void *pos; 853 854 list_for_each_entry_reverse(field, head, link) { 855 trace_seq_printf(&iter->seq, " %s=", field->name); 856 if (field->offset + field->size > iter->ent_size) { 857 trace_seq_puts(&iter->seq, "<OVERFLOW>"); 858 continue; 859 } 860 pos = (void *)iter->ent + field->offset; 861 862 switch (field->filter_type) { 863 case FILTER_COMM: 864 case FILTER_STATIC_STRING: 865 trace_seq_printf(&iter->seq, "%.*s", field->size, (char *)pos); 866 break; 867 case FILTER_RDYN_STRING: 868 case FILTER_DYN_STRING: 869 offset = *(int *)pos & 0xffff; 870 len = *(int *)pos >> 16; 871 872 if (field->filter_type == FILTER_RDYN_STRING) 873 offset += field->offset + sizeof(int); 874 875 if (offset + len > iter->ent_size) { 876 trace_seq_puts(&iter->seq, "<OVERFLOW>"); 877 break; 878 } 879 pos = (void *)iter->ent + offset; 880 trace_seq_printf(&iter->seq, "%.*s", len, (char *)pos); 881 break; 882 case FILTER_PTR_STRING: 883 if (!iter->fmt_size) 884 trace_iter_expand_format(iter); 885 pos = *(void **)pos; 886 ret = strncpy_from_kernel_nofault(iter->fmt, pos, 887 iter->fmt_size); 888 if (ret < 0) 889 trace_seq_printf(&iter->seq, "(0x%px)", pos); 890 else 891 trace_seq_printf(&iter->seq, "(0x%px:%s)", 892 pos, iter->fmt); 893 break; 894 case FILTER_TRACE_FN: 895 pos = *(void **)pos; 896 trace_seq_printf(&iter->seq, "%pS", pos); 897 break; 898 case FILTER_CPU: 899 case FILTER_OTHER: 900 switch (field->size) { 901 case 1: 902 if (isprint(*(char *)pos)) { 903 trace_seq_printf(&iter->seq, "'%c'", 904 *(unsigned char *)pos); 905 } 906 trace_seq_printf(&iter->seq, "(%d)", 907 *(unsigned char *)pos); 908 break; 909 case 2: 910 trace_seq_printf(&iter->seq, "0x%x (%d)", 911 *(unsigned short *)pos, 912 *(unsigned short *)pos); 913 break; 914 case 4: 915 /* dynamic array info is 4 bytes */ 916 if (strstr(field->type, "__data_loc")) { 917 print_array(iter, pos, NULL); 918 break; 919 } 920 921 if (strstr(field->type, "__rel_loc")) { 922 print_array(iter, pos, field); 923 break; 924 } 925 926 trace_seq_printf(&iter->seq, "0x%x (%d)", 927 *(unsigned int *)pos, 928 *(unsigned int *)pos); 929 break; 930 case 8: 931 trace_seq_printf(&iter->seq, "0x%llx (%lld)", 932 *(unsigned long long *)pos, 933 *(unsigned long long *)pos); 934 break; 935 default: 936 trace_seq_puts(&iter->seq, "<INVALID-SIZE>"); 937 break; 938 } 939 break; 940 default: 941 trace_seq_puts(&iter->seq, "<INVALID-TYPE>"); 942 } 943 } 944 trace_seq_putc(&iter->seq, '\n'); 945 } 946 947 enum print_line_t print_event_fields(struct trace_iterator *iter, 948 struct trace_event *event) 949 { 950 struct trace_event_call *call; 951 struct list_head *head; 952 953 /* ftrace defined events have separate call structures */ 954 if (event->type <= __TRACE_LAST_TYPE) { 955 bool found = false; 956 957 down_read(&trace_event_sem); 958 list_for_each_entry(call, &ftrace_events, list) { 959 if (call->event.type == event->type) { 960 found = true; 961 break; 962 } 963 /* No need to search all events */ 964 if (call->event.type > __TRACE_LAST_TYPE) 965 break; 966 } 967 up_read(&trace_event_sem); 968 if (!found) { 969 trace_seq_printf(&iter->seq, "UNKNOWN TYPE %d\n", event->type); 970 goto out; 971 } 972 } else { 973 call = container_of(event, struct trace_event_call, event); 974 } 975 head = trace_get_fields(call); 976 977 trace_seq_printf(&iter->seq, "%s:", trace_event_name(call)); 978 979 if (head && !list_empty(head)) 980 print_fields(iter, call, head); 981 else 982 trace_seq_puts(&iter->seq, "No fields found\n"); 983 984 out: 985 return trace_handle_return(&iter->seq); 986 } 987 988 enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags, 989 struct trace_event *event) 990 { 991 trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type); 992 993 return trace_handle_return(&iter->seq); 994 } 995 996 static void print_fn_trace(struct trace_seq *s, unsigned long ip, 997 unsigned long parent_ip, int flags) 998 { 999 seq_print_ip_sym(s, ip, flags); 1000 1001 if ((flags & TRACE_ITER_PRINT_PARENT) && parent_ip) { 1002 trace_seq_puts(s, " <-"); 1003 seq_print_ip_sym(s, parent_ip, flags); 1004 } 1005 } 1006 1007 /* TRACE_FN */ 1008 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags, 1009 struct trace_event *event) 1010 { 1011 struct ftrace_entry *field; 1012 struct trace_seq *s = &iter->seq; 1013 1014 trace_assign_type(field, iter->ent); 1015 1016 print_fn_trace(s, field->ip, field->parent_ip, flags); 1017 trace_seq_putc(s, '\n'); 1018 1019 return trace_handle_return(s); 1020 } 1021 1022 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags, 1023 struct trace_event *event) 1024 { 1025 struct ftrace_entry *field; 1026 1027 trace_assign_type(field, iter->ent); 1028 1029 trace_seq_printf(&iter->seq, "%lx %lx\n", 1030 field->ip, 1031 field->parent_ip); 1032 1033 return trace_handle_return(&iter->seq); 1034 } 1035 1036 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags, 1037 struct trace_event *event) 1038 { 1039 struct ftrace_entry *field; 1040 struct trace_seq *s = &iter->seq; 1041 1042 trace_assign_type(field, iter->ent); 1043 1044 SEQ_PUT_HEX_FIELD(s, field->ip); 1045 SEQ_PUT_HEX_FIELD(s, field->parent_ip); 1046 1047 return trace_handle_return(s); 1048 } 1049 1050 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags, 1051 struct trace_event *event) 1052 { 1053 struct ftrace_entry *field; 1054 struct trace_seq *s = &iter->seq; 1055 1056 trace_assign_type(field, iter->ent); 1057 1058 SEQ_PUT_FIELD(s, field->ip); 1059 SEQ_PUT_FIELD(s, field->parent_ip); 1060 1061 return trace_handle_return(s); 1062 } 1063 1064 static struct trace_event_functions trace_fn_funcs = { 1065 .trace = trace_fn_trace, 1066 .raw = trace_fn_raw, 1067 .hex = trace_fn_hex, 1068 .binary = trace_fn_bin, 1069 }; 1070 1071 static struct trace_event trace_fn_event = { 1072 .type = TRACE_FN, 1073 .funcs = &trace_fn_funcs, 1074 }; 1075 1076 /* TRACE_CTX an TRACE_WAKE */ 1077 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, 1078 char *delim) 1079 { 1080 struct ctx_switch_entry *field; 1081 char comm[TASK_COMM_LEN]; 1082 int S, T; 1083 1084 1085 trace_assign_type(field, iter->ent); 1086 1087 T = task_index_to_char(field->next_state); 1088 S = task_index_to_char(field->prev_state); 1089 trace_find_cmdline(field->next_pid, comm); 1090 trace_seq_printf(&iter->seq, 1091 " %7d:%3d:%c %s [%03d] %7d:%3d:%c %s\n", 1092 field->prev_pid, 1093 field->prev_prio, 1094 S, delim, 1095 field->next_cpu, 1096 field->next_pid, 1097 field->next_prio, 1098 T, comm); 1099 1100 return trace_handle_return(&iter->seq); 1101 } 1102 1103 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags, 1104 struct trace_event *event) 1105 { 1106 return trace_ctxwake_print(iter, "==>"); 1107 } 1108 1109 static enum print_line_t trace_wake_print(struct trace_iterator *iter, 1110 int flags, struct trace_event *event) 1111 { 1112 return trace_ctxwake_print(iter, " +"); 1113 } 1114 1115 static int trace_ctxwake_raw(struct trace_iterator *iter, char S) 1116 { 1117 struct ctx_switch_entry *field; 1118 int T; 1119 1120 trace_assign_type(field, iter->ent); 1121 1122 if (!S) 1123 S = task_index_to_char(field->prev_state); 1124 T = task_index_to_char(field->next_state); 1125 trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", 1126 field->prev_pid, 1127 field->prev_prio, 1128 S, 1129 field->next_cpu, 1130 field->next_pid, 1131 field->next_prio, 1132 T); 1133 1134 return trace_handle_return(&iter->seq); 1135 } 1136 1137 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags, 1138 struct trace_event *event) 1139 { 1140 return trace_ctxwake_raw(iter, 0); 1141 } 1142 1143 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags, 1144 struct trace_event *event) 1145 { 1146 return trace_ctxwake_raw(iter, '+'); 1147 } 1148 1149 1150 static int trace_ctxwake_hex(struct trace_iterator *iter, char S) 1151 { 1152 struct ctx_switch_entry *field; 1153 struct trace_seq *s = &iter->seq; 1154 int T; 1155 1156 trace_assign_type(field, iter->ent); 1157 1158 if (!S) 1159 S = task_index_to_char(field->prev_state); 1160 T = task_index_to_char(field->next_state); 1161 1162 SEQ_PUT_HEX_FIELD(s, field->prev_pid); 1163 SEQ_PUT_HEX_FIELD(s, field->prev_prio); 1164 SEQ_PUT_HEX_FIELD(s, S); 1165 SEQ_PUT_HEX_FIELD(s, field->next_cpu); 1166 SEQ_PUT_HEX_FIELD(s, field->next_pid); 1167 SEQ_PUT_HEX_FIELD(s, field->next_prio); 1168 SEQ_PUT_HEX_FIELD(s, T); 1169 1170 return trace_handle_return(s); 1171 } 1172 1173 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags, 1174 struct trace_event *event) 1175 { 1176 return trace_ctxwake_hex(iter, 0); 1177 } 1178 1179 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags, 1180 struct trace_event *event) 1181 { 1182 return trace_ctxwake_hex(iter, '+'); 1183 } 1184 1185 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, 1186 int flags, struct trace_event *event) 1187 { 1188 struct ctx_switch_entry *field; 1189 struct trace_seq *s = &iter->seq; 1190 1191 trace_assign_type(field, iter->ent); 1192 1193 SEQ_PUT_FIELD(s, field->prev_pid); 1194 SEQ_PUT_FIELD(s, field->prev_prio); 1195 SEQ_PUT_FIELD(s, field->prev_state); 1196 SEQ_PUT_FIELD(s, field->next_cpu); 1197 SEQ_PUT_FIELD(s, field->next_pid); 1198 SEQ_PUT_FIELD(s, field->next_prio); 1199 SEQ_PUT_FIELD(s, field->next_state); 1200 1201 return trace_handle_return(s); 1202 } 1203 1204 static struct trace_event_functions trace_ctx_funcs = { 1205 .trace = trace_ctx_print, 1206 .raw = trace_ctx_raw, 1207 .hex = trace_ctx_hex, 1208 .binary = trace_ctxwake_bin, 1209 }; 1210 1211 static struct trace_event trace_ctx_event = { 1212 .type = TRACE_CTX, 1213 .funcs = &trace_ctx_funcs, 1214 }; 1215 1216 static struct trace_event_functions trace_wake_funcs = { 1217 .trace = trace_wake_print, 1218 .raw = trace_wake_raw, 1219 .hex = trace_wake_hex, 1220 .binary = trace_ctxwake_bin, 1221 }; 1222 1223 static struct trace_event trace_wake_event = { 1224 .type = TRACE_WAKE, 1225 .funcs = &trace_wake_funcs, 1226 }; 1227 1228 /* TRACE_STACK */ 1229 1230 static enum print_line_t trace_stack_print(struct trace_iterator *iter, 1231 int flags, struct trace_event *event) 1232 { 1233 struct stack_entry *field; 1234 struct trace_seq *s = &iter->seq; 1235 unsigned long *p; 1236 unsigned long *end; 1237 1238 trace_assign_type(field, iter->ent); 1239 end = (unsigned long *)((long)iter->ent + iter->ent_size); 1240 1241 trace_seq_puts(s, "<stack trace>\n"); 1242 1243 for (p = field->caller; p && p < end && *p != ULONG_MAX; p++) { 1244 1245 if (trace_seq_has_overflowed(s)) 1246 break; 1247 1248 trace_seq_puts(s, " => "); 1249 seq_print_ip_sym(s, *p, flags); 1250 trace_seq_putc(s, '\n'); 1251 } 1252 1253 return trace_handle_return(s); 1254 } 1255 1256 static struct trace_event_functions trace_stack_funcs = { 1257 .trace = trace_stack_print, 1258 }; 1259 1260 static struct trace_event trace_stack_event = { 1261 .type = TRACE_STACK, 1262 .funcs = &trace_stack_funcs, 1263 }; 1264 1265 /* TRACE_USER_STACK */ 1266 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, 1267 int flags, struct trace_event *event) 1268 { 1269 struct trace_array *tr = iter->tr; 1270 struct userstack_entry *field; 1271 struct trace_seq *s = &iter->seq; 1272 struct mm_struct *mm = NULL; 1273 unsigned int i; 1274 1275 trace_assign_type(field, iter->ent); 1276 1277 trace_seq_puts(s, "<user stack trace>\n"); 1278 1279 if (tr->trace_flags & TRACE_ITER_SYM_USEROBJ) { 1280 struct task_struct *task; 1281 /* 1282 * we do the lookup on the thread group leader, 1283 * since individual threads might have already quit! 1284 */ 1285 rcu_read_lock(); 1286 task = find_task_by_vpid(field->tgid); 1287 if (task) 1288 mm = get_task_mm(task); 1289 rcu_read_unlock(); 1290 } 1291 1292 for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { 1293 unsigned long ip = field->caller[i]; 1294 1295 if (!ip || trace_seq_has_overflowed(s)) 1296 break; 1297 1298 trace_seq_puts(s, " => "); 1299 seq_print_user_ip(s, mm, ip, flags); 1300 trace_seq_putc(s, '\n'); 1301 } 1302 1303 if (mm) 1304 mmput(mm); 1305 1306 return trace_handle_return(s); 1307 } 1308 1309 static struct trace_event_functions trace_user_stack_funcs = { 1310 .trace = trace_user_stack_print, 1311 }; 1312 1313 static struct trace_event trace_user_stack_event = { 1314 .type = TRACE_USER_STACK, 1315 .funcs = &trace_user_stack_funcs, 1316 }; 1317 1318 /* TRACE_HWLAT */ 1319 static enum print_line_t 1320 trace_hwlat_print(struct trace_iterator *iter, int flags, 1321 struct trace_event *event) 1322 { 1323 struct trace_entry *entry = iter->ent; 1324 struct trace_seq *s = &iter->seq; 1325 struct hwlat_entry *field; 1326 1327 trace_assign_type(field, entry); 1328 1329 trace_seq_printf(s, "#%-5u inner/outer(us): %4llu/%-5llu ts:%lld.%09ld count:%d", 1330 field->seqnum, 1331 field->duration, 1332 field->outer_duration, 1333 (long long)field->timestamp.tv_sec, 1334 field->timestamp.tv_nsec, field->count); 1335 1336 if (field->nmi_count) { 1337 /* 1338 * The generic sched_clock() is not NMI safe, thus 1339 * we only record the count and not the time. 1340 */ 1341 if (!IS_ENABLED(CONFIG_GENERIC_SCHED_CLOCK)) 1342 trace_seq_printf(s, " nmi-total:%llu", 1343 field->nmi_total_ts); 1344 trace_seq_printf(s, " nmi-count:%u", 1345 field->nmi_count); 1346 } 1347 1348 trace_seq_putc(s, '\n'); 1349 1350 return trace_handle_return(s); 1351 } 1352 1353 static enum print_line_t 1354 trace_hwlat_raw(struct trace_iterator *iter, int flags, 1355 struct trace_event *event) 1356 { 1357 struct hwlat_entry *field; 1358 struct trace_seq *s = &iter->seq; 1359 1360 trace_assign_type(field, iter->ent); 1361 1362 trace_seq_printf(s, "%llu %lld %lld %09ld %u\n", 1363 field->duration, 1364 field->outer_duration, 1365 (long long)field->timestamp.tv_sec, 1366 field->timestamp.tv_nsec, 1367 field->seqnum); 1368 1369 return trace_handle_return(s); 1370 } 1371 1372 static struct trace_event_functions trace_hwlat_funcs = { 1373 .trace = trace_hwlat_print, 1374 .raw = trace_hwlat_raw, 1375 }; 1376 1377 static struct trace_event trace_hwlat_event = { 1378 .type = TRACE_HWLAT, 1379 .funcs = &trace_hwlat_funcs, 1380 }; 1381 1382 /* TRACE_OSNOISE */ 1383 static enum print_line_t 1384 trace_osnoise_print(struct trace_iterator *iter, int flags, 1385 struct trace_event *event) 1386 { 1387 struct trace_entry *entry = iter->ent; 1388 struct trace_seq *s = &iter->seq; 1389 struct osnoise_entry *field; 1390 u64 ratio, ratio_dec; 1391 u64 net_runtime; 1392 1393 trace_assign_type(field, entry); 1394 1395 /* 1396 * compute the available % of cpu time. 1397 */ 1398 net_runtime = field->runtime - field->noise; 1399 ratio = net_runtime * 10000000; 1400 do_div(ratio, field->runtime); 1401 ratio_dec = do_div(ratio, 100000); 1402 1403 trace_seq_printf(s, "%llu %10llu %3llu.%05llu %7llu", 1404 field->runtime, 1405 field->noise, 1406 ratio, ratio_dec, 1407 field->max_sample); 1408 1409 trace_seq_printf(s, " %6u", field->hw_count); 1410 trace_seq_printf(s, " %6u", field->nmi_count); 1411 trace_seq_printf(s, " %6u", field->irq_count); 1412 trace_seq_printf(s, " %6u", field->softirq_count); 1413 trace_seq_printf(s, " %6u", field->thread_count); 1414 1415 trace_seq_putc(s, '\n'); 1416 1417 return trace_handle_return(s); 1418 } 1419 1420 static enum print_line_t 1421 trace_osnoise_raw(struct trace_iterator *iter, int flags, 1422 struct trace_event *event) 1423 { 1424 struct osnoise_entry *field; 1425 struct trace_seq *s = &iter->seq; 1426 1427 trace_assign_type(field, iter->ent); 1428 1429 trace_seq_printf(s, "%lld %llu %llu %u %u %u %u %u\n", 1430 field->runtime, 1431 field->noise, 1432 field->max_sample, 1433 field->hw_count, 1434 field->nmi_count, 1435 field->irq_count, 1436 field->softirq_count, 1437 field->thread_count); 1438 1439 return trace_handle_return(s); 1440 } 1441 1442 static struct trace_event_functions trace_osnoise_funcs = { 1443 .trace = trace_osnoise_print, 1444 .raw = trace_osnoise_raw, 1445 }; 1446 1447 static struct trace_event trace_osnoise_event = { 1448 .type = TRACE_OSNOISE, 1449 .funcs = &trace_osnoise_funcs, 1450 }; 1451 1452 /* TRACE_TIMERLAT */ 1453 1454 static char *timerlat_lat_context[] = {"irq", "thread", "user-ret"}; 1455 static enum print_line_t 1456 trace_timerlat_print(struct trace_iterator *iter, int flags, 1457 struct trace_event *event) 1458 { 1459 struct trace_entry *entry = iter->ent; 1460 struct trace_seq *s = &iter->seq; 1461 struct timerlat_entry *field; 1462 1463 trace_assign_type(field, entry); 1464 1465 trace_seq_printf(s, "#%-5u context %6s timer_latency %9llu ns\n", 1466 field->seqnum, 1467 timerlat_lat_context[field->context], 1468 field->timer_latency); 1469 1470 return trace_handle_return(s); 1471 } 1472 1473 static enum print_line_t 1474 trace_timerlat_raw(struct trace_iterator *iter, int flags, 1475 struct trace_event *event) 1476 { 1477 struct timerlat_entry *field; 1478 struct trace_seq *s = &iter->seq; 1479 1480 trace_assign_type(field, iter->ent); 1481 1482 trace_seq_printf(s, "%u %d %llu\n", 1483 field->seqnum, 1484 field->context, 1485 field->timer_latency); 1486 1487 return trace_handle_return(s); 1488 } 1489 1490 static struct trace_event_functions trace_timerlat_funcs = { 1491 .trace = trace_timerlat_print, 1492 .raw = trace_timerlat_raw, 1493 }; 1494 1495 static struct trace_event trace_timerlat_event = { 1496 .type = TRACE_TIMERLAT, 1497 .funcs = &trace_timerlat_funcs, 1498 }; 1499 1500 /* TRACE_BPUTS */ 1501 static enum print_line_t 1502 trace_bputs_print(struct trace_iterator *iter, int flags, 1503 struct trace_event *event) 1504 { 1505 struct trace_entry *entry = iter->ent; 1506 struct trace_seq *s = &iter->seq; 1507 struct bputs_entry *field; 1508 1509 trace_assign_type(field, entry); 1510 1511 seq_print_ip_sym(s, field->ip, flags); 1512 trace_seq_puts(s, ": "); 1513 trace_seq_puts(s, field->str); 1514 1515 return trace_handle_return(s); 1516 } 1517 1518 1519 static enum print_line_t 1520 trace_bputs_raw(struct trace_iterator *iter, int flags, 1521 struct trace_event *event) 1522 { 1523 struct bputs_entry *field; 1524 struct trace_seq *s = &iter->seq; 1525 1526 trace_assign_type(field, iter->ent); 1527 1528 trace_seq_printf(s, ": %lx : ", field->ip); 1529 trace_seq_puts(s, field->str); 1530 1531 return trace_handle_return(s); 1532 } 1533 1534 static struct trace_event_functions trace_bputs_funcs = { 1535 .trace = trace_bputs_print, 1536 .raw = trace_bputs_raw, 1537 }; 1538 1539 static struct trace_event trace_bputs_event = { 1540 .type = TRACE_BPUTS, 1541 .funcs = &trace_bputs_funcs, 1542 }; 1543 1544 /* TRACE_BPRINT */ 1545 static enum print_line_t 1546 trace_bprint_print(struct trace_iterator *iter, int flags, 1547 struct trace_event *event) 1548 { 1549 struct trace_entry *entry = iter->ent; 1550 struct trace_seq *s = &iter->seq; 1551 struct bprint_entry *field; 1552 1553 trace_assign_type(field, entry); 1554 1555 seq_print_ip_sym(s, field->ip, flags); 1556 trace_seq_puts(s, ": "); 1557 trace_seq_bprintf(s, field->fmt, field->buf); 1558 1559 return trace_handle_return(s); 1560 } 1561 1562 1563 static enum print_line_t 1564 trace_bprint_raw(struct trace_iterator *iter, int flags, 1565 struct trace_event *event) 1566 { 1567 struct bprint_entry *field; 1568 struct trace_seq *s = &iter->seq; 1569 1570 trace_assign_type(field, iter->ent); 1571 1572 trace_seq_printf(s, ": %lx : ", field->ip); 1573 trace_seq_bprintf(s, field->fmt, field->buf); 1574 1575 return trace_handle_return(s); 1576 } 1577 1578 static struct trace_event_functions trace_bprint_funcs = { 1579 .trace = trace_bprint_print, 1580 .raw = trace_bprint_raw, 1581 }; 1582 1583 static struct trace_event trace_bprint_event = { 1584 .type = TRACE_BPRINT, 1585 .funcs = &trace_bprint_funcs, 1586 }; 1587 1588 /* TRACE_PRINT */ 1589 static enum print_line_t trace_print_print(struct trace_iterator *iter, 1590 int flags, struct trace_event *event) 1591 { 1592 struct print_entry *field; 1593 struct trace_seq *s = &iter->seq; 1594 1595 trace_assign_type(field, iter->ent); 1596 1597 seq_print_ip_sym(s, field->ip, flags); 1598 trace_seq_printf(s, ": %s", field->buf); 1599 1600 return trace_handle_return(s); 1601 } 1602 1603 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, 1604 struct trace_event *event) 1605 { 1606 struct print_entry *field; 1607 1608 trace_assign_type(field, iter->ent); 1609 1610 trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf); 1611 1612 return trace_handle_return(&iter->seq); 1613 } 1614 1615 static struct trace_event_functions trace_print_funcs = { 1616 .trace = trace_print_print, 1617 .raw = trace_print_raw, 1618 }; 1619 1620 static struct trace_event trace_print_event = { 1621 .type = TRACE_PRINT, 1622 .funcs = &trace_print_funcs, 1623 }; 1624 1625 static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags, 1626 struct trace_event *event) 1627 { 1628 struct raw_data_entry *field; 1629 int i; 1630 1631 trace_assign_type(field, iter->ent); 1632 1633 trace_seq_printf(&iter->seq, "# %x buf:", field->id); 1634 1635 for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++) 1636 trace_seq_printf(&iter->seq, " %02x", 1637 (unsigned char)field->buf[i]); 1638 1639 trace_seq_putc(&iter->seq, '\n'); 1640 1641 return trace_handle_return(&iter->seq); 1642 } 1643 1644 static struct trace_event_functions trace_raw_data_funcs = { 1645 .trace = trace_raw_data, 1646 .raw = trace_raw_data, 1647 }; 1648 1649 static struct trace_event trace_raw_data_event = { 1650 .type = TRACE_RAW_DATA, 1651 .funcs = &trace_raw_data_funcs, 1652 }; 1653 1654 static enum print_line_t 1655 trace_func_repeats_raw(struct trace_iterator *iter, int flags, 1656 struct trace_event *event) 1657 { 1658 struct func_repeats_entry *field; 1659 struct trace_seq *s = &iter->seq; 1660 1661 trace_assign_type(field, iter->ent); 1662 1663 trace_seq_printf(s, "%lu %lu %u %llu\n", 1664 field->ip, 1665 field->parent_ip, 1666 field->count, 1667 FUNC_REPEATS_GET_DELTA_TS(field)); 1668 1669 return trace_handle_return(s); 1670 } 1671 1672 static enum print_line_t 1673 trace_func_repeats_print(struct trace_iterator *iter, int flags, 1674 struct trace_event *event) 1675 { 1676 struct func_repeats_entry *field; 1677 struct trace_seq *s = &iter->seq; 1678 1679 trace_assign_type(field, iter->ent); 1680 1681 print_fn_trace(s, field->ip, field->parent_ip, flags); 1682 trace_seq_printf(s, " (repeats: %u, last_ts:", field->count); 1683 trace_print_time(s, iter, 1684 iter->ts - FUNC_REPEATS_GET_DELTA_TS(field)); 1685 trace_seq_puts(s, ")\n"); 1686 1687 return trace_handle_return(s); 1688 } 1689 1690 static struct trace_event_functions trace_func_repeats_funcs = { 1691 .trace = trace_func_repeats_print, 1692 .raw = trace_func_repeats_raw, 1693 }; 1694 1695 static struct trace_event trace_func_repeats_event = { 1696 .type = TRACE_FUNC_REPEATS, 1697 .funcs = &trace_func_repeats_funcs, 1698 }; 1699 1700 static struct trace_event *events[] __initdata = { 1701 &trace_fn_event, 1702 &trace_ctx_event, 1703 &trace_wake_event, 1704 &trace_stack_event, 1705 &trace_user_stack_event, 1706 &trace_bputs_event, 1707 &trace_bprint_event, 1708 &trace_print_event, 1709 &trace_hwlat_event, 1710 &trace_osnoise_event, 1711 &trace_timerlat_event, 1712 &trace_raw_data_event, 1713 &trace_func_repeats_event, 1714 NULL 1715 }; 1716 1717 __init int init_events(void) 1718 { 1719 struct trace_event *event; 1720 int i, ret; 1721 1722 for (i = 0; events[i]; i++) { 1723 event = events[i]; 1724 ret = register_trace_event(event); 1725 WARN_ONCE(!ret, "event %d failed to register", event->type); 1726 } 1727 1728 return 0; 1729 } 1730