root/kernel/trace/trace_output.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. trace_print_bputs_msg_only
  2. trace_print_bprintk_msg_only
  3. trace_print_printk_msg_only
  4. trace_print_flags_seq
  5. trace_print_symbols_seq
  6. trace_print_flags_seq_u64
  7. trace_print_symbols_seq_u64
  8. trace_print_bitmask_seq
  9. trace_print_hex_seq
  10. trace_print_array_seq
  11. trace_raw_output_prep
  12. trace_output_raw
  13. trace_output_call
  14. kretprobed
  15. kretprobed
  16. seq_print_sym
  17. seq_print_user_ip
  18. seq_print_ip_sym
  19. trace_print_lat_fmt
  20. lat_print_generic
  21. trace_find_mark
  22. lat_print_timestamp
  23. trace_print_context
  24. trace_print_lat_context
  25. ftrace_find_event
  26. trace_search_list
  27. trace_event_read_lock
  28. trace_event_read_unlock
  29. register_trace_event
  30. __unregister_trace_event
  31. unregister_trace_event
  32. trace_nop_print
  33. trace_fn_trace
  34. trace_fn_raw
  35. trace_fn_hex
  36. trace_fn_bin
  37. trace_ctxwake_print
  38. trace_ctx_print
  39. trace_wake_print
  40. trace_ctxwake_raw
  41. trace_ctx_raw
  42. trace_wake_raw
  43. trace_ctxwake_hex
  44. trace_ctx_hex
  45. trace_wake_hex
  46. trace_ctxwake_bin
  47. trace_stack_print
  48. trace_user_stack_print
  49. trace_hwlat_print
  50. trace_hwlat_raw
  51. trace_bputs_print
  52. trace_bputs_raw
  53. trace_bprint_print
  54. trace_bprint_raw
  55. trace_print_print
  56. trace_print_raw
  57. trace_raw_data
  58. init_events

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

/* [<][>][^][v][top][bottom][index][help] */