LCOV - code coverage report
Current view: top level - kernel/trace - trace_output.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 43 573 7.5 %
Date: 2021-04-22 12:43:58 Functions: 3 56 5.4 %

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

Generated by: LCOV version 1.14