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